From cc32b2214cebcb2feb0baea43d1ab45612220e03 Mon Sep 17 00:00:00 2001 From: Yaro Kasear Date: Mon, 12 Jan 2026 15:12:11 -0600 Subject: [PATCH] Delta differential coding --- inventory/static/js/components/draw.js | 164 +++++++++++++++++++------ inventory/templates/testing.html | 8 +- 2 files changed, 128 insertions(+), 44 deletions(-) diff --git a/inventory/static/js/components/draw.js b/inventory/static/js/components/draw.js index aff7874..ee50b39 100644 --- a/inventory/static/js/components/draw.js +++ b/inventory/static/js/components/draw.js @@ -157,44 +157,100 @@ function initGridWidget(root, opts = {}) { } function computeDeltas(shapes) { - return shapes.map(shape => { - if (shape.type === 'stateChange') return shape; + const q = 100; - const s = { ...shape }; - let points = []; + const out = []; + let prevKind = null; - if (s.type === 'path') { - if (!Array.isArray(s.points) || s.points.length === 0) return s; + let prevBR = null; - points = [Math.round(s.points[0].x * 100), Math.round(s.points[0].y * 100)]; - let prev = s.points[0]; + let prevLineEnd = null; - for (let i = 1; i < s.points.length; i++) { - const cur = s.points[i]; - points.push(Math.round((cur.x - prev.x) * 100), Math.round((cur.y - prev.y) * 100)); - prev = cur; - } - } else if (s.type === 'line') { - points = [ - Math.round(s.x1 * 100), - Math.round(s.y1 * 100), - Math.round((s.x2 - s.x1) * 100), - Math.round((s.y2 - s.y1) * 100) - ]; - delete s.x1; delete s.y1; delete s.x2; delete s.y2; - } else if (s.type === 'rect' || s.type === 'ellipse') { - points = [ - Math.round(s.x * 100), - Math.round(s.y * 100), - Math.round(s.w * 100), - Math.round(s.h * 100) - ]; - delete s.x; delete s.y; delete s.w; delete s.h; + const toInt = (n) => Math.round(Number(n) * q); + + const resetRun = () => { + prevKind = null; + prevBR = null; + prevLineEnd = null; + }; + + for (const shape of shapes) { + if (shape.type === "stateChange") { + out.push(shape); + resetRun(); + continue; } - s.points = points; - return s; - }); + if (shape.type === "path") { + const s = { ...shape }; + if (!Array.isArray(s.points) || s.points.length === 0) { + out.push(s); + resetRun(); + continue; + } + + const pts = [toInt(s.points[0].x), toInt(s.points[0].y)]; + let prev = s.points[0]; + for (let i = 1; i < s.points.length; i++) { + const cur = s.points[i]; + pts.push(toInt(cur.x - prev.x), toInt(cur.y - prev.y)); + prev = cur; + } + s.points = pts; + out.push(s); + resetRun(); + continue; + } + + if (shape.type === "line") { + const s = { ...shape }; + + const x1 = toInt(s.x1), y1 = toInt(s.y1); + const x2 = toInt(s.x2), y2 = toInt(s.y2); + + let arr; + if (prevKind !== "line" || !prevLineEnd) { + arr = [x1, y1, x2 - x1, y2 - y1]; + } else { + arr = [x1 - prevLineEnd.x2, y1 - prevLineEnd.y2, x2 - x1, y2 - y1]; + } + + prevKind = "line"; + prevLineEnd = { x2, y2 }; + + delete s.x1; delete s.y1; delete s.x2; delete s.y2; + s.points = arr; + out.push(s); + continue; + } + + if (shape.type === "rect" || shape.type === "ellipse") { + const s = { ...shape }; + + const x = toInt(s.x), y = toInt(s.y); + const w = toInt(s.w), h = toInt(s.h); + + let arr; + if (prevKind !== s.type || !prevBR) { + arr = [x, y, w, h]; + } else { + arr = [x - prevBR.x, y - prevBR.y, w, h]; + } + + prevKind = s.type; + prevBR = { x: x + w, y: y + h }; + + delete s.x; delete s.y; delete s.w; delete s.h; + s.points = arr; + out.push(s); + continue; + } + + out.push(shape); + resetRun(); + } + + return out; } function encodeRuns(shapes) { @@ -332,37 +388,65 @@ function initGridWidget(root, opts = {}) { if ((arr.length % 4) !== 0) continue; if (t === "l") { + let prevX2 = null, prevY2 = null; + for (let i = 0; i < arr.length; i += 4) { - const seg = decodeLine(arr.slice(i, i + 4), q); + const a = arr[i], b = arr[i + 1], c = arr[i + 2], d = arr[i + 3]; + + let x1, y1; + if (i === 0) { + x1 = a; y1 = b; + } else { + x1 = prevX2 + a; + y1 = prevY2 + b; + } + + const x2 = x1 + c; + const y2 = y1 + d; + outShapes.push({ type: "line", - x1: seg.x1, y1: seg.y1, x2: seg.x2, y2: seg.y2, + x1: x1 / q, y1: y1 / q, x2: x2 / q, y2: y2 / q, color: state.color, strokeWidth: state.strokeWidth, strokeOpacity: state.strokeOpacity }); + + prevX2 = x2; prevY2 = y2; } continue; } if (t === "r" || t === "e") { + let prevBRx = null, prevBRy = null; + for (let i = 0; i < arr.length; i += 4) { - const x = arr[i] / q; - const y = arr[i + 1] / q; - const w = arr[i + 2] / q; - const h = arr[i + 3] / q; + const a = arr[i], b = arr[i + 1], c = arr[i + 2], d = arr[i + 3]; + + let x, y; + if (i === 0) { + x = a; y = b; + } else { + x = prevBRx + a; + y = prevBRy + b; + } + + const w = c, h = d; outShapes.push({ type: (t === "r") ? "rect" : "ellipse", - x, y, w, h, + x: x / q, y: y / q, w: w / q, h: h / q, color: state.color, fill: state.fill, fillOpacity: state.fillOpacity, strokeWidth: state.strokeWidth, strokeOpacity: state.strokeOpacity }); + + prevBRx = x + w; + prevBRy = y + h; } - continue + continue; } } diff --git a/inventory/templates/testing.html b/inventory/templates/testing.html index 73f42e2..32a21dd 100644 --- a/inventory/templates/testing.html +++ b/inventory/templates/testing.html @@ -8,21 +8,21 @@ {% block main %} {% set jsonImage %} -{"v":1,"cs":5,"q":100,"d":{"cl":"#000000","f":false,"sw":12,"so":100,"fo":100},"s":[{"t":"s","cl":"#e8af11","f":true},{"t":"e","p":[1000,500,2500,2500]},{"t":"s","cl":"#f7a6f4"},{"t":"e","p":[1100,600,2300,2300]},{"t":"s","cl":"#e2b128"},{"t":"e","p":[1600,1100,1300,1300]},{"t":"s","cl":"#ffffff"},{"t":"e","p":[1700,1200,1100,1100]},{"t":"s","cl":"#000000","f":false},{"t":"e","p":[1000,500,2500,2500,1100,600,2300,2300,1600,1100,1300,1300,1700,1200,1100,1100]},{"t":"s","sw":30,"cl":"#ff0000"},{"t":"l","p":[2900,1100,100,0,3100,1700,0,100,3000,2200,100,0,2700,2600,0,-100,2000,2600,100,100,1600,2300,-100,0,1400,1900,0,-100,1300,1400,100,0,1600,1100,0,100,1900,900,100,-100,2300,900,100,100,2600,900,100,-100,3000,1400,100,0,2800,2300,100,0,2500,2600,-100,100,1700,2600,100,-100]},{"t":"s","cl":"#00ff00"},{"t":"l","p":[2700,1100,100,-100,2000,1000,100,0,1400,1600,100,-100,1400,2200,100,0,1300,1900,-100,100,1900,2700,0,-100,2100,2600,100,0,2300,2800,100,0,2500,2400,100,100,2900,2500,100,-100,3200,2000,-100,0,3100,1600,100,-100,3100,1300,-100,0,2400,700,-100,100,1700,900,100,100]},{"t":"s","cl":"#6188ff"},{"t":"l","p":[1500,1300,100,0,1200,1700,100,0,1500,2100,0,-100,1600,2600,0,-100,2000,2500,-100,-100,2400,2500,-100,0,2700,2400,100,0,2900,2100,100,-100,3300,1800,0,100,3000,1600,-100,-100,3200,1700,0,-100,2900,1200,-100,0,2500,900,0,100,2200,900,0,-100,1800,1100,-100,0,1500,1100,-100,100,1700,2400,0,-100,1300,2300,100,100,2600,2800,100,-100,2100,2800,100,-100,3100,2300,100,0,3200,2100,100,-100,2700,1200,100,100,1500,1700,100,-100]}]} +{"v":1,"cs":5,"q":100,"d":{"cl":"#000000","f":false,"sw":12,"so":100,"fo":100},"s":[{"t":"s","cl":"#ffff00","f":true},{"t":"e","p":[0,0,2500,2500]},{"t":"s","cl":"#ffffff"},{"t":"e","p":[500,600,600,600,300,-600,600,600]},{"t":"s","cl":"#000000"},{"t":"e","p":[700,800,200,200,700,-200,200,200,-800,300,500,1000]},{"t":"s","f":false},{"t":"e","p":[500,600,600,600,300,-600,600,600,-2000,-1200,2500,2500]},{"t":"l","p":[400,700,500,-300,1200,300,-500,-300]}]} {% endset %} {% set jsonImage2 %} -{"v":1,"cs":5,"q":100,"d":{"cl":"#000000","f":false,"sw":12,"so":100,"fo":100},"s":[{"t":"r","p":[1000,500,1500,1500,1000,500,500,500,1500,500,500,500,2000,500,500,500,2000,1000,500,500,1500,1000,500,500,1000,1000,500,500,1000,1500,500,500,1500,1500,500,500,2000,1500,500,500]},{"t":"s","so":0,"fo":50,"cl":"#ff0000","f":true},{"t":"r","p":[1000,500,500,500,2000,1500,500,500,2000,500,500,500,1000,1500,500,500]},{"t":"s","cl":"#00ff00"},{"t":"r","p":[1500,1000,500,500]},{"t":"s","cl":"#0000ff"},{"t":"r","p":[1500,500,500,500,2000,1000,500,500,1500,1500,500,500,1000,1000,500,500]},{"t":"s","sw":2,"so":100,"cl":"#000000","f":false},{"t":"e","p":[1100,600,300,300,1600,600,300,300,2100,600,300,300,2100,1100,300,300,1600,1100,300,300,1100,1100,300,300,1100,1600,300,300,1600,1600,300,300,2100,1600,300,300]},{"t":"s","sw":12},{"t":"r","p":[500,0,2500,2500]},{"t":"s","so":5,"f":true},{"t":"r","p":[500,0,500,2500,1000,2000,2000,500,2500,0,500,2000,1000,0,1500,500]},{"t":"s","so":100},{"t":"l","p":[1000,500,1500,1500,1000,2000,1500,-1500,2000,500,500,500,1500,500,1000,1000,1000,1000,1000,1000,1000,1500,500,500,1500,2000,1000,-1000,2000,2000,500,-500,1000,1500,1000,-1000,1000,1000,500,-500]}]} +{"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 %}
{{ draw.drawWidget('test1') }}
- +
{% endblock %}