itk-viewer-transfer-function-editor
Advanced tools
Comparing version 1.4.0 to 1.5.0
@@ -5,2 +5,5 @@ import { Point } from './Point'; | ||
import { ColorTransferFunction } from './PiecewiseUtils'; | ||
declare class ColorControlPoint extends ControlPoint { | ||
getSvgPosition(): number[]; | ||
} | ||
export declare const ColorRange: () => { | ||
@@ -14,5 +17,6 @@ getPoints: () => Point[]; | ||
export declare const ColorRangeController: (container: ContainerType, colorRange: ColorRangeType, toDataSpace: (x: number) => number) => { | ||
points: ControlPoint[]; | ||
points: ColorControlPoint[]; | ||
setColorTransferFunction: (colorTransferFunction: ColorTransferFunction) => void; | ||
}; | ||
export type ColorRangeControllerType = ReturnType<typeof ColorRangeController>; | ||
export {}; |
@@ -1,2 +0,2 @@ | ||
export declare const PADDING = 10; | ||
export declare const PADDING = 11; | ||
export declare const Container: (parent: HTMLElement) => { | ||
@@ -3,0 +3,0 @@ appendChild: (shape: SVGGraphicsElement) => void; |
@@ -5,2 +5,4 @@ import { ContainerType } from './Container'; | ||
export declare const CONTROL_POINT_CLASS = "controlPoint"; | ||
export declare const clamp0to1: (x: number) => number; | ||
export declare const FULL_RADIUS = 14; | ||
export declare class ControlPoint { | ||
@@ -10,5 +12,5 @@ element: SVGGraphicsElement; | ||
tooltip: ReturnType<typeof addTooltip>; | ||
private container; | ||
private isDragging; | ||
private isHovered; | ||
protected container: ContainerType; | ||
protected isDragging: boolean; | ||
protected isHovered: boolean; | ||
readonly point: Point; | ||
@@ -20,7 +22,9 @@ deletable: boolean; | ||
private grabY; | ||
private toDataSpace; | ||
protected toDataSpace: (x: number) => number; | ||
static styleElement: HTMLStyleElement | undefined; | ||
constructor(container: ContainerType, point: Point, toDataSpace: (x: number) => number, deleteEventCallback?: (event: CustomEvent) => void, isNewPointFromPointer?: boolean); | ||
remove(): void; | ||
private positionElement; | ||
getSvgPosition(): number[]; | ||
updateTooltip(xySvg?: [number, number] | undefined): void; | ||
positionElement(): void; | ||
movePoint(e: PointerEvent): void; | ||
@@ -27,0 +31,0 @@ update(): void; |
@@ -22,2 +22,3 @@ import { ColorTransferFunction } from './PiecewiseUtils'; | ||
setHistogram(histogram: number[]): void; | ||
setRange(range: [number, number]): void; | ||
} |
@@ -1,5 +0,4 @@ | ||
var Z = Object.defineProperty; | ||
var q = (n, t, e) => t in n ? Z(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e; | ||
var a = (n, t, e) => (q(n, typeof t != "symbol" ? t + "" : t, e), e); | ||
const B = (n) => Math.max(0, Math.min(1, n)); | ||
var J = Object.defineProperty; | ||
var Q = (n, t, e) => t in n ? J(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e; | ||
var a = (n, t, e) => (Q(n, typeof t != "symbol" ? t + "" : t, e), e); | ||
class N { | ||
@@ -10,3 +9,3 @@ constructor(t, e) { | ||
a(this, "eventTarget", new EventTarget()); | ||
this.x = t, this.y = e; | ||
this.setPosition(t, e); | ||
} | ||
@@ -17,3 +16,3 @@ get x() { | ||
set x(t) { | ||
this._x = B(t), this.dispatchUpdatedEvent(); | ||
this._x = t, this.dispatchUpdatedEvent(); | ||
} | ||
@@ -24,6 +23,6 @@ get y() { | ||
set y(t) { | ||
this._y = B(t), this.dispatchUpdatedEvent(); | ||
this._y = t, this.dispatchUpdatedEvent(); | ||
} | ||
setPosition(t, e) { | ||
this.x = t, this.y = e, this.dispatchUpdatedEvent(); | ||
this._x = t, this._y = e, this.dispatchUpdatedEvent(); | ||
} | ||
@@ -36,3 +35,3 @@ dispatchUpdatedEvent() { | ||
} | ||
const X = (n, t = !1) => { | ||
const W = (n, t = !1) => { | ||
if (n.length === 0) | ||
@@ -52,4 +51,4 @@ return [ | ||
return t ? [[e[0], 0], ...n, [o[0], 0]] : [[0, e[1]], ...n, [1, o[1]]]; | ||
}, $ = (n) => X(n.map(({ x: t, y: e }) => [t, e])); | ||
class J { | ||
}, j = (n) => W(n.map(({ x: t, y: e }) => [t, e])); | ||
class tt { | ||
constructor() { | ||
@@ -85,4 +84,4 @@ a(this, "_points", []); | ||
return o.eventTarget.addEventListener("updated", () => { | ||
this._points.sort((i, r) => i.x - r.x), this.dispatchUpdatedEvent(); | ||
}), this._points.push(o), this._points.sort((i, r) => i.x - r.x), o; | ||
this._points.sort((i, s) => i.x - s.x), this.dispatchUpdatedEvent(); | ||
}), this._points.push(o), this._points.sort((i, s) => i.x - s.x), o; | ||
} | ||
@@ -93,3 +92,3 @@ deletePoint(t) { | ||
} | ||
const Q = (n, t, e, o = { | ||
const et = (n, t, e, o = { | ||
lineWidth: 1, | ||
@@ -100,8 +99,8 @@ strokeStyle: "#000", | ||
}) => { | ||
const i = t[3], r = t[2] / (e.length - 1), l = i + t[1]; | ||
const i = t[3], s = t[2] / (e.length - 1), d = i + t[1]; | ||
n.lineWidth = o.lineWidth, n.strokeStyle = o.strokeStyle, n.beginPath(), n.moveTo(t[0], t[1] + t[3]); | ||
for (let s = 0; s < e.length; s++) | ||
for (let r = 0; r < e.length; r++) | ||
n.lineTo( | ||
t[0] + s * r, | ||
Math.max(t[1], l - e[s] * i) | ||
t[0] + r * s, | ||
Math.max(t[1], d - e[r] * i) | ||
); | ||
@@ -116,7 +115,7 @@ if (o.fillStyle) { | ||
n.stroke(); | ||
}, D = 1, tt = (n, t, e, o) => { | ||
}, _ = 1, nt = (n, t, e, o) => { | ||
const i = o || document.createElement("canvas"); | ||
if (i.setAttribute("width", String(t)), i.setAttribute("height", String(D)), n.getSize() === 0) | ||
if (i.setAttribute("width", String(t)), i.setAttribute("height", String(_)), n.getSize() === 0) | ||
return i; | ||
const r = n.getUint8Table( | ||
const s = n.getUint8Table( | ||
e[0], | ||
@@ -126,23 +125,23 @@ e[1], | ||
!0 | ||
), l = i.getContext("2d"); | ||
if (l) { | ||
const s = l.getImageData(0, 0, t, D); | ||
for (let d = 0; d < D; d++) | ||
s.data.set(r, d * 4 * t); | ||
const c = D * t * 4; | ||
for (let d = 3; d < c; d += 4) | ||
s.data[d] = 255; | ||
l.putImageData(s, 0, 0); | ||
), d = i.getContext("2d"); | ||
if (d) { | ||
const r = d.getImageData(0, 0, t, _); | ||
for (let l = 0; l < _; l++) | ||
r.data.set(s, l * 4 * t); | ||
const p = _ * t * 4; | ||
for (let l = 3; l < p; l += 4) | ||
r.data[l] = 255; | ||
d.putImageData(r, 0, 0); | ||
} | ||
return i; | ||
}, bt = (n) => { | ||
const t = X(n); | ||
}, Pt = (n) => { | ||
const t = W(n); | ||
return t[0][0] -= 1e-8, t[t.length - 1][0] += 1e-8, t; | ||
}, et = (n) => { | ||
}, ot = (n) => { | ||
if (!n) | ||
return []; | ||
const t = n.map((s) => s === 0 ? 0 : Math.log(s)), e = t.filter(Boolean), o = Math.min(...e), r = Math.max(...e) - o; | ||
return t.map((s) => s === 0 ? 0 : (s - o) / r); | ||
const t = n.map((r) => r === 0 ? 0 : Math.log(r)), e = t.filter(Boolean), o = Math.min(...e), s = Math.max(...e) - o; | ||
return t.map((r) => r === 0 ? 0 : (r - o) / s); | ||
}; | ||
function nt(n, t) { | ||
function it(n, t) { | ||
if (n.length !== t.length) | ||
@@ -155,6 +154,6 @@ return !1; | ||
} | ||
function F(n) { | ||
function I(n) { | ||
return `#${n.map((e) => Math.floor(e * 255)).map((e) => `0${e.toString(16)}`.slice(-2)).join("")}`; | ||
} | ||
const R = 10, ot = () => { | ||
const A = 11, st = 2 * A, rt = () => { | ||
const n = document.createElementNS("http://www.w3.org/2000/svg", "svg"); | ||
@@ -165,3 +164,3 @@ return n.setAttribute( | ||
), n; | ||
}, it = (n) => { | ||
}, at = (n) => { | ||
const t = document.createElement("div"); | ||
@@ -172,6 +171,6 @@ t.setAttribute( | ||
), n.appendChild(t); | ||
const e = ot(); | ||
const e = rt(); | ||
t.appendChild(e); | ||
const o = new EventTarget(), i = (h) => { | ||
o.addEventListener("sizeupdated", h); | ||
const o = new EventTarget(), i = (g) => { | ||
o.addEventListener("sizeupdated", g); | ||
}; | ||
@@ -181,49 +180,49 @@ new ResizeObserver(() => { | ||
}).observe(t); | ||
const l = document.createElementNS( | ||
const d = document.createElementNS( | ||
"http://www.w3.org/2000/svg", | ||
"rect" | ||
); | ||
e.appendChild(l), l.setAttribute("fill", "none"), l.setAttribute("stroke", "black"); | ||
const s = (h) => { | ||
e.appendChild(h); | ||
}, c = (h) => { | ||
e.removeChild(h); | ||
e.appendChild(d), d.setAttribute("fill", "none"), d.setAttribute("stroke", "black"); | ||
const r = (g) => { | ||
e.appendChild(g); | ||
}, p = (g) => { | ||
e.removeChild(g); | ||
}; | ||
let d = [0, 1, 0, 1]; | ||
const E = () => d, p = (h, m, v = 0, g = 1) => { | ||
const b = d; | ||
d = [h, m, v, g], nt(b, d) || o.dispatchEvent(new Event("sizeupdated")); | ||
}, f = () => { | ||
const { top: h, left: m, width: v, height: g } = t.getBoundingClientRect(); | ||
let l = [0, 1, 0, 1]; | ||
const E = () => l, u = (g, w, f = 0, b = 1) => { | ||
const T = l; | ||
l = [g, w, f, b], it(T, l) || o.dispatchEvent(new Event("sizeupdated")); | ||
}, S = () => { | ||
const { top: g, left: w, width: f, height: b } = t.getBoundingClientRect(); | ||
return { | ||
width: v - 2 * R, | ||
height: g - 2 * R, | ||
top: h + R, | ||
left: m + R | ||
width: f - 2 * A, | ||
height: b - (st + A), | ||
top: g + A, | ||
left: w + A | ||
}; | ||
}, S = (h, m) => { | ||
const { top: v, left: g, width: b, height: x } = f(), w = d[1] - d[0] || 1e-3, A = d[3] - d[2] || 1e-3; | ||
}, c = (g, w) => { | ||
const { top: f, left: b, width: T, height: x } = S(), C = l[1] - l[0] || 1e-3, R = l[3] - l[2] || 1e-3; | ||
return [ | ||
(h - g) / b * w + d[0], | ||
(1 - (m - v) / x) * A + d[2] | ||
(g - b) / T * C + l[0], | ||
(1 - (w - f) / x) * R + l[2] | ||
]; | ||
}, u = (h, m) => { | ||
const { width: v, height: g } = f(), b = d[1] - d[0] || 1e-3, x = (h - d[0]) / b * v + R, w = d[3] - d[2] || 1e-3, A = (1 - (m - d[2]) / w) * g + R; | ||
return [x, A]; | ||
}, C = () => { | ||
const [h, m] = u(0, 0), [v, g] = u(1, 1); | ||
return { left: h, bottom: m, right: v, top: g }; | ||
}, h = (g, w) => { | ||
const { width: f, height: b } = S(), T = l[1] - l[0] || 1e-3, x = (g - l[0]) / T * f + A, C = l[3] - l[2] || 1e-3, R = (1 - (w - l[2]) / C) * b + A; | ||
return [x, R]; | ||
}, v = () => { | ||
const [g, w] = h(0, 0), [f, b] = h(1, 1); | ||
return { left: g, bottom: w, right: f, top: b }; | ||
}; | ||
return i(() => { | ||
const { left: h, bottom: m, right: v, top: g } = C(); | ||
l.setAttribute("x", `${h}`), l.setAttribute("y", `${g}`), l.setAttribute("width", `${Math.max(0, v - h)}`), l.setAttribute("height", `${Math.max(0, m - g)}`); | ||
const { left: g, bottom: w, right: f, top: b } = v(); | ||
d.setAttribute("x", `${g}`), d.setAttribute("y", `${b}`), d.setAttribute("width", `${Math.max(0, f - g)}`), d.setAttribute("height", `${Math.max(0, w - b)}`); | ||
}), { | ||
appendChild: s, | ||
removeChild: c, | ||
appendChild: r, | ||
removeChild: p, | ||
addSizeObserver: i, | ||
getViewBox: E, | ||
setViewBox: p, | ||
domToNormalized: S, | ||
normalizedToSvg: u, | ||
borderSize: C, | ||
setViewBox: u, | ||
domToNormalized: c, | ||
normalizedToSvg: h, | ||
borderSize: v, | ||
remove: () => n.removeChild(t), | ||
@@ -234,7 +233,7 @@ root: t, | ||
}; | ||
let O = !1; | ||
const st = () => { | ||
if (O) | ||
let V = !1; | ||
const dt = () => { | ||
if (V) | ||
return; | ||
O = !0; | ||
V = !0; | ||
const n = document.createElement("style"); | ||
@@ -255,7 +254,8 @@ n.innerHTML = ` | ||
max-width: 150px; | ||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); | ||
} | ||
`, document.head.appendChild(n); | ||
}; | ||
function rt(n) { | ||
st(); | ||
function lt(n) { | ||
dt(); | ||
const t = [10, 10], e = document.createElementNS( | ||
@@ -271,23 +271,23 @@ "http://www.w3.org/2000/svg", | ||
o.setAttribute("class", "tfeditor-svg-tooltip"), e.appendChild(o), n.append(e); | ||
function i(c, d, E) { | ||
let p = d + t[0], f = E + t[1]; | ||
o.innerHTML = c; | ||
const S = n.getBBox(), u = o.getBoundingClientRect(); | ||
p > S.width - u.width && (p = d - u.width - t[0]), f > S.height - u.height && (f = E - u.height - t[1]), o.style.transform = `translate(${p}px,${f}px)`; | ||
function i(p, l, E) { | ||
let u = l + t[0], S = E + t[1]; | ||
o.textContent = p; | ||
const c = n.getBBox(), h = o.getBoundingClientRect(); | ||
u > c.width - h.width && (u = l - h.width - t[0]), S > c.height - h.height && (S = E - h.height - t[1]), o.style.transform = `translate(${u}px,${S}px)`; | ||
} | ||
function r() { | ||
function s() { | ||
o.style.visibility = "visible"; | ||
} | ||
function l() { | ||
function d() { | ||
o.style.visibility = "hidden"; | ||
} | ||
return { update: i, show: r, hide: l, remove: () => { | ||
return { update: i, show: s, hide: d, remove: () => { | ||
n.removeChild(e); | ||
} }; | ||
} | ||
const at = "controlPoint", M = 2, dt = 8, W = 14, T = W, lt = () => { | ||
const ct = "controlPoint", U = (n) => Math.max(0, Math.min(1, n)), z = 2, ht = 8, G = 14, P = G, pt = () => { | ||
const n = document.createElementNS("http://www.w3.org/2000/svg", "svg"); | ||
n.setAttribute("width", String(T * 2)), n.setAttribute("height", String(T * 2)), n.setAttribute( | ||
n.setAttribute("width", String(P * 2)), n.setAttribute("height", String(P * 2)), n.setAttribute( | ||
"viewBox", | ||
`-${T} -${T} ${T * 2} ${T * 2}` | ||
`-${P} -${P} ${P * 2} ${P * 2}` | ||
); | ||
@@ -298,3 +298,3 @@ const t = document.createElementNS( | ||
); | ||
t.setAttribute("r", String(dt)), t.setAttribute("fill", "white"), t.setAttribute("stroke", "black"), t.setAttribute("stroke-width", String(M)), t.setAttribute("class", at), n.appendChild(t); | ||
t.setAttribute("r", String(ht)), t.setAttribute("fill", "white"), t.setAttribute("stroke", "black"), t.setAttribute("stroke-width", String(z)), t.setAttribute("class", ct), n.appendChild(t); | ||
const e = document.createElementNS( | ||
@@ -304,6 +304,6 @@ "http://www.w3.org/2000/svg", | ||
); | ||
return e.setAttribute("r", String(W)), e.setAttribute("fill", "transparent"), e.setAttribute("stroke", "transparent"), e.setAttribute("style", "cursor: move;"), n.appendChild(e), { group: n, circle: t, clickTarget: e }; | ||
return e.setAttribute("r", String(G)), e.setAttribute("fill", "transparent"), e.setAttribute("stroke", "transparent"), e.setAttribute("style", "cursor: move;"), n.appendChild(e), { group: n, circle: t, clickTarget: e }; | ||
}; | ||
class _ { | ||
constructor(t, e, o, i, r = !1) { | ||
class O { | ||
constructor(t, e, o, i, s = !1) { | ||
a(this, "element"); | ||
@@ -322,11 +322,11 @@ a(this, "circle"); | ||
a(this, "toDataSpace"); | ||
const { group: l, circle: s } = lt(); | ||
this.element = l, this.circle = s, this.point = e, this.container = t, this.toDataSpace = o, this.tooltip = rt(this.container.svg), t.addSizeObserver(() => { | ||
const { group: d, circle: r } = pt(); | ||
this.element = d, this.circle = r, this.point = e, this.container = t, this.toDataSpace = o, this.tooltip = lt(this.container.svg), t.addSizeObserver(() => { | ||
this.positionElement(); | ||
}), i && this.eventTarget.addEventListener(this.DELETE_EVENT, (c) => { | ||
i(c); | ||
}), i && this.eventTarget.addEventListener(this.DELETE_EVENT, (p) => { | ||
i(p); | ||
}), t.appendChild(this.element), this.positionElement(), this.point.eventTarget.addEventListener( | ||
"updated", | ||
() => this.positionElement() | ||
), this.setupInteraction(), r && this.startInteraction(!0); | ||
), this.setupInteraction(), s && this.startInteraction(!0); | ||
} | ||
@@ -336,14 +336,20 @@ remove() { | ||
} | ||
getSvgPosition() { | ||
const { x: t, y: e } = this.point; | ||
return this.container.normalizedToSvg(t, e); | ||
} | ||
updateTooltip(t = void 0) { | ||
const { x: e } = this.point, o = this.toDataSpace(e), [i, s] = t ?? this.getSvgPosition(); | ||
this.tooltip.update(o.toPrecision(4), i, s); | ||
} | ||
positionElement() { | ||
const { x: t, y: e } = this.point, [o, i] = this.container.normalizedToSvg(t, e); | ||
this.element.setAttribute("x", String(o - T)), this.element.setAttribute("y", String(i - T)); | ||
const r = this.toDataSpace(t); | ||
this.tooltip.update(String(r), o, i); | ||
const [t, e] = this.getSvgPosition(); | ||
this.element.setAttribute("x", String(t - P)), this.element.setAttribute("y", String(e - P)), this.updateTooltip([t, e]); | ||
} | ||
movePoint(t) { | ||
const [e, o] = this.container.domToNormalized(t.clientX, t.clientY); | ||
this.point.setPosition(e + this.grabX, o + this.grabY), this.positionElement(); | ||
this.point.setPosition(U(e + this.grabX), U(o + this.grabY)); | ||
} | ||
update() { | ||
this.circle.setAttribute("stroke-width", String(M)), this.isHovered ? (this.circle.setAttribute("stroke-width", String(M + 1)), this.tooltip.show()) : this.tooltip.hide(), this.isDragging && this.circle.setAttribute("stroke-width", String(M * 2)); | ||
this.circle.setAttribute("stroke-width", String(z)), this.isHovered && (this.circle.setAttribute("stroke-width", String(z + 1)), this.updateTooltip(), this.tooltip.show()), this.isDragging && this.circle.setAttribute("stroke-width", String(z * 2)), !this.isDragging && !this.isHovered && this.tooltip.hide(); | ||
} | ||
@@ -353,3 +359,3 @@ startInteraction(t = !1) { | ||
const e = (i) => { | ||
this.isDragging = !0, this.circle.setAttribute("stroke", "black"), this.movePoint(i); | ||
this.isDragging || this.circle.setAttribute("stroke", "black"), this.isDragging = !0, this.movePoint(i); | ||
}; | ||
@@ -368,3 +374,3 @@ document.addEventListener("pointermove", e); | ||
this.element.addEventListener("pointerdown", (t) => { | ||
t.stopPropagation(), this.circle.setAttribute("stroke-width", String(M * 2)); | ||
t.stopPropagation(), this.circle.setAttribute("stroke-width", String(z * 2)); | ||
const [e, o] = this.container.domToNormalized( | ||
@@ -385,4 +391,4 @@ t.clientX, | ||
} | ||
a(_, "styleElement"); | ||
class ct { | ||
a(O, "styleElement"); | ||
class gt { | ||
constructor(t, e, o) { | ||
@@ -397,3 +403,3 @@ a(this, "container"); | ||
const { root: i } = t; | ||
i.addEventListener("pointerdown", (r) => this.onPointerDown(r)), this.onPointsUpdated = () => this.updatePoints(), this.points.eventTarget.addEventListener("updated", this.onPointsUpdated), this.updatePoints(); | ||
i.addEventListener("pointerdown", (s) => this.onPointerDown(s)), this.onPointsUpdated = () => this.updatePoints(), this.points.eventTarget.addEventListener("updated", this.onPointsUpdated), this.updatePoints(); | ||
} | ||
@@ -404,3 +410,3 @@ remove() { | ||
onPointerDown(t) { | ||
const [e, o] = this.container.domToNormalized(t.clientX, t.clientY); | ||
const [e, o] = this.container.domToNormalized(t.clientX, t.clientY).map(U); | ||
this.isNewPointFromPointer = !0, this.points.addPoint(e, o), this.isNewPointFromPointer = !1; | ||
@@ -413,3 +419,3 @@ } | ||
const t = this.controlPoints.filter( | ||
(i) => !this.points.points.find((r) => r === i.point) | ||
(i) => !this.points.points.find((s) => s === i.point) | ||
); | ||
@@ -419,8 +425,8 @@ t.forEach((i) => i.remove()), this.controlPoints = this.controlPoints.filter( | ||
); | ||
const e = (i) => this.controlPoints.find((r) => r.point === i), o = (i) => this.controlPoints.push( | ||
new _( | ||
const e = (i) => this.controlPoints.find((s) => s.point === i), o = (i) => this.controlPoints.push( | ||
new O( | ||
this.container, | ||
i, | ||
this.toDataSpace, | ||
(r) => this.onControlPointDelete(r), | ||
(s) => this.onControlPointDelete(s), | ||
this.isNewPointFromPointer | ||
@@ -432,3 +438,3 @@ ) | ||
} | ||
const ht = () => { | ||
const ut = () => { | ||
const n = document.createElementNS( | ||
@@ -440,3 +446,3 @@ "http://www.w3.org/2000/svg", | ||
}; | ||
class pt { | ||
class mt { | ||
constructor(t, e) { | ||
@@ -447,3 +453,3 @@ a(this, "points"); | ||
a(this, "element"); | ||
this.container = t, this.points = e, this.element = ht(), this.container.appendChild(this.element), this.onPointsUpdated = () => this.update(), this.points.eventTarget.addEventListener("updated", this.onPointsUpdated), this.container.addSizeObserver(() => { | ||
this.container = t, this.points = e, this.element = ut(), this.container.appendChild(this.element), this.onPointsUpdated = () => this.update(), this.points.eventTarget.addEventListener("updated", this.onPointsUpdated), this.container.addSizeObserver(() => { | ||
this.update(); | ||
@@ -460,58 +466,58 @@ }), this.update(); | ||
} | ||
const t = $(this.points.points).map(([e, o]) => this.container.normalizedToSvg(e, o)).map(([e, o]) => `${e},${o}`).join(" "); | ||
const t = j(this.points.points).map(([e, o]) => this.container.normalizedToSvg(e, o)).map(([e, o]) => `${e},${o}`).join(" "); | ||
this.element.setAttribute("points", t); | ||
} | ||
} | ||
const V = 1.1, gt = (n) => { | ||
const H = 1.1, vt = (n) => { | ||
n.root.addEventListener("wheel", (t) => { | ||
const e = t.deltaY > 0 ? V : 1 / V, [o] = n.domToNormalized(t.clientX, t.clientY), [i, r] = n.getViewBox(), l = Math.max( | ||
const e = t.deltaY > 0 ? H : 1 / H, [o] = n.domToNormalized(t.clientX, t.clientY), [i, s] = n.getViewBox(), d = Math.max( | ||
0, | ||
i - Math.max(0, o - i) * (e - 1) | ||
), s = Math.min(1, (r - i) * e + l); | ||
l === i && s === r || (t.preventDefault(), t.stopPropagation(), n.setViewBox(l, s)); | ||
), r = Math.min(1, (s - i) * e + d); | ||
d === i && r === s || (t.preventDefault(), t.stopPropagation(), n.setViewBox(d, r)); | ||
}); | ||
}, H = "rgba(50, 50, 50, 0.3)", ut = (n, t, e) => { | ||
}, X = "rgba(50, 50, 50, 0.3)", wt = (n, t, e) => { | ||
const o = document.createElement("canvas"); | ||
n.root.appendChild(o), o.setAttribute("style", "width: 100%; height: 100%; "); | ||
const i = o.getContext("2d"); | ||
let r, l; | ||
const s = document.createElement("canvas"), c = () => { | ||
let s, d; | ||
const r = document.createElement("canvas"), p = () => { | ||
if (i) { | ||
if (i.clearRect(0, 0, o.width, o.height), r) { | ||
const { width: p, height: f } = n.root.getBoundingClientRect(); | ||
o.setAttribute("width", String(p)), o.setAttribute("height", String(f)); | ||
const { left: S, right: u, bottom: C, top: P } = n.borderSize(); | ||
if (Math.ceil(u - S) < 0) | ||
if (i.clearRect(0, 0, o.width, o.height), s) { | ||
const { width: u, height: S } = n.root.getBoundingClientRect(); | ||
o.setAttribute("width", String(u)), o.setAttribute("height", String(S)); | ||
const { left: c, right: h, bottom: v, top: m } = n.borderSize(); | ||
if (Math.ceil(h - c) < 0) | ||
return; | ||
const h = $(t.points), m = [[0, 0], ...h, [1, 0]].map( | ||
([y, L]) => n.normalizedToSvg(y, L) | ||
const g = j(t.points), w = [[0, 0], ...g, [1, 0]].map( | ||
([L, k]) => n.normalizedToSvg(L, k) | ||
); | ||
i.save(), i.beginPath(), m.forEach(([y, L]) => { | ||
i.lineTo(y, L); | ||
i.save(), i.beginPath(), w.forEach(([L, k]) => { | ||
i.lineTo(L, k); | ||
}), i.clip(); | ||
const [v, g] = e.getColorRange(), [b] = n.normalizedToSvg(v, 1), [x] = n.normalizedToSvg(g, 1), w = Math.min(p, Math.max(0, b)), A = Math.min(p, Math.max(0, x)), k = A - w < 2 ? w + 2 : A, I = Math.ceil(k - w); | ||
if (r) { | ||
const y = x - b, L = (w - b) / y, j = (k - x) / y, z = r.getMappingRange(), U = z[1] - z[0], G = [ | ||
z[0] + U * L, | ||
z[1] + U * j | ||
const [f, b] = e.getColorRange(), [T] = n.normalizedToSvg(f, 1), [x] = n.normalizedToSvg(b, 1), C = Math.min(u, Math.max(0, T)), R = Math.min(u, Math.max(0, x)), D = R - C < 2 ? C + 2 : R, $ = Math.ceil(D - C); | ||
if (s) { | ||
const L = x - T, k = (C - T) / L, K = (D - x) / L, M = s.getMappingRange(), F = M[1] - M[0], Z = [ | ||
M[0] + F * k, | ||
M[1] + F * K | ||
]; | ||
tt( | ||
nt( | ||
s, | ||
$, | ||
Z, | ||
r | ||
), i.drawImage( | ||
r, | ||
I, | ||
G, | ||
s | ||
), i.drawImage( | ||
s, | ||
0, | ||
0, | ||
s.width, | ||
s.height, | ||
Math.floor(w), | ||
Math.floor(P), | ||
I, | ||
Math.ceil(C - P) | ||
r.width, | ||
r.height, | ||
Math.floor(C), | ||
Math.floor(m), | ||
$, | ||
Math.ceil(v - m) | ||
); | ||
const K = i.imageSmoothingEnabled; | ||
const q = i.imageSmoothingEnabled; | ||
i.imageSmoothingEnabled = !1, i.drawImage( | ||
s, | ||
r, | ||
0, | ||
@@ -522,25 +528,25 @@ 0, | ||
0, | ||
Math.floor(P), | ||
Math.floor(w), | ||
Math.ceil(C - P) | ||
Math.floor(m), | ||
Math.floor(C), | ||
Math.ceil(v - m) | ||
), i.drawImage( | ||
s, | ||
s.width - 1, | ||
r, | ||
r.width - 1, | ||
0, | ||
1, | ||
1, | ||
Math.floor(k), | ||
Math.floor(P), | ||
p - k, | ||
Math.ceil(C - P) | ||
), i.imageSmoothingEnabled = K; | ||
Math.floor(D), | ||
Math.floor(m), | ||
u - D, | ||
Math.ceil(v - m) | ||
), i.imageSmoothingEnabled = q; | ||
} | ||
i.restore(); | ||
} | ||
if (l) { | ||
const { left: p, right: f, bottom: S, top: u } = n.borderSize(), C = [p, u, f - p, S - u]; | ||
Q(i, C, l, { | ||
if (d) { | ||
const { left: u, right: S, bottom: c, top: h } = n.borderSize(), v = [u, h, S - u, c - h]; | ||
et(i, v, d, { | ||
lineWidth: 1, | ||
strokeStyle: H, | ||
fillStyle: H | ||
strokeStyle: X, | ||
fillStyle: X | ||
}); | ||
@@ -550,73 +556,111 @@ } | ||
}; | ||
return n.addSizeObserver(c), t.eventTarget.addEventListener("updated", c), e.eventTarget.addEventListener("updated", c), { | ||
return n.addSizeObserver(p), t.eventTarget.addEventListener("updated", p), e.eventTarget.addEventListener("updated", p), { | ||
container: n, | ||
canvas: o, | ||
setColorTransferFunction: (p) => { | ||
r = p, c(); | ||
setColorTransferFunction: (u) => { | ||
s = u, p(); | ||
}, | ||
setHistogram: (p) => { | ||
l = p, c(); | ||
setHistogram: (u) => { | ||
d = u, p(); | ||
}, | ||
render: c, | ||
render: p, | ||
remove: () => n.root.removeChild(o) | ||
}; | ||
}, mt = () => { | ||
const n = [new N(0, 0), new N(1, 0)], t = () => n.sort((s, c) => s.x - c.x), e = () => t().map((s) => s.x), o = new EventTarget(), i = () => o.dispatchEvent( | ||
}, B = -2.75; | ||
class Y extends O { | ||
getSvgPosition() { | ||
const { x: t } = this.point, [e, o] = this.container.normalizedToSvg(t, 0), i = o + B + P; | ||
return [e, i]; | ||
} | ||
} | ||
const ft = () => { | ||
const n = [new N(0, 0), new N(1, 0)], t = () => n.sort((r, p) => r.x - p.x), e = () => t().map((r) => r.x), o = new EventTarget(), i = () => o.dispatchEvent( | ||
new CustomEvent("updated", { detail: e() }) | ||
); | ||
let r = !1; | ||
const l = (s) => { | ||
s.eventTarget.addEventListener("updated", () => { | ||
s.y !== 0 && (s.y = 0), r || i(); | ||
let s = !1; | ||
const d = (r) => { | ||
r.eventTarget.addEventListener("updated", () => { | ||
s || i(); | ||
}); | ||
}; | ||
return n.forEach(l), { | ||
return n.forEach(d), { | ||
getPoints: t, | ||
getColorRange: e, | ||
setColorRange: (s) => { | ||
r = !0, t().forEach((c, d) => { | ||
c.x = s[d]; | ||
}), r = !1, i(); | ||
setColorRange: (r) => { | ||
s = !0, t().forEach((p, l) => { | ||
p.x = r[l]; | ||
}), s = !1, i(); | ||
}, | ||
eventTarget: o | ||
}; | ||
}, vt = (n, t, e) => { | ||
const o = t.getPoints().map((s) => { | ||
const c = new _(n, s, e); | ||
return c.deletable = !1, c; | ||
}, bt = () => { | ||
const n = document.createElementNS( | ||
"http://www.w3.org/2000/svg", | ||
"polyline" | ||
); | ||
return n.setAttribute("fill", "none"), n.setAttribute("stroke", "black"), n.setAttribute("stroke-width", "1"), n; | ||
}, Et = (n, t, e) => { | ||
const o = bt(); | ||
n.appendChild(o); | ||
const i = new N(0.5, B), s = new Y( | ||
n, | ||
i, | ||
e | ||
); | ||
s.deletable = !1; | ||
const d = t.getPoints().map((c) => { | ||
const h = new Y(n, c, e); | ||
return h.deletable = !1, h; | ||
}), r = () => { | ||
const [, c] = n.normalizedToSvg(0, 0), h = c + B + P, v = d.map((m) => [m.point.x, m.point.y]).map(([m, y]) => n.normalizedToSvg(m, y)).map(([m]) => `${m},${h}`).join(" "); | ||
o.setAttribute("points", v); | ||
}; | ||
n.addSizeObserver(() => { | ||
r(); | ||
}); | ||
let i; | ||
const r = () => { | ||
if (!i) | ||
let p = !1, l = !1; | ||
i.eventTarget.addEventListener("updated", () => { | ||
if (l) | ||
return; | ||
const s = i.getMappingRange(), c = []; | ||
i.getColor(s[0], c); | ||
const d = []; | ||
i.getColor(s[1], d); | ||
const E = o.sort((p, f) => p.point.x - f.point.x); | ||
E[0].setColor(F(c)), E[1].setColor(F(d)); | ||
}, l = (s) => { | ||
i = s, r(); | ||
const c = d[1].point.x - d[0].point.x; | ||
p = !0, d[0].point.x = i.x - c / 2, d[1].point.x = i.x + c / 2, p = !1, r(); | ||
}); | ||
let E; | ||
const u = () => { | ||
if (!E) | ||
return; | ||
const c = E.getMappingRange(), h = []; | ||
E.getColor(c[0], h); | ||
const v = []; | ||
E.getColor(c[1], v); | ||
const m = d.sort((w, f) => w.point.x - f.point.x); | ||
m[0].setColor(I(h)), m[1].setColor(I(v)); | ||
const y = [], g = (c[1] - c[0]) / 2 + c[0]; | ||
E.getColor(g, y), s.setColor(I(y)); | ||
}, S = (c) => { | ||
E = c, u(); | ||
}; | ||
return t.eventTarget.addEventListener("updated", () => { | ||
r(); | ||
if (p) | ||
return; | ||
u(); | ||
const c = t.getPoints().length; | ||
l = !0, i.x = t.getPoints().reduce((h, v) => h + v.x, 0) / c, r(), l = !1; | ||
}), { | ||
points: o, | ||
setColorTransferFunction: l | ||
points: d, | ||
setColorTransferFunction: S | ||
}; | ||
}, ft = () => { | ||
let n; | ||
}, St = () => { | ||
let n = [0, 1]; | ||
return { | ||
setColorTransferFunction: (o) => { | ||
setRange: (o) => { | ||
n = o; | ||
}, | ||
toDataSpace: (o) => { | ||
if (!n) | ||
return o; | ||
const [i, r] = n.getMappingRange(), l = r - i; | ||
return o * l + i; | ||
const [i, s] = n, d = s - i; | ||
return o * d + i; | ||
} | ||
}; | ||
}; | ||
class Et { | ||
class Tt { | ||
constructor(t) { | ||
@@ -631,4 +675,4 @@ a(this, "eventTarget", new EventTarget()); | ||
a(this, "background"); | ||
a(this, "dataSpaceConverter", ft()); | ||
this.container = it(t), gt(this.container), this.points = new J(); | ||
a(this, "dataSpaceConverter", St()); | ||
this.container = at(t), vt(this.container), this.points = new tt(); | ||
const e = [ | ||
@@ -638,11 +682,11 @@ [0, 0], | ||
]; | ||
this.points.setPoints(e), this.line = new pt(this.container, this.points), this.pointController = new ct( | ||
this.points.setPoints(e), this.line = new mt(this.container, this.points), this.pointController = new gt( | ||
this.container, | ||
this.points, | ||
this.dataSpaceConverter.toDataSpace | ||
), this.colorRange = mt(), this.colorRangeController = vt( | ||
), this.colorRange = ft(), this.colorRangeController = Et( | ||
this.container, | ||
this.colorRange, | ||
this.dataSpaceConverter.toDataSpace | ||
), this.background = ut(this.container, this.points, this.colorRange), this.points.eventTarget.addEventListener("updated", (o) => { | ||
), this.background = wt(this.container, this.points, this.colorRange), this.points.eventTarget.addEventListener("updated", (o) => { | ||
this.eventTarget.dispatchEvent( | ||
@@ -678,11 +722,15 @@ new CustomEvent("updated", { detail: o.detail }) | ||
setColorTransferFunction(t) { | ||
this.dataSpaceConverter.setColorTransferFunction(t), this.background.setColorTransferFunction(t), this.colorRangeController.setColorTransferFunction(t); | ||
this.background.setColorTransferFunction(t), this.colorRangeController.setColorTransferFunction(t); | ||
} | ||
setHistogram(t) { | ||
this.background.setHistogram(et(t)); | ||
this.background.setHistogram(ot(t)); | ||
} | ||
setRange(t) { | ||
this.dataSpaceConverter.setRange(t); | ||
} | ||
} | ||
export { | ||
Et as TransferFunctionEditor, | ||
bt as windowPointsForSort | ||
Tt as TransferFunctionEditor, | ||
Pt as windowPointsForSort | ||
}; | ||
//# sourceMappingURL=TransferFunctionEditor.es.js.map |
@@ -1,2 +0,2 @@ | ||
(function(m,g){typeof exports=="object"&&typeof module<"u"?g(exports):typeof define=="function"&&define.amd?define(["exports"],g):(m=typeof globalThis<"u"?globalThis:m||self,g(m.TransferFunctionEditor={}))})(this,function(m){"use strict";var bt=Object.defineProperty;var Et=(m,g,S)=>g in m?bt(m,g,{enumerable:!0,configurable:!0,writable:!0,value:S}):m[g]=S;var a=(m,g,S)=>(Et(m,typeof g!="symbol"?g+"":g,S),S);const g=n=>Math.max(0,Math.min(1,n));class S{constructor(t,e){a(this,"_x");a(this,"_y");a(this,"eventTarget",new EventTarget);this.x=t,this.y=e}get x(){return this._x}set x(t){this._x=g(t),this.dispatchUpdatedEvent()}get y(){return this._y}set y(t){this._y=g(t),this.dispatchUpdatedEvent()}setPosition(t,e){this.x=t,this.y=e,this.dispatchUpdatedEvent()}dispatchUpdatedEvent(){this.eventTarget.dispatchEvent(new CustomEvent("updated",{detail:[this.x,this.y]}))}}const B=(n,t=!1)=>{if(n.length===0)return[[0,1],[1,1]];if(n.length===1){const[,i]=n[0];return[[0,i],[1,i]]}const e=n[0],o=n[n.length-1];return t?[[e[0],0],...n,[o[0],0]]:[[0,e[1]],...n,[1,o[1]]]},F=n=>B(n.map(({x:t,y:e})=>[t,e]));class j{constructor(){a(this,"_points",[]);a(this,"eventTarget",new EventTarget)}get points(){return[...this._points]}addPoint(t,e){const o=this.createPoint(t,e);return this.dispatchUpdatedEvent(),o}addPoints(t){return t.map(([o,i])=>this.createPoint(o,i))}setPoints(t){return[...this._points].forEach(e=>this.deletePoint(e)),this.addPoints(t)}removePoint(t){this.deletePoint(t),this.dispatchUpdatedEvent()}dispatchUpdatedEvent(){this.eventTarget.dispatchEvent(new CustomEvent("updated",{detail:this._points}))}createPoint(t,e){const o=new S(t,e);return o.eventTarget.addEventListener("updated",()=>{this._points.sort((i,r)=>i.x-r.x),this.dispatchUpdatedEvent()}),this._points.push(o),this._points.sort((i,r)=>i.x-r.x),o}deletePoint(t){this._points=this._points.filter(e=>e!==t)}}const G=(n,t,e,o={lineWidth:1,strokeStyle:"#000",fillStyle:void 0,clip:!1})=>{const i=t[3],r=t[2]/(e.length-1),c=i+t[1];n.lineWidth=o.lineWidth,n.strokeStyle=o.strokeStyle,n.beginPath(),n.moveTo(t[0],t[1]+t[3]);for(let s=0;s<e.length;s++)n.lineTo(t[0]+s*r,Math.max(t[1],c-e[s]*i));if(o.fillStyle){if(n.fillStyle=o.fillStyle,n.lineTo(t[0]+t[2],t[1]+t[3]),o.clip){n.clip();return}n.fill()}n.stroke()},N=1,K=(n,t,e,o)=>{const i=o||document.createElement("canvas");if(i.setAttribute("width",String(t)),i.setAttribute("height",String(N)),n.getSize()===0)return i;const r=n.getUint8Table(e[0],e[1],t,!0),c=i.getContext("2d");if(c){const s=c.getImageData(0,0,t,N);for(let d=0;d<N;d++)s.data.set(r,d*4*t);const l=N*t*4;for(let d=3;d<l;d+=4)s.data[d]=255;c.putImageData(s,0,0)}return i},Z=n=>{const t=B(n);return t[0][0]-=1e-8,t[t.length-1][0]+=1e-8,t},q=n=>{if(!n)return[];const t=n.map(s=>s===0?0:Math.log(s)),e=t.filter(Boolean),o=Math.min(...e),r=Math.max(...e)-o;return t.map(s=>s===0?0:(s-o)/r)};function J(n,t){if(n.length!==t.length)return!1;for(let e=0;e<n.length;e++)if(n[e]!==t[e])return!1;return!0}function O(n){return`#${n.map(e=>Math.floor(e*255)).map(e=>`0${e.toString(16)}`.slice(-2)).join("")}`}const L=10,Q=()=>{const n=document.createElementNS("http://www.w3.org/2000/svg","svg");return n.setAttribute("style","position: absolute; top: 0; left: 0; z-index: 2; box-sizing: border-box; width: 100%; height: 100%;"),n},tt=n=>{const t=document.createElement("div");t.setAttribute("style","position: relative; width: 100%; height: 100%; user-select: none;"),n.appendChild(t);const e=Q();t.appendChild(e);const o=new EventTarget,i=h=>{o.addEventListener("sizeupdated",h)};new ResizeObserver(()=>{o.dispatchEvent(new Event("sizeupdated"))}).observe(t);const c=document.createElementNS("http://www.w3.org/2000/svg","rect");e.appendChild(c),c.setAttribute("fill","none"),c.setAttribute("stroke","black");const s=h=>{e.appendChild(h)},l=h=>{e.removeChild(h)};let d=[0,1,0,1];const P=()=>d,p=(h,f,w=0,u=1)=>{const C=d;d=[h,f,w,u],J(C,d)||o.dispatchEvent(new Event("sizeupdated"))},b=()=>{const{top:h,left:f,width:w,height:u}=t.getBoundingClientRect();return{width:w-2*L,height:u-2*L,top:h+L,left:f+L}},x=(h,f)=>{const{top:w,left:u,width:C,height:R}=b(),E=d[1]-d[0]||.001,M=d[3]-d[2]||.001;return[(h-u)/C*E+d[0],(1-(f-w)/R)*M+d[2]]},v=(h,f)=>{const{width:w,height:u}=b(),C=d[1]-d[0]||.001,R=(h-d[0])/C*w+L,E=d[3]-d[2]||.001,M=(1-(f-d[2])/E)*u+L;return[R,M]},A=()=>{const[h,f]=v(0,0),[w,u]=v(1,1);return{left:h,bottom:f,right:w,top:u}};return i(()=>{const{left:h,bottom:f,right:w,top:u}=A();c.setAttribute("x",`${h}`),c.setAttribute("y",`${u}`),c.setAttribute("width",`${Math.max(0,w-h)}`),c.setAttribute("height",`${Math.max(0,f-u)}`)}),{appendChild:s,removeChild:l,addSizeObserver:i,getViewBox:P,setViewBox:p,domToNormalized:x,normalizedToSvg:v,borderSize:A,remove:()=>n.removeChild(t),root:t,svg:e}};let V=!1;const et=()=>{if(V)return;V=!0;const n=document.createElement("style");n.innerHTML=` | ||
(function(S,v){typeof exports=="object"&&typeof module<"u"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(S=typeof globalThis<"u"?globalThis:S||self,v(S.TransferFunctionEditor={}))})(this,function(S){"use strict";var Pt=Object.defineProperty;var Tt=(S,v,y)=>v in S?Pt(S,v,{enumerable:!0,configurable:!0,writable:!0,value:y}):S[v]=y;var a=(S,v,y)=>(Tt(S,typeof v!="symbol"?v+"":v,y),y);class v{constructor(t,e){a(this,"_x");a(this,"_y");a(this,"eventTarget",new EventTarget);this.setPosition(t,e)}get x(){return this._x}set x(t){this._x=t,this.dispatchUpdatedEvent()}get y(){return this._y}set y(t){this._y=t,this.dispatchUpdatedEvent()}setPosition(t,e){this._x=t,this._y=e,this.dispatchUpdatedEvent()}dispatchUpdatedEvent(){this.eventTarget.dispatchEvent(new CustomEvent("updated",{detail:[this.x,this.y]}))}}const y=(n,t=!1)=>{if(n.length===0)return[[0,1],[1,1]];if(n.length===1){const[,i]=n[0];return[[0,i],[1,i]]}const e=n[0],o=n[n.length-1];return t?[[e[0],0],...n,[o[0],0]]:[[0,e[1]],...n,[1,o[1]]]},V=n=>y(n.map(({x:t,y:e})=>[t,e]));class Z{constructor(){a(this,"_points",[]);a(this,"eventTarget",new EventTarget)}get points(){return[...this._points]}addPoint(t,e){const o=this.createPoint(t,e);return this.dispatchUpdatedEvent(),o}addPoints(t){return t.map(([o,i])=>this.createPoint(o,i))}setPoints(t){return[...this._points].forEach(e=>this.deletePoint(e)),this.addPoints(t)}removePoint(t){this.deletePoint(t),this.dispatchUpdatedEvent()}dispatchUpdatedEvent(){this.eventTarget.dispatchEvent(new CustomEvent("updated",{detail:this._points}))}createPoint(t,e){const o=new v(t,e);return o.eventTarget.addEventListener("updated",()=>{this._points.sort((i,s)=>i.x-s.x),this.dispatchUpdatedEvent()}),this._points.push(o),this._points.sort((i,s)=>i.x-s.x),o}deletePoint(t){this._points=this._points.filter(e=>e!==t)}}const q=(n,t,e,o={lineWidth:1,strokeStyle:"#000",fillStyle:void 0,clip:!1})=>{const i=t[3],s=t[2]/(e.length-1),d=i+t[1];n.lineWidth=o.lineWidth,n.strokeStyle=o.strokeStyle,n.beginPath(),n.moveTo(t[0],t[1]+t[3]);for(let r=0;r<e.length;r++)n.lineTo(t[0]+r*s,Math.max(t[1],d-e[r]*i));if(o.fillStyle){if(n.fillStyle=o.fillStyle,n.lineTo(t[0]+t[2],t[1]+t[3]),o.clip){n.clip();return}n.fill()}n.stroke()},N=1,J=(n,t,e,o)=>{const i=o||document.createElement("canvas");if(i.setAttribute("width",String(t)),i.setAttribute("height",String(N)),n.getSize()===0)return i;const s=n.getUint8Table(e[0],e[1],t,!0),d=i.getContext("2d");if(d){const r=d.getImageData(0,0,t,N);for(let l=0;l<N;l++)r.data.set(s,l*4*t);const p=N*t*4;for(let l=3;l<p;l+=4)r.data[l]=255;d.putImageData(r,0,0)}return i},Q=n=>{const t=y(n);return t[0][0]-=1e-8,t[t.length-1][0]+=1e-8,t},tt=n=>{if(!n)return[];const t=n.map(r=>r===0?0:Math.log(r)),e=t.filter(Boolean),o=Math.min(...e),s=Math.max(...e)-o;return t.map(r=>r===0?0:(r-o)/s)};function et(n,t){if(n.length!==t.length)return!1;for(let e=0;e<n.length;e++)if(n[e]!==t[e])return!1;return!0}function B(n){return`#${n.map(e=>Math.floor(e*255)).map(e=>`0${e.toString(16)}`.slice(-2)).join("")}`}const R=11,nt=2*R,ot=()=>{const n=document.createElementNS("http://www.w3.org/2000/svg","svg");return n.setAttribute("style","position: absolute; top: 0; left: 0; z-index: 2; box-sizing: border-box; width: 100%; height: 100%;"),n},it=n=>{const t=document.createElement("div");t.setAttribute("style","position: relative; width: 100%; height: 100%; user-select: none;"),n.appendChild(t);const e=ot();t.appendChild(e);const o=new EventTarget,i=g=>{o.addEventListener("sizeupdated",g)};new ResizeObserver(()=>{o.dispatchEvent(new Event("sizeupdated"))}).observe(t);const d=document.createElementNS("http://www.w3.org/2000/svg","rect");e.appendChild(d),d.setAttribute("fill","none"),d.setAttribute("stroke","black");const r=g=>{e.appendChild(g)},p=g=>{e.removeChild(g)};let l=[0,1,0,1];const C=()=>l,u=(g,w,b=0,E=1)=>{const A=l;l=[g,w,b,E],et(A,l)||o.dispatchEvent(new Event("sizeupdated"))},P=()=>{const{top:g,left:w,width:b,height:E}=t.getBoundingClientRect();return{width:b-2*R,height:E-(nt+R),top:g+R,left:w+R}},c=(g,w)=>{const{top:b,left:E,width:A,height:L}=P(),x=l[1]-l[0]||.001,z=l[3]-l[2]||.001;return[(g-E)/A*x+l[0],(1-(w-b)/L)*z+l[2]]},h=(g,w)=>{const{width:b,height:E}=P(),A=l[1]-l[0]||.001,L=(g-l[0])/A*b+R,x=l[3]-l[2]||.001,z=(1-(w-l[2])/x)*E+R;return[L,z]},f=()=>{const[g,w]=h(0,0),[b,E]=h(1,1);return{left:g,bottom:w,right:b,top:E}};return i(()=>{const{left:g,bottom:w,right:b,top:E}=f();d.setAttribute("x",`${g}`),d.setAttribute("y",`${E}`),d.setAttribute("width",`${Math.max(0,b-g)}`),d.setAttribute("height",`${Math.max(0,w-E)}`)}),{appendChild:r,removeChild:p,addSizeObserver:i,getViewBox:C,setViewBox:u,domToNormalized:c,normalizedToSvg:h,borderSize:f,remove:()=>n.removeChild(t),root:t,svg:e}};let H=!1;const st=()=>{if(H)return;H=!0;const n=document.createElement("style");n.innerHTML=` | ||
.tfeditor-svg-tooltip { | ||
@@ -15,3 +15,5 @@ color: black; | ||
max-width: 150px; | ||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); | ||
} | ||
`,document.head.appendChild(n)};function nt(n){et();const t=[10,10],e=document.createElementNS("http://www.w3.org/2000/svg","foreignObject");e.setAttribute("width","100%"),e.setAttribute("height","100%"),e.setAttribute("pointer-events","none");const o=document.createElementNS("http://www.w3.org/1999/xhtml","div");o.setAttribute("class","tfeditor-svg-tooltip"),e.appendChild(o),n.append(e);function i(l,d,P){let p=d+t[0],b=P+t[1];o.innerHTML=l;const x=n.getBBox(),v=o.getBoundingClientRect();p>x.width-v.width&&(p=d-v.width-t[0]),b>x.height-v.height&&(b=P-v.height-t[1]),o.style.transform=`translate(${p}px,${b}px)`}function r(){o.style.visibility="visible"}function c(){o.style.visibility="hidden"}return{update:i,show:r,hide:c,remove:()=>{n.removeChild(e)}}}const ot="controlPoint",z=2,it=8,H=14,T=H,st=()=>{const n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("width",String(T*2)),n.setAttribute("height",String(T*2)),n.setAttribute("viewBox",`-${T} -${T} ${T*2} ${T*2}`);const t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("r",String(it)),t.setAttribute("fill","white"),t.setAttribute("stroke","black"),t.setAttribute("stroke-width",String(z)),t.setAttribute("class",ot),n.appendChild(t);const e=document.createElementNS("http://www.w3.org/2000/svg","circle");return e.setAttribute("r",String(H)),e.setAttribute("fill","transparent"),e.setAttribute("stroke","transparent"),e.setAttribute("style","cursor: move;"),n.appendChild(e),{group:n,circle:t,clickTarget:e}};class U{constructor(t,e,o,i,r=!1){a(this,"element");a(this,"circle");a(this,"tooltip");a(this,"container");a(this,"isDragging",!1);a(this,"isHovered",!1);a(this,"point");a(this,"deletable",!0);a(this,"DELETE_EVENT","deleteme");a(this,"eventTarget",new EventTarget);a(this,"grabX",0);a(this,"grabY",0);a(this,"toDataSpace");const{group:c,circle:s}=st();this.element=c,this.circle=s,this.point=e,this.container=t,this.toDataSpace=o,this.tooltip=nt(this.container.svg),t.addSizeObserver(()=>{this.positionElement()}),i&&this.eventTarget.addEventListener(this.DELETE_EVENT,l=>{i(l)}),t.appendChild(this.element),this.positionElement(),this.point.eventTarget.addEventListener("updated",()=>this.positionElement()),this.setupInteraction(),r&&this.startInteraction(!0)}remove(){this.tooltip.remove(),this.container.removeChild(this.element)}positionElement(){const{x:t,y:e}=this.point,[o,i]=this.container.normalizedToSvg(t,e);this.element.setAttribute("x",String(o-T)),this.element.setAttribute("y",String(i-T));const r=this.toDataSpace(t);this.tooltip.update(String(r),o,i)}movePoint(t){const[e,o]=this.container.domToNormalized(t.clientX,t.clientY);this.point.setPosition(e+this.grabX,o+this.grabY),this.positionElement()}update(){this.circle.setAttribute("stroke-width",String(z)),this.isHovered?(this.circle.setAttribute("stroke-width",String(z+1)),this.tooltip.show()):this.tooltip.hide(),this.isDragging&&this.circle.setAttribute("stroke-width",String(z*2))}startInteraction(t=!1){this.isDragging=t,!this.isDragging&&this.deletable&&this.circle.setAttribute("stroke","red");const e=i=>{this.isDragging=!0,this.circle.setAttribute("stroke","black"),this.movePoint(i)};document.addEventListener("pointermove",e);const o=()=>{if(document.removeEventListener("pointermove",e),document.removeEventListener("pointerup",o),!this.isDragging){const i=new CustomEvent(this.DELETE_EVENT,{detail:this});this.eventTarget.dispatchEvent(i)}this.isDragging=!1,this.update()};document.addEventListener("pointerup",o)}setupInteraction(){this.element.addEventListener("pointerdown",t=>{t.stopPropagation(),this.circle.setAttribute("stroke-width",String(z*2));const[e,o]=this.container.domToNormalized(t.clientX,t.clientY);this.grabX=this.point.x-e,this.grabY=this.point.y-o,this.startInteraction()}),this.element.addEventListener("pointerenter",()=>{this.isHovered=!0,this.update()}),this.element.addEventListener("pointerleave",()=>{this.isHovered=!1,this.update()})}setColor(t){this.circle.setAttribute("fill",t)}}a(U,"styleElement");class rt{constructor(t,e,o){a(this,"container");a(this,"points");a(this,"onPointsUpdated");a(this,"controlPoints",[]);a(this,"isNewPointFromPointer",!1);a(this,"toDataSpace");this.container=t,this.points=e,this.toDataSpace=o;const{root:i}=t;i.addEventListener("pointerdown",r=>this.onPointerDown(r)),this.onPointsUpdated=()=>this.updatePoints(),this.points.eventTarget.addEventListener("updated",this.onPointsUpdated),this.updatePoints()}remove(){this.points.eventTarget.removeEventListener("updated",this.onPointsUpdated)}onPointerDown(t){const[e,o]=this.container.domToNormalized(t.clientX,t.clientY);this.isNewPointFromPointer=!0,this.points.addPoint(e,o),this.isNewPointFromPointer=!1}onControlPointDelete(t){this.points.removePoint(t.detail.point)}updatePoints(){const t=this.controlPoints.filter(i=>!this.points.points.find(r=>r===i.point));t.forEach(i=>i.remove()),this.controlPoints=this.controlPoints.filter(i=>!t.includes(i));const e=i=>this.controlPoints.find(r=>r.point===i),o=i=>this.controlPoints.push(new U(this.container,i,this.toDataSpace,r=>this.onControlPointDelete(r),this.isNewPointFromPointer));this.points.points.filter(i=>!e(i)).forEach(o)}}const at=()=>{const n=document.createElementNS("http://www.w3.org/2000/svg","polyline");return n.setAttribute("fill","none"),n.setAttribute("stroke","black"),n.setAttribute("stroke-width","2"),n};class dt{constructor(t,e){a(this,"points");a(this,"container");a(this,"onPointsUpdated");a(this,"element");this.container=t,this.points=e,this.element=at(),this.container.appendChild(this.element),this.onPointsUpdated=()=>this.update(),this.points.eventTarget.addEventListener("updated",this.onPointsUpdated),this.container.addSizeObserver(()=>{this.update()}),this.update()}remove(){this.points.eventTarget.removeEventListener("updated",this.onPointsUpdated)}update(){if(this.points.points.length===0){this.element.setAttribute("points","");return}const t=F(this.points.points).map(([e,o])=>this.container.normalizedToSvg(e,o)).map(([e,o])=>`${e},${o}`).join(" ");this.element.setAttribute("points",t)}}const X=1.1,ct=n=>{n.root.addEventListener("wheel",t=>{const e=t.deltaY>0?X:1/X,[o]=n.domToNormalized(t.clientX,t.clientY),[i,r]=n.getViewBox(),c=Math.max(0,i-Math.max(0,o-i)*(e-1)),s=Math.min(1,(r-i)*e+c);c===i&&s===r||(t.preventDefault(),t.stopPropagation(),n.setViewBox(c,s))})},$="rgba(50, 50, 50, 0.3)",lt=(n,t,e)=>{const o=document.createElement("canvas");n.root.appendChild(o),o.setAttribute("style","width: 100%; height: 100%; ");const i=o.getContext("2d");let r,c;const s=document.createElement("canvas"),l=()=>{if(i){if(i.clearRect(0,0,o.width,o.height),r){const{width:p,height:b}=n.root.getBoundingClientRect();o.setAttribute("width",String(p)),o.setAttribute("height",String(b));const{left:x,right:v,bottom:A,top:y}=n.borderSize();if(Math.ceil(v-x)<0)return;const h=F(t.points),f=[[0,0],...h,[1,0]].map(([k,D])=>n.normalizedToSvg(k,D));i.save(),i.beginPath(),f.forEach(([k,D])=>{i.lineTo(k,D)}),i.clip();const[w,u]=e.getColorRange(),[C]=n.normalizedToSvg(w,1),[R]=n.normalizedToSvg(u,1),E=Math.min(p,Math.max(0,C)),M=Math.min(p,Math.max(0,R)),_=M-E<2?E+2:M,W=Math.ceil(_-E);if(r){const k=R-C,D=(E-C)/k,vt=(_-R)/k,I=r.getMappingRange(),Y=I[1]-I[0],ft=[I[0]+Y*D,I[1]+Y*vt];K(r,W,ft,s),i.drawImage(s,0,0,s.width,s.height,Math.floor(E),Math.floor(y),W,Math.ceil(A-y));const wt=i.imageSmoothingEnabled;i.imageSmoothingEnabled=!1,i.drawImage(s,0,0,1,1,0,Math.floor(y),Math.floor(E),Math.ceil(A-y)),i.drawImage(s,s.width-1,0,1,1,Math.floor(_),Math.floor(y),p-_,Math.ceil(A-y)),i.imageSmoothingEnabled=wt}i.restore()}if(c){const{left:p,right:b,bottom:x,top:v}=n.borderSize(),A=[p,v,b-p,x-v];G(i,A,c,{lineWidth:1,strokeStyle:$,fillStyle:$})}}};return n.addSizeObserver(l),t.eventTarget.addEventListener("updated",l),e.eventTarget.addEventListener("updated",l),{container:n,canvas:o,setColorTransferFunction:p=>{r=p,l()},setHistogram:p=>{c=p,l()},render:l,remove:()=>n.root.removeChild(o)}},ht=()=>{const n=[new S(0,0),new S(1,0)],t=()=>n.sort((s,l)=>s.x-l.x),e=()=>t().map(s=>s.x),o=new EventTarget,i=()=>o.dispatchEvent(new CustomEvent("updated",{detail:e()}));let r=!1;const c=s=>{s.eventTarget.addEventListener("updated",()=>{s.y!==0&&(s.y=0),r||i()})};return n.forEach(c),{getPoints:t,getColorRange:e,setColorRange:s=>{r=!0,t().forEach((l,d)=>{l.x=s[d]}),r=!1,i()},eventTarget:o}},pt=(n,t,e)=>{const o=t.getPoints().map(s=>{const l=new U(n,s,e);return l.deletable=!1,l});let i;const r=()=>{if(!i)return;const s=i.getMappingRange(),l=[];i.getColor(s[0],l);const d=[];i.getColor(s[1],d);const P=o.sort((p,b)=>p.point.x-b.point.x);P[0].setColor(O(l)),P[1].setColor(O(d))},c=s=>{i=s,r()};return t.eventTarget.addEventListener("updated",()=>{r()}),{points:o,setColorTransferFunction:c}},gt=()=>{let n;return{setColorTransferFunction:o=>{n=o},toDataSpace:o=>{if(!n)return o;const[i,r]=n.getMappingRange(),c=r-i;return o*c+i}}};class ut{constructor(t){a(this,"eventTarget",new EventTarget);a(this,"points");a(this,"colorRange");a(this,"colorRangeController");a(this,"line");a(this,"pointController");a(this,"container");a(this,"background");a(this,"dataSpaceConverter",gt());this.container=tt(t),ct(this.container),this.points=new j;const e=[[0,0],[1,1]];this.points.setPoints(e),this.line=new dt(this.container,this.points),this.pointController=new rt(this.container,this.points,this.dataSpaceConverter.toDataSpace),this.colorRange=ht(),this.colorRangeController=pt(this.container,this.colorRange,this.dataSpaceConverter.toDataSpace),this.background=lt(this.container,this.points,this.colorRange),this.points.eventTarget.addEventListener("updated",o=>{this.eventTarget.dispatchEvent(new CustomEvent("updated",{detail:o.detail}))}),this.colorRange.eventTarget.addEventListener("updated",o=>{this.eventTarget.dispatchEvent(new CustomEvent("colorRange",{detail:o.detail}))})}remove(){this.background.remove(),this.container.remove()}getPoints(){return this.points.points.map(({x:t,y:e})=>[t,e])}setPoints(t){this.points.setPoints(t),this.pointController.updatePoints(),this.line.update(),this.background.render()}getColorRange(){return this.colorRange.getColorRange()}setColorRange(t){return this.colorRange.setColorRange(t)}setViewBox(t,e,o=0,i=1){this.container.setViewBox(t,e,o,i)}setColorTransferFunction(t){this.dataSpaceConverter.setColorTransferFunction(t),this.background.setColorTransferFunction(t),this.colorRangeController.setColorTransferFunction(t)}setHistogram(t){this.background.setHistogram(q(t))}}m.TransferFunctionEditor=ut,m.windowPointsForSort=Z,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})}); | ||
`,document.head.appendChild(n)};function rt(n){st();const t=[10,10],e=document.createElementNS("http://www.w3.org/2000/svg","foreignObject");e.setAttribute("width","100%"),e.setAttribute("height","100%"),e.setAttribute("pointer-events","none");const o=document.createElementNS("http://www.w3.org/1999/xhtml","div");o.setAttribute("class","tfeditor-svg-tooltip"),e.appendChild(o),n.append(e);function i(p,l,C){let u=l+t[0],P=C+t[1];o.textContent=p;const c=n.getBBox(),h=o.getBoundingClientRect();u>c.width-h.width&&(u=l-h.width-t[0]),P>c.height-h.height&&(P=C-h.height-t[1]),o.style.transform=`translate(${u}px,${P}px)`}function s(){o.style.visibility="visible"}function d(){o.style.visibility="hidden"}return{update:i,show:s,hide:d,remove:()=>{n.removeChild(e)}}}const at="controlPoint",O=n=>Math.max(0,Math.min(1,n)),M=2,dt=8,X=14,T=X,lt=()=>{const n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("width",String(T*2)),n.setAttribute("height",String(T*2)),n.setAttribute("viewBox",`-${T} -${T} ${T*2} ${T*2}`);const t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("r",String(dt)),t.setAttribute("fill","white"),t.setAttribute("stroke","black"),t.setAttribute("stroke-width",String(M)),t.setAttribute("class",at),n.appendChild(t);const e=document.createElementNS("http://www.w3.org/2000/svg","circle");return e.setAttribute("r",String(X)),e.setAttribute("fill","transparent"),e.setAttribute("stroke","transparent"),e.setAttribute("style","cursor: move;"),n.appendChild(e),{group:n,circle:t,clickTarget:e}};class F{constructor(t,e,o,i,s=!1){a(this,"element");a(this,"circle");a(this,"tooltip");a(this,"container");a(this,"isDragging",!1);a(this,"isHovered",!1);a(this,"point");a(this,"deletable",!0);a(this,"DELETE_EVENT","deleteme");a(this,"eventTarget",new EventTarget);a(this,"grabX",0);a(this,"grabY",0);a(this,"toDataSpace");const{group:d,circle:r}=lt();this.element=d,this.circle=r,this.point=e,this.container=t,this.toDataSpace=o,this.tooltip=rt(this.container.svg),t.addSizeObserver(()=>{this.positionElement()}),i&&this.eventTarget.addEventListener(this.DELETE_EVENT,p=>{i(p)}),t.appendChild(this.element),this.positionElement(),this.point.eventTarget.addEventListener("updated",()=>this.positionElement()),this.setupInteraction(),s&&this.startInteraction(!0)}remove(){this.tooltip.remove(),this.container.removeChild(this.element)}getSvgPosition(){const{x:t,y:e}=this.point;return this.container.normalizedToSvg(t,e)}updateTooltip(t=void 0){const{x:e}=this.point,o=this.toDataSpace(e),[i,s]=t??this.getSvgPosition();this.tooltip.update(o.toPrecision(4),i,s)}positionElement(){const[t,e]=this.getSvgPosition();this.element.setAttribute("x",String(t-T)),this.element.setAttribute("y",String(e-T)),this.updateTooltip([t,e])}movePoint(t){const[e,o]=this.container.domToNormalized(t.clientX,t.clientY);this.point.setPosition(O(e+this.grabX),O(o+this.grabY))}update(){this.circle.setAttribute("stroke-width",String(M)),this.isHovered&&(this.circle.setAttribute("stroke-width",String(M+1)),this.updateTooltip(),this.tooltip.show()),this.isDragging&&this.circle.setAttribute("stroke-width",String(M*2)),!this.isDragging&&!this.isHovered&&this.tooltip.hide()}startInteraction(t=!1){this.isDragging=t,!this.isDragging&&this.deletable&&this.circle.setAttribute("stroke","red");const e=i=>{this.isDragging||this.circle.setAttribute("stroke","black"),this.isDragging=!0,this.movePoint(i)};document.addEventListener("pointermove",e);const o=()=>{if(document.removeEventListener("pointermove",e),document.removeEventListener("pointerup",o),!this.isDragging){const i=new CustomEvent(this.DELETE_EVENT,{detail:this});this.eventTarget.dispatchEvent(i)}this.isDragging=!1,this.update()};document.addEventListener("pointerup",o)}setupInteraction(){this.element.addEventListener("pointerdown",t=>{t.stopPropagation(),this.circle.setAttribute("stroke-width",String(M*2));const[e,o]=this.container.domToNormalized(t.clientX,t.clientY);this.grabX=this.point.x-e,this.grabY=this.point.y-o,this.startInteraction()}),this.element.addEventListener("pointerenter",()=>{this.isHovered=!0,this.update()}),this.element.addEventListener("pointerleave",()=>{this.isHovered=!1,this.update()})}setColor(t){this.circle.setAttribute("fill",t)}}a(F,"styleElement");class ct{constructor(t,e,o){a(this,"container");a(this,"points");a(this,"onPointsUpdated");a(this,"controlPoints",[]);a(this,"isNewPointFromPointer",!1);a(this,"toDataSpace");this.container=t,this.points=e,this.toDataSpace=o;const{root:i}=t;i.addEventListener("pointerdown",s=>this.onPointerDown(s)),this.onPointsUpdated=()=>this.updatePoints(),this.points.eventTarget.addEventListener("updated",this.onPointsUpdated),this.updatePoints()}remove(){this.points.eventTarget.removeEventListener("updated",this.onPointsUpdated)}onPointerDown(t){const[e,o]=this.container.domToNormalized(t.clientX,t.clientY).map(O);this.isNewPointFromPointer=!0,this.points.addPoint(e,o),this.isNewPointFromPointer=!1}onControlPointDelete(t){this.points.removePoint(t.detail.point)}updatePoints(){const t=this.controlPoints.filter(i=>!this.points.points.find(s=>s===i.point));t.forEach(i=>i.remove()),this.controlPoints=this.controlPoints.filter(i=>!t.includes(i));const e=i=>this.controlPoints.find(s=>s.point===i),o=i=>this.controlPoints.push(new F(this.container,i,this.toDataSpace,s=>this.onControlPointDelete(s),this.isNewPointFromPointer));this.points.points.filter(i=>!e(i)).forEach(o)}}const ht=()=>{const n=document.createElementNS("http://www.w3.org/2000/svg","polyline");return n.setAttribute("fill","none"),n.setAttribute("stroke","black"),n.setAttribute("stroke-width","2"),n};class pt{constructor(t,e){a(this,"points");a(this,"container");a(this,"onPointsUpdated");a(this,"element");this.container=t,this.points=e,this.element=ht(),this.container.appendChild(this.element),this.onPointsUpdated=()=>this.update(),this.points.eventTarget.addEventListener("updated",this.onPointsUpdated),this.container.addSizeObserver(()=>{this.update()}),this.update()}remove(){this.points.eventTarget.removeEventListener("updated",this.onPointsUpdated)}update(){if(this.points.points.length===0){this.element.setAttribute("points","");return}const t=V(this.points.points).map(([e,o])=>this.container.normalizedToSvg(e,o)).map(([e,o])=>`${e},${o}`).join(" ");this.element.setAttribute("points",t)}}const Y=1.1,gt=n=>{n.root.addEventListener("wheel",t=>{const e=t.deltaY>0?Y:1/Y,[o]=n.domToNormalized(t.clientX,t.clientY),[i,s]=n.getViewBox(),d=Math.max(0,i-Math.max(0,o-i)*(e-1)),r=Math.min(1,(s-i)*e+d);d===i&&r===s||(t.preventDefault(),t.stopPropagation(),n.setViewBox(d,r))})},W="rgba(50, 50, 50, 0.3)",ut=(n,t,e)=>{const o=document.createElement("canvas");n.root.appendChild(o),o.setAttribute("style","width: 100%; height: 100%; ");const i=o.getContext("2d");let s,d;const r=document.createElement("canvas"),p=()=>{if(i){if(i.clearRect(0,0,o.width,o.height),s){const{width:u,height:P}=n.root.getBoundingClientRect();o.setAttribute("width",String(u)),o.setAttribute("height",String(P));const{left:c,right:h,bottom:f,top:m}=n.borderSize();if(Math.ceil(h-c)<0)return;const g=V(t.points),w=[[0,0],...g,[1,0]].map(([D,_])=>n.normalizedToSvg(D,_));i.save(),i.beginPath(),w.forEach(([D,_])=>{i.lineTo(D,_)}),i.clip();const[b,E]=e.getColorRange(),[A]=n.normalizedToSvg(b,1),[L]=n.normalizedToSvg(E,1),x=Math.min(u,Math.max(0,A)),z=Math.min(u,Math.max(0,L)),I=z-x<2?x+2:z,G=Math.ceil(I-x);if(s){const D=L-A,_=(x-A)/D,Et=(I-L)/D,U=s.getMappingRange(),K=U[1]-U[0],St=[U[0]+K*_,U[1]+K*Et];J(s,G,St,r),i.drawImage(r,0,0,r.width,r.height,Math.floor(x),Math.floor(m),G,Math.ceil(f-m));const Ct=i.imageSmoothingEnabled;i.imageSmoothingEnabled=!1,i.drawImage(r,0,0,1,1,0,Math.floor(m),Math.floor(x),Math.ceil(f-m)),i.drawImage(r,r.width-1,0,1,1,Math.floor(I),Math.floor(m),u-I,Math.ceil(f-m)),i.imageSmoothingEnabled=Ct}i.restore()}if(d){const{left:u,right:P,bottom:c,top:h}=n.borderSize(),f=[u,h,P-u,c-h];q(i,f,d,{lineWidth:1,strokeStyle:W,fillStyle:W})}}};return n.addSizeObserver(p),t.eventTarget.addEventListener("updated",p),e.eventTarget.addEventListener("updated",p),{container:n,canvas:o,setColorTransferFunction:u=>{s=u,p()},setHistogram:u=>{d=u,p()},render:p,remove:()=>n.root.removeChild(o)}},$=-2.75;class j extends F{getSvgPosition(){const{x:t}=this.point,[e,o]=this.container.normalizedToSvg(t,0),i=o+$+T;return[e,i]}}const mt=()=>{const n=[new v(0,0),new v(1,0)],t=()=>n.sort((r,p)=>r.x-p.x),e=()=>t().map(r=>r.x),o=new EventTarget,i=()=>o.dispatchEvent(new CustomEvent("updated",{detail:e()}));let s=!1;const d=r=>{r.eventTarget.addEventListener("updated",()=>{s||i()})};return n.forEach(d),{getPoints:t,getColorRange:e,setColorRange:r=>{s=!0,t().forEach((p,l)=>{p.x=r[l]}),s=!1,i()},eventTarget:o}},vt=()=>{const n=document.createElementNS("http://www.w3.org/2000/svg","polyline");return n.setAttribute("fill","none"),n.setAttribute("stroke","black"),n.setAttribute("stroke-width","1"),n},ft=(n,t,e)=>{const o=vt();n.appendChild(o);const i=new v(.5,$),s=new j(n,i,e);s.deletable=!1;const d=t.getPoints().map(c=>{const h=new j(n,c,e);return h.deletable=!1,h}),r=()=>{const[,c]=n.normalizedToSvg(0,0),h=c+$+T,f=d.map(m=>[m.point.x,m.point.y]).map(([m,k])=>n.normalizedToSvg(m,k)).map(([m])=>`${m},${h}`).join(" ");o.setAttribute("points",f)};n.addSizeObserver(()=>{r()});let p=!1,l=!1;i.eventTarget.addEventListener("updated",()=>{if(l)return;const c=d[1].point.x-d[0].point.x;p=!0,d[0].point.x=i.x-c/2,d[1].point.x=i.x+c/2,p=!1,r()});let C;const u=()=>{if(!C)return;const c=C.getMappingRange(),h=[];C.getColor(c[0],h);const f=[];C.getColor(c[1],f);const m=d.sort((w,b)=>w.point.x-b.point.x);m[0].setColor(B(h)),m[1].setColor(B(f));const k=[],g=(c[1]-c[0])/2+c[0];C.getColor(g,k),s.setColor(B(k))},P=c=>{C=c,u()};return t.eventTarget.addEventListener("updated",()=>{if(p)return;u();const c=t.getPoints().length;l=!0,i.x=t.getPoints().reduce((h,f)=>h+f.x,0)/c,r(),l=!1}),{points:d,setColorTransferFunction:P}},wt=()=>{let n=[0,1];return{setRange:o=>{n=o},toDataSpace:o=>{const[i,s]=n,d=s-i;return o*d+i}}};class bt{constructor(t){a(this,"eventTarget",new EventTarget);a(this,"points");a(this,"colorRange");a(this,"colorRangeController");a(this,"line");a(this,"pointController");a(this,"container");a(this,"background");a(this,"dataSpaceConverter",wt());this.container=it(t),gt(this.container),this.points=new Z;const e=[[0,0],[1,1]];this.points.setPoints(e),this.line=new pt(this.container,this.points),this.pointController=new ct(this.container,this.points,this.dataSpaceConverter.toDataSpace),this.colorRange=mt(),this.colorRangeController=ft(this.container,this.colorRange,this.dataSpaceConverter.toDataSpace),this.background=ut(this.container,this.points,this.colorRange),this.points.eventTarget.addEventListener("updated",o=>{this.eventTarget.dispatchEvent(new CustomEvent("updated",{detail:o.detail}))}),this.colorRange.eventTarget.addEventListener("updated",o=>{this.eventTarget.dispatchEvent(new CustomEvent("colorRange",{detail:o.detail}))})}remove(){this.background.remove(),this.container.remove()}getPoints(){return this.points.points.map(({x:t,y:e})=>[t,e])}setPoints(t){this.points.setPoints(t),this.pointController.updatePoints(),this.line.update(),this.background.render()}getColorRange(){return this.colorRange.getColorRange()}setColorRange(t){return this.colorRange.setColorRange(t)}setViewBox(t,e,o=0,i=1){this.container.setViewBox(t,e,o,i)}setColorTransferFunction(t){this.background.setColorTransferFunction(t),this.colorRangeController.setColorTransferFunction(t)}setHistogram(t){this.background.setHistogram(tt(t))}setRange(t){this.dataSpaceConverter.setRange(t)}}S.TransferFunctionEditor=bt,S.windowPointsForSort=Q,Object.defineProperty(S,Symbol.toStringTag,{value:"Module"})}); | ||
//# sourceMappingURL=TransferFunctionEditor.umd.js.map |
{ | ||
"name": "itk-viewer-transfer-function-editor", | ||
"version": "1.4.0", | ||
"version": "1.5.0", | ||
"description": "Interface to interactively edit opacity transfer functions, etc", | ||
@@ -5,0 +5,0 @@ "files": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
185097
26
1012