JSFiddle - React, Tailwind, and code Playground
by Yurik Elmanov
HTML
<h4>Drag 1 or more shapes.</h4>
<button type="button" onClick="handleSaveImage()">Save Image</button>
<canvas id="canvas" width="1170" height="606"></canvas>
<canvas id="shadow-canvas" width="570" height="606"></canvas>
CSS
#shadow-canvas {
display: none;
opacity: 0;
visibility: hidden;
pointer-events: none;
}
JavaScript
// get canvas related references
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const BB = canvas.getBoundingClientRect();
const offsetX = BB.left;
const offsetY = BB.top;
const WIDTH = canvas.width;
const HEIGHT = canvas.height;
const handleSaveImage = () => {
const shadowCanvas = document.getElementById('shadow-canvas');
const sctx = shadowCanvas.getContext('2d');
// Заменить на фоновую картинку
sctx.fillStyle = '#312F42';
sctx.beginPath();
sctx.rect(0, 0, 570, 606);
sctx.closePath();
sctx.fill();
rects.forEach(({ x, y, width, height, fill }) => {
sctx.fillStyle = fill;
sctx.beginPath();
sctx.rect(x >= 570 ? x - 600 : x, y, width, height);
sctx.closePath();
sctx.fill();
});
const link = document.createElement('a');
link.download = 'image.png';
link.href = shadowCanvas.toDataURL();
link.click();
};
// drag related variables
let dragok = false;
let startX;
let startY;
// an array of objects that define different rectangles
const rects = [];
rects.push({
x: 75 - 15,
y: 50 - 15,
width: 30,
height: 30,
fill: "#444444",
isDragging: false
});
rects.push({
x: 75 - 25,
y: 50 - 25,
width: 30,
height: 30,
fill: "#ff550d",
isDragging: false
});
rects.push({
x: 75 - 35,
y: 50 - 35,
width: 30,
height: 30,
fill: "#800080",
isDragging: false
});
rects.push({
x: 75 - 45,
y: 50 - 45,
width: 30,
height: 30,
fill: "#0c64e8",
isDragging: false
});
// clear the canvas
const clear = () => {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
// draw a single rect
const createFiled = (x, y, width, height, fill) => {
ctx.fillStyle = fill;
ctx.beginPath();
ctx.rect(x, y, width, height);
ctx.closePath();
ctx.fill();
};
const createItemOnField = () => {
rects.forEach(({ x, y, width, height, fill }) => {
ctx.fillStyle = fill;
createFiled(x, y, width, height);
});
};
// redraw the scene
const draw = () => {
clear();
createFiled(0,...