feat: preview size is fixed to 512

This commit is contained in:
2025-12-20 23:14:14 +01:00
parent 95d09d7750
commit 030c2f0803
2 changed files with 49 additions and 51 deletions
+31 -33
View File
@@ -19,6 +19,7 @@ enum PAPosition {
}
const PA_RATIO = 404 / 646;
const PREVIEW_SIZE = 512;
const visible = ref<boolean>(false);
const srcData = ref<string | null>(null);
@@ -60,9 +61,9 @@ function randomElement<T>(items: T[]): T {
}
function randomize() {
centerX.value = Math.random();
centerY.value = Math.random();
zoom.value = 1 + Math.random() * 2;
centerX.value = 0.25 + Math.random() * 0.5;
centerY.value = 0.25 + Math.random() * 0.5;
zoom.value = 1 + Math.random();
filter.value = randomElement(Object.values(Filter));
paPos.value = randomElement(Object.values(PAPosition));
paScale.value = 0.1 + Math.random() * 0.2;
@@ -89,6 +90,9 @@ function newImage() {
function download() {
const link = document.createElement("a");
link.download = `coverify-${new Date().getTime().toString()}.png`;
if (targetSize.value !== PREVIEW_SIZE) {
draw(targetSize.value);
}
link.href = canvas.value?.toDataURL() ?? "#";
link.click();
}
@@ -122,7 +126,7 @@ function asyncDraw() {
drawTimeout.value = setTimeout(draw);
}
function draw() {
function draw(size = PREVIEW_SIZE) {
if (!canvas.value) {
return;
}
@@ -130,31 +134,25 @@ function draw() {
if (!ctx || !image.value) {
return;
}
canvas.value.width = targetSize.value;
canvas.value.height = targetSize.value;
ctx.clearRect(0, 0, targetSize.value, targetSize.value);
canvas.value.width = size;
canvas.value.height = size;
ctx.clearRect(0, 0, size, size);
const imgRatio = image.value.height / image.value.width;
const widthFirst = image.value.width < image.value.height;
const imgWidth = targetSize.value * (widthFirst ? 1 : 1 / imgRatio) * zoom.value;
const imgHeight = targetSize.value * (widthFirst ? imgRatio : 1) * zoom.value;
const dx = (targetSize.value - imgWidth) * centerX.value;
const dy = (targetSize.value - imgHeight) * centerY.value;
// TODO get only selected area
const imgWidth = size * (widthFirst ? 1 : 1 / imgRatio) * zoom.value;
const imgHeight = size * (widthFirst ? imgRatio : 1) * zoom.value;
const dx = (size - imgWidth) * centerX.value;
const dy = (size - imgHeight) * centerY.value;
ctx.drawImage(image.value, dx, dy, imgWidth, imgHeight);
const imageData = ctx.getImageData(
0,
0,
targetSize.value,
targetSize.value,
);
// @ts-expect-error: safer to cast
const pixelData = imageData.data as number[];
if (filter.value !== Filter.None) {
const imageData = ctx.getImageData(0, 0, size, size);
const pixelData = imageData.data;
for (let i = 0; i < pixelData.length; i += 4) {
const r1 = pixelData[i]!;
const g1 = pixelData[i + 1]!;
const b1 = pixelData[i + 2]!;
const r1 = pixelData[i] ?? 0;
const g1 = pixelData[i + 1] ?? 0;
const b1 = pixelData[i + 2] ?? 0;
const [r2, g2, b2] = applyFilter(filter.value, r1, g1, b1);
@@ -163,28 +161,28 @@ function draw() {
pixelData[i + 2] = b2;
pixelData[i + 3] = 255;
}
ctx.putImageData(imageData, 0, 0);
}
if (paPos.value !== PAPosition.None && parentalAdvisory.value) {
const paWidth = targetSize.value * paScale.value;
const paWidth = size * paScale.value;
const paHeight = paWidth * PA_RATIO;
let padx = paMargin.value * targetSize.value;
let pady = paMargin.value * targetSize.value;
let padx = paMargin.value * size;
let pady = paMargin.value * size;
if (
paPos.value === PAPosition.BC ||
paPos.value === PAPosition.BL ||
paPos.value === PAPosition.BR
) {
pady = targetSize.value - paHeight - pady;
pady = size - paHeight - pady;
}
if (paPos.value === PAPosition.BR || paPos.value === PAPosition.TR) {
padx = targetSize.value - paWidth - padx;
padx = size - paWidth - padx;
} else if (
paPos.value === PAPosition.BC ||
paPos.value === PAPosition.TC
) {
padx = (targetSize.value - paWidth) * 0.5;
padx = (size - paWidth) * 0.5;
}
ctx.drawImage(parentalAdvisory.value, padx, pady, paWidth, paHeight);
}
@@ -290,7 +288,7 @@ onMounted(() => {
v-model="zoom"
type="range"
min="1"
max="3"
max="4"
step="0.01"
@input="asyncDraw"
/>
@@ -333,7 +331,7 @@ onMounted(() => {
</td>
<td></td>
</tr>
<tr v-if="paPos !== PAPosition.None">
<tr>
<td><label for="pa-scale">Sticker Scale:</label></td>
<td>
<input
@@ -348,7 +346,7 @@ onMounted(() => {
</td>
<td>{{ (paScale * 100).toFixed(0) }}%</td>
</tr>
<tr v-if="paPos !== PAPosition.None">
<tr>
<td><label for="pa-margin">Sticker Margin:</label></td>
<td>
<input