Move the dot outside the grid.
This commit is contained in:
parent
e8d9d1a330
commit
c5cc368ef9
1 changed files with 27 additions and 20 deletions
|
|
@ -37,6 +37,11 @@
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#dot {
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 10000;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
@ -48,7 +53,7 @@
|
||||||
<input type="number" min="1" value="25" name="cellSize" id="cellSize" class="form-control form-control-sm">
|
<input type="number" min="1" value="25" name="cellSize" id="cellSize" class="form-control form-control-sm">
|
||||||
|
|
||||||
<span class="input-group-text">Fill Opacity:</span>
|
<span class="input-group-text">Fill Opacity:</span>
|
||||||
<input type="number" min="0" max="1" step=".01" value="0.15" name="fillOpacity" id="fillOpacity"
|
<input type="number" min="0" max="1" step=".01" value="1" name="fillOpacity" id="fillOpacity"
|
||||||
class="form-control form-control-sm">
|
class="form-control form-control-sm">
|
||||||
</div>
|
</div>
|
||||||
<div class="vr mx-1"></div>
|
<div class="vr mx-1"></div>
|
||||||
|
|
@ -171,13 +176,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="gridWrap">
|
<div id="gridWrap">
|
||||||
|
<span id="dot" class="position-absolute p-0 m-0 d-none">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" id="dotSVG">
|
||||||
|
<circle cx="16" cy="16" r="4" fill="black" />
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
<div id="grid" class="position-relative overflow-hidden">
|
<div id="grid" class="position-relative overflow-hidden">
|
||||||
|
|
||||||
<span id="dot" class="position-absolute p-0 m-0 d-none">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" id="dotSVG">
|
|
||||||
<circle cx="16" cy="16" r="4" fill="black" />
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
<div id="coords"
|
<div id="coords"
|
||||||
class="border border-black position-absolute d-none bg-warning-subtle px-1 py-0 user-select-none"></div>
|
class="border border-black position-absolute d-none bg-warning-subtle px-1 py-0 user-select-none"></div>
|
||||||
<canvas id="overlay" class="position-absolute w-100 h-100"></canvas>
|
<canvas id="overlay" class="position-absolute w-100 h-100"></canvas>
|
||||||
|
|
@ -215,7 +219,7 @@ let dotSize = Math.floor(Math.max(cellSize * 1.25, 32));
|
||||||
let ctx;
|
let ctx;
|
||||||
let dpr = 1;
|
let dpr = 1;
|
||||||
let selectedColor;
|
let selectedColor;
|
||||||
let currentOpacity = clamp01(fillOpacityEl?.value ?? 0.15, 0.15);
|
let currentOpacity = clamp01(fillOpacityEl?.value ?? 1, 1);
|
||||||
|
|
||||||
let currentShape = null;
|
let currentShape = null;
|
||||||
const history = [structuredClone(shapes)];
|
const history = [structuredClone(shapes)];
|
||||||
|
|
@ -268,7 +272,7 @@ function commit(nextShapes) {
|
||||||
redrawAll();
|
redrawAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clamp01(n, fallback = 0.15) {
|
function clamp01(n, fallback = 1) {
|
||||||
const x = Number(n);
|
const x = Number(n);
|
||||||
return Number.isFinite(x) ? Math.min(1, Math.max(0, x)) : fallback;
|
return Number.isFinite(x) ? Math.min(1, Math.max(0, x)) : fallback;
|
||||||
}
|
}
|
||||||
|
|
@ -281,7 +285,7 @@ function sanitizeShapes(list) {
|
||||||
return list.flatMap((s) => {
|
return list.flatMap((s) => {
|
||||||
if (!s || typeof s !== 'object' || !allowed.has(s.type)) return [];
|
if (!s || typeof s !== 'object' || !allowed.has(s.type)) return [];
|
||||||
const color = typeof s.color === 'string' ? s.color : '#000000';
|
const color = typeof s.color === 'string' ? s.color : '#000000';
|
||||||
const opacity = clamp01(s.opacity, 0.15);
|
const opacity = clamp01(s.opacity, 1);
|
||||||
|
|
||||||
if (s.type === 'line') {
|
if (s.type === 'line') {
|
||||||
if (!['x1','y1','x2','y2'].every(k => isFiniteNum(s[k]))) return [];
|
if (!['x1','y1','x2','y2'].every(k => isFiniteNum(s[k]))) return [];
|
||||||
|
|
@ -446,7 +450,7 @@ function normalizeRect(shape) {
|
||||||
h: Math.abs(y2 - y1),
|
h: Math.abs(y2 - y1),
|
||||||
color: shape.color,
|
color: shape.color,
|
||||||
fill: shape.fill,
|
fill: shape.fill,
|
||||||
opacity: clamp01(shape.opacity, 0.15)
|
opacity: clamp01(shape.opacity, 1)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -522,7 +526,7 @@ function drawShape(shape) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shape.fill) {
|
if (shape.fill) {
|
||||||
ctx.globalAlpha = clamp01(shape.opacity, 0.15);
|
ctx.globalAlpha = clamp01(shape.opacity, 1);
|
||||||
ctx.fillStyle = shape.color;
|
ctx.fillStyle = shape.color;
|
||||||
if (shape.type === 'rect') {
|
if (shape.type === 'rect') {
|
||||||
ctx.fillRect(x, y, w, h);
|
ctx.fillRect(x, y, w, h);
|
||||||
|
|
@ -702,11 +706,11 @@ document.addEventListener('keydown', (e) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
fillOpacityEl?.addEventListener('input', () => {
|
fillOpacityEl?.addEventListener('input', () => {
|
||||||
currentOpacity = clamp01(fillOpacityEl.value, 0.15);
|
currentOpacity = clamp01(fillOpacityEl.value, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
fillOpacityEl?.addEventListener('change', () => {
|
fillOpacityEl?.addEventListener('change', () => {
|
||||||
currentOpacity = clamp01(fillOpacityEl.value, 0.15);
|
currentOpacity = clamp01(fillOpacityEl.value, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
gridEl.addEventListener('pointercancel', () => {
|
gridEl.addEventListener('pointercancel', () => {
|
||||||
|
|
@ -724,16 +728,19 @@ gridEl.addEventListener('pointermove', (e) => {
|
||||||
|
|
||||||
const { ix, iy, x: snapX, y: snapY, localX, localY } = snapToGrid(e.clientX, e.clientY);
|
const { ix, iy, x: snapX, y: snapY, localX, localY } = snapToGrid(e.clientX, e.clientY);
|
||||||
|
|
||||||
|
|
||||||
const renderX = snapX - dotSize / 2;
|
|
||||||
const renderY = snapY - dotSize / 2;
|
|
||||||
|
|
||||||
coordsEl.classList.remove('d-none');
|
coordsEl.classList.remove('d-none');
|
||||||
|
|
||||||
if (getActiveType() !== 'noGrid') {
|
if (getActiveType() !== 'noGrid') {
|
||||||
dotEl.classList.remove('d-none');
|
dotEl.classList.remove('d-none');
|
||||||
dotEl.style.top = `${renderY}px`;
|
|
||||||
dotEl.style.left = `${renderX}px`;
|
const gridRect = gridEl.getBoundingClientRect();
|
||||||
|
const wrapRect = gridWrapEl.getBoundingClientRect();
|
||||||
|
|
||||||
|
const offsetX = gridRect.left - wrapRect.left;
|
||||||
|
const offsetY = gridRect.top - wrapRect.top;
|
||||||
|
|
||||||
|
dotEl.style.left = `${offsetX + snapX}px`;
|
||||||
|
dotEl.style.top = `${offsetY + snapY}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getActiveType() == 'noGrid') {
|
if (getActiveType() == 'noGrid') {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue