fix: zoom not working as expected

This commit is contained in:
2025-12-20 21:17:13 +01:00
parent 8b6d4dbf90
commit fdf5002496
+25 -19
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, onMounted, useTemplateRef, computed } from "vue";
import { ref, onMounted, useTemplateRef } from "vue";
import LucideIcon from "./components/LucideIcon.vue";
enum Filter {
@@ -22,8 +22,6 @@ const PA_RATIO = 404 / 646;
const visible = ref<boolean>(false);
const srcData = ref<string | null>(null);
const srcWidth = ref<number>(0);
const srcHeight = ref<number>(0);
const srcLoaded = ref<boolean>(false);
const centerX = ref<number>(0.5);
@@ -33,13 +31,7 @@ const filter = ref<Filter>(Filter.None);
const paPos = ref<PAPosition>(PAPosition.BR);
const paScale = ref<number>(0.2);
const paMargin = ref<number>(0.05);
const targetSize = computed<number>(() => {
if (!srcWidth.value || !srcHeight.value) {
return 100;
}
return Math.min(1024, srcWidth.value, srcHeight.value);
});
const targetSize = ref<number>(1024);
const input = useTemplateRef<HTMLInputElement>("input");
const image = useTemplateRef<HTMLImageElement>("image");
@@ -58,11 +50,6 @@ function openImage() {
}
function imageOnLoad() {
srcWidth.value = image.value?.width ?? 0;
srcHeight.value = image.value?.height ?? 0;
if (!srcWidth.value || !srcHeight.value) {
return;
}
srcLoaded.value = true;
setTimeout(draw);
}
@@ -147,10 +134,13 @@ function draw() {
canvas.value.height = targetSize.value;
ctx.clearRect(0, 0, targetSize.value, targetSize.value);
const imgWidth = srcWidth.value * zoom.value;
const imgHeight = srcHeight.value * zoom.value;
const dx = (targetSize.value - imgWidth) * centerX.value;
const dy = (targetSize.value - imgHeight) * centerY.value;
const imgRatio = image.value.height / image.value.width;
const widthFirst = image.value.width < image.value.height;
const imgWidth = targetSize.value * (widthFirst ? 1 : 1 / imgRatio);
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);
const imageData = ctx.getImageData(
@@ -373,6 +363,22 @@ onMounted(() => {
</td>
<td>{{ (paMargin * 100).toFixed(0) }}%</td>
</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>
</table>
</template>