UNPKG

ixfx

Version:

A framework for programming interactivity

443 lines (430 loc) 13.3 kB
import { fromNumbers } from "./chunk-425CNZZO.js"; import { fromLine, toCartesian2 as toCartesian } from "./chunk-R4JIRHLR.js"; import { getCssVariable } from "./chunk-DLFRRV7R.js"; import { __export } from "./chunk-L5EJU35C.js"; // src/visual/svg/index.ts var svg_exports = {}; __export(svg_exports, { Elements: () => Elements_exports, applyOpts: () => applyOpts, applyPathOpts: () => applyPathOpts, applyStrokeOpts: () => applyStrokeOpts, clear: () => clear, createEl: () => createEl, createMarker: () => createMarker, createOrResolve: () => createOrResolve, getBounds: () => getBounds, lineFromSvgLine: () => lineFromSvgLine, makeHelper: () => makeHelper, markerPrebuilt: () => markerPrebuilt, polarRayFromSvgLine: () => polarRayFromSvgLine, remove: () => remove, setBounds: () => setBounds }); // src/visual/svg/Apply.ts var applyOpts = (elem, opts) => { if (opts.fillStyle) elem.setAttributeNS(null, `fill`, opts.fillStyle); if (opts.opacity) { elem.setAttributeNS(null, `opacity`, opts.opacity.toString()); } }; // src/visual/svg/Bounds.ts var getBounds = (svg) => { const w = svg.getAttributeNS(null, `width`); const width = w === null ? 0 : Number.parseFloat(w); const h = svg.getAttributeNS(null, `height`); const height = h === null ? 0 : Number.parseFloat(h); return { width, height }; }; var setBounds = (svg, bounds) => { svg.setAttributeNS(null, `width`, bounds.width.toString()); svg.setAttributeNS(null, `height`, bounds.height.toString()); }; // src/visual/svg/Create.ts var createEl = (type, id) => { const m = document.createElementNS(`http://www.w3.org/2000/svg`, type); if (id) { m.id = id; } return m; }; var createOrResolve = (parent, type, queryOrExisting, suffix) => { let existing = null; if (queryOrExisting !== void 0) { existing = typeof queryOrExisting === `string` ? parent.querySelector(queryOrExisting) : queryOrExisting; } if (existing === null) { const p = document.createElementNS(`http://www.w3.org/2000/svg`, type); parent.append(p); if (queryOrExisting && typeof queryOrExisting === `string` && queryOrExisting.startsWith(`#`)) { p.id = suffix !== void 0 && !queryOrExisting.endsWith(suffix) ? queryOrExisting.slice(1) + suffix : queryOrExisting.slice(1); } return p; } return existing; }; // src/visual/svg/Elements.ts var Elements_exports = {}; __export(Elements_exports, { circle: () => circle, circleUpdate: () => circleUpdate, grid: () => grid, group: () => group, groupUpdate: () => groupUpdate, line: () => line, lineUpdate: () => lineUpdate, path: () => path, pathUpdate: () => pathUpdate, polarRayUpdate: () => polarRayUpdate, text: () => text, textPath: () => textPath, textPathUpdate: () => textPathUpdate, textUpdate: () => textUpdate }); // src/visual/svg/Stroke.ts var applyStrokeOpts = (elem, opts) => { if (opts.strokeStyle) elem.setAttributeNS(null, `stroke`, opts.strokeStyle); if (opts.strokeWidth) { elem.setAttributeNS(null, `stroke-width`, opts.strokeWidth.toString()); } if (opts.strokeDash) elem.setAttribute(`stroke-dasharray`, opts.strokeDash); if (opts.strokeLineCap) { elem.setAttribute(`stroke-linecap`, opts.strokeLineCap); } }; // src/visual/svg/Markers.ts var createMarker = (id, opts, childCreator) => { const m = createEl(`marker`, id); if (opts.markerWidth) { m.setAttribute(`markerWidth`, opts.markerWidth?.toString()); } if (opts.markerHeight) { m.setAttribute(`markerHeight`, opts.markerHeight?.toString()); } if (opts.orient) m.setAttribute(`orient`, opts.orient.toString()); else m.setAttribute(`orient`, `auto-start-reverse`); if (opts.viewBox) m.setAttribute(`viewBox`, opts.viewBox.toString()); if (opts.refX) m.setAttribute(`refX`, opts.refX.toString()); if (opts.refY) m.setAttribute(`refY`, opts.refY.toString()); if (childCreator) { const c = childCreator(); m.appendChild(c); } return m; }; var markerPrebuilt = (elem, opts, _context) => { if (elem === null) return `(elem null)`; const parent = elem.ownerSVGElement; if (parent === null) throw new Error(`parent for elem is null`); const defsEl = createOrResolve(parent, `defs`, `defs`); let defEl = defsEl.querySelector(`#${opts.id}`); if (defEl !== null) { return `url(#${opts.id})`; } if (opts.id === `triangle`) { opts = { ...opts, strokeStyle: `transparent` }; if (!opts.markerHeight) opts = { ...opts, markerHeight: 6 }; if (!opts.markerWidth) opts = { ...opts, markerWidth: 6 }; if (!opts.refX) opts = { ...opts, refX: opts.markerWidth }; if (!opts.refY) opts = { ...opts, refY: opts.markerHeight }; if (!opts.fillStyle || opts.fillStyle === `none`) { opts = { ...opts, fillStyle: `black` }; } if (!opts.viewBox) opts = { ...opts, viewBox: `0 0 10 10` }; defEl = createMarker(opts.id, opts, () => { const tri = createEl(`path`); tri.setAttribute(`d`, `M 0 0 L 10 5 L 0 10 z`); if (opts) applyOpts(tri, opts); return tri; }); } else throw new Error(`Do not know how to make ${opts.id}`); defEl.id = opts.id; defsEl.appendChild(defEl); return `url(#${opts.id})`; }; // src/visual/svg/Path.ts var applyPathOpts = (elem, opts) => { if (opts.markerEnd) { elem.setAttribute( `marker-end`, markerPrebuilt(elem, opts.markerEnd, opts) ); } if (opts.markerStart) { elem.setAttribute( `marker-start`, markerPrebuilt(elem, opts.markerStart, opts) ); } if (opts.markerMid) { elem.setAttribute( `marker-mid`, markerPrebuilt(elem, opts.markerMid, opts) ); } }; // src/visual/svg/Elements.ts var numberOrPercentage = (v) => { if (v >= 0 && v <= 1) return `${v * 100}%`; return v.toString(); }; var path = (svgOrArray, parent, opts, queryOrExisting) => { const elem = createOrResolve( parent, `path`, queryOrExisting ); const svg = typeof svgOrArray === `string` ? svgOrArray : svgOrArray.join(` `); elem.setAttributeNS(null, `d`, svg); parent.append(elem); return pathUpdate(elem, opts); }; var pathUpdate = (elem, opts) => { if (opts) applyOpts(elem, opts); if (opts) applyStrokeOpts(elem, opts); return elem; }; var circleUpdate = (elem, circle2, opts) => { elem.setAttributeNS(null, `cx`, circle2.x.toString()); elem.setAttributeNS(null, `cy`, circle2.y.toString()); elem.setAttributeNS(null, `r`, circle2.radius.toString()); if (opts) applyOpts(elem, opts); if (opts) applyStrokeOpts(elem, opts); return elem; }; var circle = (circle2, parent, opts, queryOrExisting) => { const p = createOrResolve( parent, `circle`, queryOrExisting ); return circleUpdate(p, circle2, opts); }; var group = (children, parent, queryOrExisting) => { const p = createOrResolve(parent, `g`, queryOrExisting); return groupUpdate(p, children); }; var groupUpdate = (elem, children) => { for (const c of children) { if (c.parentNode !== elem) { elem.append(c); } } return elem; }; var line = (line2, parent, opts, queryOrExisting) => { const lineEl = createOrResolve( parent, `line`, queryOrExisting ); return lineUpdate(lineEl, line2, opts); }; var lineUpdate = (lineEl, line2, opts) => { lineEl.setAttributeNS(null, `x1`, line2.a.x.toString()); lineEl.setAttributeNS(null, `y1`, line2.a.y.toString()); lineEl.setAttributeNS(null, `x2`, line2.b.x.toString()); lineEl.setAttributeNS(null, `y2`, line2.b.y.toString()); if (opts) applyOpts(lineEl, opts); if (opts) applyPathOpts(lineEl, opts); if (opts) applyStrokeOpts(lineEl, opts); return lineEl; }; var polarRayUpdate = (lineEl, ray, opts) => { const l = toCartesian(ray); lineEl.setAttributeNS(null, `x1`, l.a.x.toString()); lineEl.setAttributeNS(null, `y1`, l.a.y.toString()); lineEl.setAttributeNS(null, `x2`, l.b.x.toString()); lineEl.setAttributeNS(null, `y2`, l.b.y.toString()); if (opts) applyOpts(lineEl, opts); if (opts) applyPathOpts(lineEl, opts); if (opts) applyStrokeOpts(lineEl, opts); return lineEl; }; var textPathUpdate = (el, text2, opts) => { if (opts?.method) el.setAttributeNS(null, `method`, opts.method); if (opts?.side) el.setAttributeNS(null, `side`, opts.side); if (opts?.spacing) el.setAttributeNS(null, `spacing`, opts.spacing); if (opts?.startOffset) { el.setAttributeNS(null, `startOffset`, numberOrPercentage(opts.startOffset)); } if (opts?.textLength) { el.setAttributeNS(null, `textLength`, numberOrPercentage(opts.textLength)); } if (text2) { el.textContent = text2; } if (opts) applyOpts(el, opts); if (opts) applyStrokeOpts(el, opts); return el; }; var textPath = (pathReference, text2, parent, opts, textQueryOrExisting, pathQueryOrExisting) => { const textEl = createOrResolve( parent, `text`, textQueryOrExisting, `-text` ); textUpdate(textEl, void 0, void 0, opts); const p = createOrResolve( textEl, `textPath`, pathQueryOrExisting ); p.setAttributeNS(null, `href`, pathReference); return textPathUpdate(p, text2, opts); }; var textUpdate = (el, pos, text2, opts) => { if (pos) { el.setAttributeNS(null, `x`, pos.x.toString()); el.setAttributeNS(null, `y`, pos.y.toString()); } if (text2) { el.textContent = text2; } if (opts) { applyOpts(el, opts); if (opts) applyStrokeOpts(el, opts); if (opts.anchor) el.setAttributeNS(null, `text-anchor`, opts.anchor); if (opts.align) el.setAttributeNS(null, `alignment-baseline`, opts.align); const userSelect = opts.userSelect ?? true; if (!userSelect) { el.style.userSelect = `none`; el.style.webkitUserSelect = `none`; } } return el; }; var text = (text2, parent, pos, opts, queryOrExisting) => { const p = createOrResolve( parent, `text`, queryOrExisting ); return textUpdate(p, pos, text2, opts); }; var grid = (parent, center, spacing, width, height, opts = {}) => { if (!opts.strokeStyle) { opts = { ...opts, strokeStyle: getCssVariable(`bg-dim`, `silver`) }; } if (!opts.strokeWidth) opts = { ...opts, strokeWidth: 1 }; const g = createEl(`g`); applyOpts(g, opts); applyPathOpts(g, opts); applyStrokeOpts(g, opts); let y = 0; while (y < height) { const horiz = fromNumbers(0, y, width, y); line(horiz, g); y += spacing; } let x = 0; while (x < width) { const vert = fromNumbers(x, 0, x, height); line(vert, g); x += spacing; } parent.append(g); return g; }; // src/visual/svg/Geometry.ts var lineFromSvgLine = (el) => { if (!el) throw new Error(`Param 'el' is undefined`); const a = { x: el.x1.baseVal.value, y: el.y1.baseVal.value }; const b = { x: el.x2.baseVal.value, y: el.y2.baseVal.value }; return { a, b }; }; var polarRayFromSvgLine = (el, origin) => { const l = lineFromSvgLine(el); return fromLine(l, origin); }; // src/visual/svg/Remove.ts var remove = (parent, queryOrExisting) => { if (typeof queryOrExisting === `string`) { const elem = parent.querySelector(queryOrExisting); if (elem === null) return; elem.remove(); } else { queryOrExisting.remove(); } }; var clear = (parent) => { let c = parent.lastElementChild; while (c) { c.remove(); c = parent.lastElementChild; } }; // src/visual/svg/Helper.ts var makeHelper = (parent, parentOpts) => { if (parentOpts) { applyOpts(parent, parentOpts); applyStrokeOpts(parent, parentOpts); } const o = { remove: (queryOrExisting) => { remove(parent, queryOrExisting); }, text: (text2, pos, opts, queryOrExisting) => text(text2, parent, pos, opts, queryOrExisting), textPath: (pathReference, text2, opts, textQueryOrExisting, pathQueryOrExisting) => textPath(pathReference, text2, parent, opts, textQueryOrExisting, pathQueryOrExisting), line: (line2, opts, queryOrExisting) => line(line2, parent, opts, queryOrExisting), circle: (circle2, opts, queryOrExisting) => circle(circle2, parent, opts, queryOrExisting), path: (svgString, opts, queryOrExisting) => path(svgString, parent, opts, queryOrExisting), grid: (center, spacing, width, height, opts) => grid(parent, center, spacing, width, height, opts), query: (selectors) => parent.querySelector(selectors), get width() { const w = parent.getAttributeNS(null, `width`); if (w === null) return 0; return Number.parseFloat(w); }, set width(width) { parent.setAttributeNS(null, `width`, width.toString()); }, get parent() { return parent; }, get height() { const w = parent.getAttributeNS(null, `height`); if (w === null) return 0; return Number.parseFloat(w); }, set height(height) { parent.setAttributeNS(null, `height`, height.toString()); }, clear: () => { while (parent.firstChild) { parent.lastChild.remove(); } } }; return o; }; export { applyOpts, getBounds, setBounds, createEl, createOrResolve, applyStrokeOpts, createMarker, markerPrebuilt, applyPathOpts, Elements_exports, lineFromSvgLine, polarRayFromSvgLine, remove, clear, makeHelper, svg_exports }; //# sourceMappingURL=chunk-5CYQHQM5.js.map