Hey, I added lines!
This commit is contained in:
parent
285db679d9
commit
55f18b1cbe
1 changed files with 123 additions and 48 deletions
|
|
@ -63,6 +63,11 @@
|
|||
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2z" />
|
||||
</svg>
|
||||
</label>
|
||||
|
||||
<input type="radio" class="btn-check" id="line" name="tool">
|
||||
<label for="line" class="btn btn-sm btn-light border d-inline-flex align-items-center justify-content-center">
|
||||
⎯
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<span id="dot" class="position-absolute p-0 m-0 d-none">
|
||||
|
|
@ -89,12 +94,17 @@
|
|||
let dpr = 1;
|
||||
let selectedColor = '#000000';
|
||||
|
||||
let currentRect = null;
|
||||
let rects = [];
|
||||
let currentShape = null;
|
||||
let shapes = [];
|
||||
|
||||
resizeAndSetupCanvas();
|
||||
window.addEventListener('resize', resizeAndSetupCanvas);
|
||||
|
||||
function getActiveTool() {
|
||||
const checked = document.querySelector('input[name="tool"]:checked');
|
||||
return checked ? checked.id : 'outline';
|
||||
}
|
||||
|
||||
function snapToGrid(x, y) {
|
||||
const rect = gridEl.getBoundingClientRect();
|
||||
const clampedX = Math.min(Math.max(x, rect.left), rect.right);
|
||||
|
|
@ -113,14 +123,20 @@
|
|||
};
|
||||
}
|
||||
|
||||
function normalizeRect(rect) {
|
||||
function normalizeRect(shape) {
|
||||
const x = Math.min(shape.x1, shape.x2);
|
||||
const y = Math.min(shape.y1, shape.y2);
|
||||
const w = Math.abs(shape.x2 - shape.x1);
|
||||
const h = Math.abs(shape.y2 - shape.y1);
|
||||
|
||||
return {
|
||||
x: Math.min(rect.x1, rect.x2),
|
||||
y: Math.min(rect.y1, rect.y2),
|
||||
w: Math.abs(rect.x2 - rect.x1),
|
||||
h: Math.abs(rect.y2 - rect.y1),
|
||||
color: rect.color,
|
||||
fill: rect.fill
|
||||
type: 'rect',
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
color: shape.color,
|
||||
fill: shape.fill
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -141,20 +157,29 @@
|
|||
if (!ctx) return;
|
||||
|
||||
clearCanvas();
|
||||
rects.forEach(drawRect);
|
||||
shapes.forEach(drawShape);
|
||||
}
|
||||
|
||||
function drawRect(rect) {
|
||||
function drawShape(shape) {
|
||||
if (!ctx) return;
|
||||
|
||||
ctx.save();
|
||||
ctx.strokeStyle = shape.color || '#000000';
|
||||
|
||||
ctx.strokeStyle = rect.color;
|
||||
ctx.strokeRect(rect.x, rect.y, rect.w, rect.h);
|
||||
if (shape.type === 'rect') {
|
||||
ctx.strokeRect(shape.x, shape.y, shape.w, shape.h);
|
||||
|
||||
if (rect.fill) {
|
||||
ctx.globalAlpha = 0.15;
|
||||
ctx.fillStyle = rect.color;
|
||||
ctx.fillRect(rect.x, rect.y, rect.w, rect.h);
|
||||
ctx.globalAlpha = 1;
|
||||
if (shape.fill) {
|
||||
ctx.globalAlpha = 0.15;
|
||||
ctx.fillStyle = shape.color;
|
||||
ctx.fillRect(shape.x, shape.y, shape.w, shape.h);
|
||||
ctx.globalAlpha = 1;
|
||||
}
|
||||
} else if ( shape.type === 'line' ) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(shape.x1, shape.y1);
|
||||
ctx.lineTo(shape.x2, shape.y2);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
|
|
@ -177,12 +202,12 @@
|
|||
|
||||
if ((e.ctrlKey || e.metaKey) && key === 'z') {
|
||||
e.preventDefault();
|
||||
rects.pop();
|
||||
shapes.pop();
|
||||
redrawAll();
|
||||
}
|
||||
|
||||
if (key === 'escape' && currentRect) {
|
||||
currentRect = null;
|
||||
if (key === 'escape' && currentShape) {
|
||||
currentShape = null;
|
||||
redrawAll();
|
||||
}
|
||||
});
|
||||
|
|
@ -201,18 +226,36 @@
|
|||
dotEl.style.top = `${renderY}px`;
|
||||
dotEl.style.left = `${renderX}px`;
|
||||
|
||||
if (currentRect) {
|
||||
const previewRect = normalizeRect({
|
||||
...currentRect,
|
||||
x2: snapX,
|
||||
y2: snapY
|
||||
});
|
||||
if (currentShape) {
|
||||
const tool = currentShape.tool;
|
||||
|
||||
clearCanvas();
|
||||
rects.forEach(drawRect);
|
||||
shapes.forEach(drawShape);
|
||||
|
||||
ctx.save();
|
||||
ctx.setLineDash([5, 3]);
|
||||
drawRect(previewRect);
|
||||
|
||||
if (tool === 'line') {
|
||||
const previewLine = {
|
||||
type: 'line',
|
||||
x1: currentShape.x1,
|
||||
y1: currentShape.y1,
|
||||
x2: snapX,
|
||||
y2: snapY,
|
||||
color: currentShape.color
|
||||
};
|
||||
drawShape(previewLine);
|
||||
} else {
|
||||
const previewRect = normalizeRect({
|
||||
...currentShape,
|
||||
x2: snapX,
|
||||
y2: snapY
|
||||
});
|
||||
drawShape(previewRect);
|
||||
}
|
||||
|
||||
ctx.setLineDash([]);
|
||||
ctx.restore();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -228,34 +271,66 @@
|
|||
|
||||
if (e.target.closest('#toolBar')) return;
|
||||
|
||||
const {ix, iy, x: snapX, y: snapY} = snapToGrid(e.clientX, e.clientY);
|
||||
const {x: snapX, y: snapY} = snapToGrid(e.clientX, e.clientY);
|
||||
const tool = getActiveTool();
|
||||
|
||||
currentRect = {
|
||||
x1: snapX,
|
||||
y1: snapY,
|
||||
x2: snapX,
|
||||
y2: snapY,
|
||||
color: selectedColor,
|
||||
fill: document.getElementById('filled').checked
|
||||
};
|
||||
if (tool === 'line') {
|
||||
currentShape = {
|
||||
tool,
|
||||
type: 'line',
|
||||
x1: snapX,
|
||||
y1: snapY,
|
||||
x2: snapX,
|
||||
y2: snapY,
|
||||
color: selectedColor
|
||||
};
|
||||
} else {
|
||||
currentShape = {
|
||||
tool,
|
||||
x1: snapX,
|
||||
y1: snapY,
|
||||
x2: snapX,
|
||||
y2: snapY,
|
||||
color: selectedColor,
|
||||
fill: document.getElementById('filled').checked
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('mouseup', (e) => {
|
||||
if (!currentRect) return;
|
||||
if (!currentShape) return;
|
||||
|
||||
const {ix, iy, x: snapX, y: snapY } = snapToGrid(e.clientX, e.clientY);
|
||||
const { x: snapX, y: snapY } = snapToGrid(e.clientX, e.clientY);
|
||||
|
||||
currentRect.x2 = snapX;
|
||||
currentRect.y2 = snapY;
|
||||
currentShape.x2 = snapX;
|
||||
currentShape.y2 = snapY;
|
||||
|
||||
const finalRect = normalizeRect(currentRect);
|
||||
let finalShape = null;
|
||||
|
||||
if (finalRect.w > 0 && finalRect.h > 0) {
|
||||
rects.push(finalRect);
|
||||
if (currentShape.tool === 'line') {
|
||||
finalShape = {
|
||||
type: 'line',
|
||||
x1: currentShape.x1,
|
||||
y1: currentShape.y1,
|
||||
x2: currentShape.x2,
|
||||
y2: currentShape.y2,
|
||||
color: currentShape.color
|
||||
};
|
||||
} else {
|
||||
const rect = normalizeRect(currentShape);
|
||||
|
||||
if (rect.w > 0 && rect.h > 0) {
|
||||
finalShape = rect;
|
||||
}
|
||||
}
|
||||
clearCanvas();
|
||||
rects.forEach(drawRect);
|
||||
|
||||
currentRect = null;
|
||||
if (finalShape) {
|
||||
shapes.push(finalShape);
|
||||
}
|
||||
|
||||
clearCanvas();
|
||||
shapes.forEach(drawShape);
|
||||
|
||||
currentShape = null;
|
||||
});
|
||||
{% endblock %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue