Use the canvas scaling API to preserve applied transformations
continuous-integration/drone/push Build is passing Details

main
Clément FRÉVILLE 1 year ago
parent 92d0061284
commit 6a904b705a

@ -3,13 +3,14 @@ import { onMounted, ref } from 'vue';
import { blackAndWhite, grayScale } from '../processing/gray-scale.ts'; import { blackAndWhite, grayScale } from '../processing/gray-scale.ts';
import ImageCollection from './ImageCollection.vue'; import ImageCollection from './ImageCollection.vue';
import { mergeImages } from '../processing/merge.ts'; import { mergeImages } from '../processing/merge.ts';
import { drawOffscreen } from '../processing/offscreen.ts';
const canvas = ref<HTMLCanvasElement | null>(null); const canvas = ref<HTMLCanvasElement | null>(null);
const collection = ref<typeof ImageCollection>(); const collection = ref<typeof ImageCollection>();
const overlay = ref<string | null>(null); const overlay = ref<string | null>(null);
const currentWidth = ref(100); const currentWidth = ref(100);
const currentHeight = ref(100); const currentHeight = ref(100);
let img: HTMLImageElement; let viable = new ImageData(1, 1);
let ctx: CanvasRenderingContext2D; let ctx: CanvasRenderingContext2D;
onMounted(() => { onMounted(() => {
ctx = canvas.value!.getContext('2d')!; ctx = canvas.value!.getContext('2d')!;
@ -19,33 +20,45 @@ function onSelected(image: HTMLImageElement): void {
canvas.value!.width = image.width; canvas.value!.width = image.width;
canvas.value!.height = image.height; canvas.value!.height = image.height;
ctx.drawImage(image, 0, 0); ctx.drawImage(image, 0, 0);
img = image; viable = ctx.getImageData(0, 0, canvas.value!.width, canvas.value!.height);
} }
function grayScaleApply() { function grayScaleApply() {
const imageData = ctx.getImageData(0, 0, canvas.value!.width, canvas.value!.height); const imageData = ctx.getImageData(0, 0, canvas.value!.width, canvas.value!.height);
const pixels = imageData.data; const pixels = imageData.data;
grayScale(pixels); grayScale(pixels);
ctx.putImageData(imageData, 0, 0); draw(imageData);
} }
function blackAndWhiteApply() { function blackAndWhiteApply() {
const imageData = ctx.getImageData(0, 0, canvas.value!.width, canvas.value!.height); const imageData = ctx.getImageData(0, 0, canvas.value!.width, canvas.value!.height);
const pixels = imageData.data; const pixels = imageData.data;
blackAndWhite(pixels); blackAndWhite(pixels);
ctx.putImageData(imageData, 0, 0); draw(imageData);
} }
function onChangeSlideWidth() { function onChangeSlideWidth() {
const width = currentWidth.value / 100 * img.width; const newCanvas = drawOffscreen(viable);
canvas.value!.width = width; canvas.value!.width = viable.width * currentWidth.value / 100;
ctx.drawImage(img, 0, 0, width, canvas.value!.height); drawScaled(newCanvas);
} }
function onChangeSlideHeight() { function onChangeSlideHeight() {
const height = currentHeight.value / 100 * img.height; const newCanvas = drawOffscreen(viable);
canvas.value!.height = height; canvas.value!.height = viable.height * currentHeight.value / 100;
ctx.drawImage(img, 0, 0, canvas.value!.width, height); drawScaled(newCanvas);
}
function drawScaled(newCanvas: OffscreenCanvas) {
ctx.scale(currentWidth.value / 100, currentHeight.value / 100);
ctx.drawImage(newCanvas, 0, 0);
}
function draw(data: ImageData) {
ctx.putImageData(data, 0, 0);
currentWidth.value = 100;
currentHeight.value = 100;
viable = data;
} }
function onDragOver(event: DragEvent) { function onDragOver(event: DragEvent) {
@ -104,14 +117,14 @@ function onDragLeave() {
</button> </button>
</div> </div>
<div class="inner"> <div class="inner">
<input v-model="currentHeight" type="range" min="1" max="200" value="100" orient="vertical" @change="onChangeSlideHeight"> <input v-model="currentHeight" type="range" min="5" max="200" value="100" orient="vertical" @change="onChangeSlideHeight">
<div class="preview" @dragover="onDragOver" @dragleave="onDragLeave" @drop="onDrop"> <div class="preview" @dragover="onDragOver" @dragleave="onDragLeave" @drop="onDrop">
<canvas ref="canvas"></canvas> <canvas ref="canvas"></canvas>
<div v-if="overlay" :class="`overlay overlay-${overlay}`"></div> <div v-if="overlay" :class="`overlay overlay-${overlay}`"></div>
</div> </div>
</div> </div>
<div class="controls"> <div class="controls">
<input id="image-width" v-model="currentWidth" type="range" min="1" max="200" @change="onChangeSlideWidth"> <input id="image-width" v-model="currentWidth" type="range" min="5" max="200" @change="onChangeSlideWidth">
<output for="image-width">{{ currentWidth }}%</output> <output for="image-width">{{ currentWidth }}%</output>
</div> </div>
</div> </div>

@ -0,0 +1,6 @@
export function drawOffscreen(data: ImageData): OffscreenCanvas {
const newCanvas = new OffscreenCanvas(data.width, data.height);
const newCtx = newCanvas.getContext('2d')!;
newCtx.putImageData(data, 0, 0);
return newCanvas;
}
Loading…
Cancel
Save