Various bug fixes.
This commit is contained in:
parent
cc32b2214c
commit
82c3ea2b90
2 changed files with 97 additions and 26 deletions
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
// Pointer finalize (for drawing finishing outside the element)
|
||||
const forwardPointer = (e) => {
|
||||
const w = window.activeGridWidget;
|
||||
const w = window.__gridPointerOwner || window.activeGridWidget;
|
||||
if (!w || typeof w.handleGlobalPointerUp !== 'function') return;
|
||||
w.handleGlobalPointerUp(e);
|
||||
};
|
||||
|
|
@ -763,24 +763,30 @@ function initGridWidget(root, opts = {}) {
|
|||
resizeAndSetupCanvas();
|
||||
redrawAll();
|
||||
|
||||
// ✅ viewer mode still needs to respond to layout/resize
|
||||
if (mode !== 'editor') {
|
||||
const ro = new ResizeObserver(() => resizeAndSetupCanvas());
|
||||
ro.observe(gridEl);
|
||||
let resizeRAF = 0;
|
||||
const scheduleResize = () => {
|
||||
if (resizeRAF) return;
|
||||
resizeRAF = requestAnimationFrame(() => {
|
||||
resizeRAF = 0;
|
||||
resizeAndSetupCanvas();
|
||||
});
|
||||
};
|
||||
|
||||
const ro = new ResizeObserver(scheduleResize);
|
||||
ro.observe(gridWrapEl);
|
||||
|
||||
// optional, but helps with viewport changes
|
||||
window.addEventListener('resize', resizeAndSetupCanvas, { passive: true });
|
||||
window.addEventListener('resize', scheduleResize, { passive: true });
|
||||
|
||||
// also optional: if it's inside tabs/collapses, kick one extra redraw
|
||||
requestAnimationFrame(() => resizeAndSetupCanvas());
|
||||
requestAnimationFrame(scheduleResize);
|
||||
|
||||
return {
|
||||
setDoc,
|
||||
redraw: redrawAll,
|
||||
destroy() {
|
||||
if (window.activeGridWidget === api) window.activeGridWidget = null;
|
||||
ro.disconnect();
|
||||
window.removeEventListener('resize', resizeAndSetupCanvas);
|
||||
window.removeEventListener('resize', scheduleResize);
|
||||
},
|
||||
decode
|
||||
};
|
||||
|
|
@ -903,11 +909,35 @@ function initGridWidget(root, opts = {}) {
|
|||
},
|
||||
|
||||
handleGlobalPointerUp(e) {
|
||||
// Only finalize if this widget is the active one (it should be)
|
||||
finishPointer(e);
|
||||
}
|
||||
},
|
||||
|
||||
cancelStroke() { cancelStroke(); }
|
||||
};
|
||||
|
||||
function destroy() {
|
||||
if (window.activeGridWidget === api) window.activeGridWidget = null;
|
||||
|
||||
currentShape = null;
|
||||
activePointerId = null;
|
||||
|
||||
try {
|
||||
if (window.__gridPointerId != null && gridEl.hasPointerCapture?.(window.__gridPointerId)) {
|
||||
gridEl.releasePointerCapture(window.__gridPointerId);
|
||||
}
|
||||
} catch { }
|
||||
|
||||
if (window.__gridPointerOwner === api) {
|
||||
window.__gridPointerOwner = null;
|
||||
window.__gridPointerId = null;
|
||||
}
|
||||
|
||||
ro.disconnect();
|
||||
}
|
||||
|
||||
|
||||
api.destroy = destroy;
|
||||
|
||||
root.addEventListener('focusin', () => { window.activeGridWidget = api; });
|
||||
|
||||
root.addEventListener('pointerdown', () => {
|
||||
|
|
@ -1005,12 +1035,15 @@ function initGridWidget(root, opts = {}) {
|
|||
}
|
||||
|
||||
function finishPointer(e) {
|
||||
if (window.activeGridWidget !== api) return;
|
||||
if (window.__gridPointerOwner !== api) return;
|
||||
if (!currentShape) return;
|
||||
if (activePointerId !== null && e.pointerId !== activePointerId) return;
|
||||
if (e.pointerId !== activePointerId) return;
|
||||
|
||||
onPointerUp(e);
|
||||
activePointerId = null;
|
||||
|
||||
window.__gridPointerOwner = null;
|
||||
window.__gridPointerId = null;
|
||||
}
|
||||
|
||||
function renderAllWithPreview(previewShape = null, dashed = true) {
|
||||
|
|
@ -1111,7 +1144,7 @@ function initGridWidget(root, opts = {}) {
|
|||
const nearLeft = Math.abs(p.x - minX) <= tol && p.y >= minY - tol && p.y <= maxY + tol;
|
||||
const nearRight = Math.abs(p.x - maxX) <= tol && p.y >= minY - tol && p.y <= maxY + tol;
|
||||
const nearTop = Math.abs(p.y - minY) <= tol && p.x >= minX - tol && p.x <= maxX + tol;
|
||||
const nearBottom = Math.abs(p.y - minX) <= tol && p.x >= minX - tol && p.x <= maxX + tol;
|
||||
const nearBottom = Math.abs(p.y - maxY) <= tol && p.x >= minX - tol && p.x <= maxX + tol;
|
||||
|
||||
return nearLeft || nearRight || nearTop || nearBottom;
|
||||
}
|
||||
|
|
@ -1477,6 +1510,21 @@ function initGridWidget(root, opts = {}) {
|
|||
};
|
||||
}
|
||||
|
||||
function cancelStroke(e) {
|
||||
const owns = (window.__gridPointerOwner === api) &&
|
||||
(e ? window.__gridPointerId === e.pointerId : true);
|
||||
|
||||
if (!owns) return;
|
||||
|
||||
currentShape = null;
|
||||
activePointerId = null;
|
||||
|
||||
window.__gridPointerOwner = null;
|
||||
window.__gridPointerId = null;
|
||||
|
||||
redrawAll();
|
||||
}
|
||||
|
||||
function onPointerUp(e) {
|
||||
if (!currentShape) return;
|
||||
|
||||
|
|
@ -1718,15 +1766,8 @@ function initGridWidget(root, opts = {}) {
|
|||
currentStrokeWidth = Math.max(0, Number(strokeWidthEl.value) || 0.12);
|
||||
});
|
||||
|
||||
gridEl.addEventListener('pointercancel', () => {
|
||||
currentShape = null;
|
||||
redrawAll();
|
||||
});
|
||||
|
||||
gridEl.addEventListener('lostpointercapture', () => {
|
||||
currentShape = null;
|
||||
redrawAll();
|
||||
});
|
||||
gridEl.addEventListener('pointercancel', (e) => cancelStroke(e));
|
||||
gridEl.addEventListener('lostpointercapture', (e) => cancelStroke(e));
|
||||
|
||||
gridEl.addEventListener('pointermove', (e) => {
|
||||
if (!ctx) return;
|
||||
|
|
@ -1807,6 +1848,10 @@ function initGridWidget(root, opts = {}) {
|
|||
|
||||
e.preventDefault();
|
||||
activePointerId = e.pointerId;
|
||||
|
||||
window.__gridPointerOwner = api;
|
||||
window.__gridPointerId = e.pointerId;
|
||||
|
||||
try {
|
||||
gridEl.setPointerCapture(e.pointerId);
|
||||
} catch {
|
||||
|
|
@ -1866,6 +1911,8 @@ function initGridWidget(root, opts = {}) {
|
|||
};
|
||||
}
|
||||
});
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
(function autoBootGridWidgets() {
|
||||
|
|
@ -1915,6 +1962,19 @@ function initGridWidget(root, opts = {}) {
|
|||
|
||||
const mo = new MutationObserver((mutations) => {
|
||||
for (const m of mutations) {
|
||||
for (const node of m.removedNodes) {
|
||||
if (!(node instanceof Element)) continue;
|
||||
|
||||
const roots = [];
|
||||
if (node.matches?.('[data-grid-widget]')) roots.push(node);
|
||||
node.querySelectorAll?.('[data-grid-widget]').forEach(r => roots.push(r));
|
||||
|
||||
for (const r of roots) {
|
||||
r.__gridApi?.destroy?.();
|
||||
r.__gridApi = null;
|
||||
}
|
||||
}
|
||||
|
||||
for (const node of m.addedNodes) {
|
||||
if (!(node instanceof Element)) continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,15 +14,26 @@
|
|||
{"v":1,"cs":5,"q":100,"d":{"cl":"#000000","f":false,"sw":12,"so":100,"fo":100},"s":[{"t":"s","cl":"#ffe59e","f":true},{"t":"e","p":[0,0,2500,2500]},{"t":"s","cl":"#fdc8fe"},{"t":"e","p":[100,100,2300,2300]},{"t":"s","cl":"#fbe6a1"},{"t":"e","p":[600,600,1300,1300]},{"t":"s","cl":"#ffffff"},{"t":"e","p":[700,700,1100,1100]},{"t":"s","cl":"#000000","f":false},{"t":"e","p":[0,0,2500,2500,-2400,-2400,2300,2300,-1800,-1800,1300,1300,-1200,-1200,1100,1100]},{"t":"s","sw":37,"cl":"#ff0000"},{"t":"l","p":[600,500,100,-100,500,0,100,0,500,200,100,100,200,200,100,-100,-600,-400,0,-100,-800,300,-100,100,-400,800,0,-100,100,-400,-100,-100,200,1000,100,0,-100,-600,-100,-100,500,1000,100,-100,-200,-200,0,100,500,200,100,-100,200,-200,100,100,-500,0,-100,100,800,-400,100,100,0,-400,100,100,0,-300,100,0,-200,-100,0,-100,0,-400,0,100,-400,-200,100,0,-600,-200,100,-100,-300,100,0,100,-300,500,-100,-100,0,900,100,-100,1300,400,100,-100,200,-200,0,-100,100,-200,0,-100]},{"t":"s","cl":"#00ff00"},{"t":"l","p":[400,700,100,0,500,-200,0,-100,400,-200,0,100,100,200,100,100,200,-200,100,100,300,600,100,0,-400,-300,100,100,100,400,100,0,100,200,-100,0,-200,100,100,100,0,200,100,-100,-400,100,0,-100,-100,300,100,0,-200,200,0,-100,-100,-200,0,100,-200,200,100,0,-300,0,0,-100,200,-100,100,-100,-400,0,100,0,-300,100,100,0,-200,-300,0,100,-200,-100,100,0,-200,-100,0,-100,100,-100,0,-100,-300,-100,100,0,0,-200,100,0,100,-200,0,100,100,-400,100,0]},{"t":"s","cl":"#0000ff"},{"t":"l","p":[800,400,0,100,300,0,100,0,200,-100,100,-100,200,0,0,100,300,100,100,100,0,200,0,-100,0,300,100,0,-200,300,0,-100,100,200,100,0,-300,100,0,100,0,200,0,100,-200,-100,0,100,200,200,-100,-100,0,200,-100,0,-100,-100,0,-100,-100,200,-100,0,-200,100,0,-100,-300,100,100,-100,-100,-300,0,100,-300,100,100,0,-200,-100,100,0,-200,-100,-100,-100,0,-200,100,-100,0,-200,-100,-100,100,-400,-100,0,200,300,100,-100,100,-200,-100,-100,300,-100,100,0,-500,-100,-100,100,1300,100,100,100,-1200,900,100,0]}]}
|
||||
{% endset %}
|
||||
<div class="row">
|
||||
<div class="col" style="height: 80vh;">
|
||||
<div class="col" style="height: 80vh">
|
||||
{{ draw.drawWidget('test1') }}
|
||||
</div>
|
||||
<div class="col" style="height: 80vh;">
|
||||
<!-- div class="col">
|
||||
{{ draw.drawWidget('test4') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
{{ draw.drawWidget('test5') }}
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ draw.drawWidget('test6') }}
|
||||
</div -->
|
||||
<!-- div class="col" style="height: 80vh;">
|
||||
I am testing a thing.
|
||||
{{ draw.viewWidget('test2', jsonImage) }}
|
||||
{{ draw.viewWidget('test3', jsonImage2) }}
|
||||
The thing has been tested.
|
||||
</div>
|
||||
</div -->
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue