fix: zoom not working as expected
This commit is contained in:
+25
-19
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, useTemplateRef, computed } from "vue";
|
import { ref, onMounted, useTemplateRef } from "vue";
|
||||||
import LucideIcon from "./components/LucideIcon.vue";
|
import LucideIcon from "./components/LucideIcon.vue";
|
||||||
|
|
||||||
enum Filter {
|
enum Filter {
|
||||||
@@ -22,8 +22,6 @@ const PA_RATIO = 404 / 646;
|
|||||||
|
|
||||||
const visible = ref<boolean>(false);
|
const visible = ref<boolean>(false);
|
||||||
const srcData = ref<string | null>(null);
|
const srcData = ref<string | null>(null);
|
||||||
const srcWidth = ref<number>(0);
|
|
||||||
const srcHeight = ref<number>(0);
|
|
||||||
const srcLoaded = ref<boolean>(false);
|
const srcLoaded = ref<boolean>(false);
|
||||||
|
|
||||||
const centerX = ref<number>(0.5);
|
const centerX = ref<number>(0.5);
|
||||||
@@ -33,13 +31,7 @@ const filter = ref<Filter>(Filter.None);
|
|||||||
const paPos = ref<PAPosition>(PAPosition.BR);
|
const paPos = ref<PAPosition>(PAPosition.BR);
|
||||||
const paScale = ref<number>(0.2);
|
const paScale = ref<number>(0.2);
|
||||||
const paMargin = ref<number>(0.05);
|
const paMargin = ref<number>(0.05);
|
||||||
|
const targetSize = ref<number>(1024);
|
||||||
const targetSize = computed<number>(() => {
|
|
||||||
if (!srcWidth.value || !srcHeight.value) {
|
|
||||||
return 100;
|
|
||||||
}
|
|
||||||
return Math.min(1024, srcWidth.value, srcHeight.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
const input = useTemplateRef<HTMLInputElement>("input");
|
const input = useTemplateRef<HTMLInputElement>("input");
|
||||||
const image = useTemplateRef<HTMLImageElement>("image");
|
const image = useTemplateRef<HTMLImageElement>("image");
|
||||||
@@ -58,11 +50,6 @@ function openImage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function imageOnLoad() {
|
function imageOnLoad() {
|
||||||
srcWidth.value = image.value?.width ?? 0;
|
|
||||||
srcHeight.value = image.value?.height ?? 0;
|
|
||||||
if (!srcWidth.value || !srcHeight.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
srcLoaded.value = true;
|
srcLoaded.value = true;
|
||||||
setTimeout(draw);
|
setTimeout(draw);
|
||||||
}
|
}
|
||||||
@@ -147,10 +134,13 @@ function draw() {
|
|||||||
canvas.value.height = targetSize.value;
|
canvas.value.height = targetSize.value;
|
||||||
ctx.clearRect(0, 0, targetSize.value, targetSize.value);
|
ctx.clearRect(0, 0, targetSize.value, targetSize.value);
|
||||||
|
|
||||||
const imgWidth = srcWidth.value * zoom.value;
|
const imgRatio = image.value.height / image.value.width;
|
||||||
const imgHeight = srcHeight.value * zoom.value;
|
const widthFirst = image.value.width < image.value.height;
|
||||||
const dx = (targetSize.value - imgWidth) * centerX.value;
|
const imgWidth = targetSize.value * (widthFirst ? 1 : 1 / imgRatio);
|
||||||
const dy = (targetSize.value - imgHeight) * centerY.value;
|
const imgHeight = targetSize.value * (widthFirst ? imgRatio : 1);
|
||||||
|
const dx = (targetSize.value - imgWidth * zoom.value) * centerX.value;
|
||||||
|
const dy = (targetSize.value - imgHeight * zoom.value) * centerY.value;
|
||||||
|
// TODO get only selected area
|
||||||
ctx.drawImage(image.value, dx, dy, imgWidth, imgHeight);
|
ctx.drawImage(image.value, dx, dy, imgWidth, imgHeight);
|
||||||
|
|
||||||
const imageData = ctx.getImageData(
|
const imageData = ctx.getImageData(
|
||||||
@@ -373,6 +363,22 @@ onMounted(() => {
|
|||||||
</td>
|
</td>
|
||||||
<td>{{ (paMargin * 100).toFixed(0) }}%</td>
|
<td>{{ (paMargin * 100).toFixed(0) }}%</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="size">Image Size:</label></td>
|
||||||
|
<td>
|
||||||
|
<select
|
||||||
|
id="size"
|
||||||
|
v-model="targetSize"
|
||||||
|
@change="asyncDraw"
|
||||||
|
>
|
||||||
|
<option :value="512">512x512</option>
|
||||||
|
<option :value="1024">1024x1024</option>
|
||||||
|
<option :value="2048">2048x2048</option>
|
||||||
|
<option :value="4096">4096x4096</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user