| let canvas = document.getElementById('canvas');
|
| let ctx = canvas.getContext('2d');
|
|
|
|
|
| let originalCtxOriginal = document.createElement('canvas').getContext('2d');
|
| let maskCtxOriginal = document.createElement('canvas').getContext('2d');
|
|
|
| let isDrawing = false;
|
| let brushSize = 5;
|
| let eraserMode = false;
|
|
|
|
|
| document.getElementById('imageUpload').addEventListener('change', handleImageUpload);
|
| document.getElementById('brushSize').addEventListener('change', (e) => brushSize = parseInt(e.target.value));
|
| document.getElementById('eraserMode').addEventListener('change', (e) => eraserMode = e.target.checked);
|
| canvas.addEventListener('mousedown', startDrawing);
|
| canvas.addEventListener('mousemove', draw);
|
| canvas.addEventListener('mouseup', stopDrawing);
|
| canvas.addEventListener('mouseout', stopDrawing);
|
|
|
| function handleImageUpload(e) {
|
| let file = e.target.files[0];
|
| let reader = new FileReader();
|
|
|
| reader.onload = function(event) {
|
| let img = new Image();
|
| img.onload = function() {
|
|
|
| originalCtxOriginal.canvas.width = img.width;
|
| originalCtxOriginal.canvas.height = img.height;
|
| originalCtxOriginal.drawImage(img, 0, 0);
|
|
|
|
|
| maskCtxOriginal.canvas.width = img.width;
|
| maskCtxOriginal.canvas.height = img.height;
|
|
|
|
|
| const container = document.getElementById('canvasContainer');
|
| const maxWidth = container.clientWidth;
|
| const maxHeight = container.clientHeight;
|
|
|
| let ratio = Math.min(maxWidth / img.width, maxHeight / img.height);
|
| ratio = Math.min(ratio, 1);
|
|
|
| const scaledWidth = img.width * ratio;
|
| const scaledHeight = img.height * ratio;
|
| const offsetX = (maxWidth - scaledWidth) / 2;
|
| const offsetY = (maxHeight - scaledHeight) / 2;
|
|
|
|
|
| canvas.width = maxWidth;
|
| canvas.height = maxHeight;
|
|
|
|
|
| ctx.drawImage(img, offsetX, offsetY, scaledWidth, scaledHeight);
|
|
|
|
|
| window.scaleRatio = ratio;
|
| window.offsetX = offsetX;
|
| window.offsetY = offsetY;
|
| };
|
| img.src = event.target.result;
|
| };
|
| reader.readAsDataURL(file);
|
| }
|
|
|
| function startDrawing(e) {
|
| isDrawing = true;
|
| draw(e);
|
| }
|
|
|
| function stopDrawing() {
|
| isDrawing = false;
|
| ctx.beginPath();
|
| }
|
|
|
| function draw(e) {
|
| if (!isDrawing || !window.scaleRatio) return;
|
|
|
| const rect = canvas.getBoundingClientRect();
|
| const mouseX = e.clientX - rect.left;
|
| const mouseY = e.clientY - rect.top;
|
|
|
|
|
| const originalX = (mouseX - window.offsetX) / window.scaleRatio;
|
| const originalY = (mouseY - window.offsetY) / window.scaleRatio;
|
| const brushRadius = brushSize / window.scaleRatio;
|
|
|
| if (eraserMode) {
|
|
|
| maskCtxOriginal.clearRect(
|
| originalX - brushRadius,
|
| originalY - brushRadius,
|
| brushRadius * 2,
|
| brushRadius * 2
|
| );
|
| } else {
|
|
|
| maskCtxOriginal.fillStyle = '#FFFFFF';
|
| maskCtxOriginal.beginPath();
|
| maskCtxOriginal.arc(
|
| originalX,
|
| originalY,
|
| brushRadius,
|
| 0,
|
| Math.PI * 2
|
| );
|
| maskCtxOriginal.fill();
|
| }
|
|
|
|
|
| ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| ctx.drawImage(originalCtxOriginal.canvas,
|
| 0, 0, originalCtxOriginal.canvas.width, originalCtxOriginal.canvas.height,
|
| window.offsetX, window.offsetY,
|
| originalCtxOriginal.canvas.width * window.scaleRatio,
|
| originalCtxOriginal.canvas.height * window.scaleRatio
|
| );
|
|
|
|
|
| ctx.globalAlpha = 0.5;
|
| ctx.drawImage(maskCtxOriginal.canvas,
|
| 0, 0, maskCtxOriginal.canvas.width, maskCtxOriginal.canvas.height,
|
| window.offsetX, window.offsetY,
|
| maskCtxOriginal.canvas.width * window.scaleRatio,
|
| maskCtxOriginal.canvas.height * window.scaleRatio
|
| );
|
| ctx.globalAlpha = 1;
|
| }
|
|
|
|
|
| document.getElementById('downloadBtn').addEventListener('click', () => {
|
| const binaryCanvas = document.createElement('canvas');
|
| binaryCanvas.width = originalCtxOriginal.canvas.width;
|
| binaryCanvas.height = originalCtxOriginal.canvas.height;
|
| const binaryCtx = binaryCanvas.getContext('2d');
|
|
|
|
|
| binaryCtx.fillStyle = 'white';
|
| binaryCtx.fillRect(0, 0, binaryCanvas.width, binaryCanvas.height);
|
|
|
|
|
| const maskData = maskCtxOriginal.getImageData(0, 0,
|
| binaryCanvas.width, binaryCanvas.height);
|
|
|
|
|
| for (let i = 0; i < maskData.data.length; i += 4) {
|
| if (maskData.data[i + 3] > 0) {
|
| const x = (i / 4) % binaryCanvas.width;
|
| const y = Math.floor((i / 4) / binaryCanvas.width);
|
| binaryCtx.fillStyle = 'black';
|
| binaryCtx.fillRect(x, y, 1, 1);
|
| }
|
| }
|
|
|
| document.getElementById('downloadBtn').href = binaryCanvas.toDataURL('image/png');
|
| }); |