@realsee/dnalogel
Version:
159 lines (158 loc) • 7.34 kB
JavaScript
var p = Object.defineProperty;
var b = (r, t, e) => t in r ? p(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
var n = (r, t, e) => (b(r, typeof t != "symbol" ? t + "" : t, e), e);
import C from "hammerjs";
import * as l from "three";
import { Subscribe as w } from "@realsee/five";
function d(r, t, e) {
const s = r[t], i = r[e];
s === void 0 || i === void 0 || (r[t] = i, r[e] = s);
}
function R(r, t, e) {
const s = e / 2;
for (let i = 1; i <= s; i++) {
const h = e - (i - 1);
for (let a = 1; a <= t; a++) {
const o = (i - 1) * t + a - 1, f = (h - 1) * t + a - 1;
d(r, o * 4 + 0, f * 4 + 0), d(r, o * 4 + 1, f * 4 + 1), d(r, o * 4 + 2, f * 4 + 2), d(r, o * 4 + 3, f * 4 + 3);
}
}
}
class S {
constructor(t, e) {
n(this, "width");
n(this, "height");
n(this, "containerDom");
n(this, "hooks", new w());
n(this, "canvas", document.createElement("canvas"));
n(this, "five");
n(this, "scale");
n(this, "config");
n(this, "offset", { x: 0, y: 0 });
n(this, "context");
n(this, "renderCenter", new l.Vector3());
n(this, "hammer");
n(this, "state", { enabled: !1 });
n(this, "offsetRange");
n(this, "isPanning", !1);
n(this, "onPanstart", () => {
this.isPanning = !0, this.canvas.style.boxShadow = "0 2px 30px 0 rgba(0,0,0,0.20)";
});
n(this, "onPan", (t) => {
if (!this.isPanning || !this.offsetRange || this.hooks.emit("wantsPanGesture", t))
return;
const { translateX: s, translateY: i } = this.getPanOffset(t, this.offsetRange);
this.canvas.style.transform = `translate3d(${s}px, ${i}px, 100px)`;
});
n(this, "onPanend", (t) => {
if (this.isPanning = !1, this.canvas.style.boxShadow = "none", !this.offsetRange)
return;
const { translateX: e, translateY: s } = this.getPanOffset(t, this.offsetRange);
this.canvas.style.transform = `translate3d(${e}px, ${s}px, 100px)`, this.offset = { x: e, y: s };
});
var i, h, a;
if (!t.renderer)
throw new Error("Five Render 未初始化");
this.five = t, this.scale = (i = e == null ? void 0 : e.scale) != null ? i : 2, this.width = (h = e == null ? void 0 : e.width) != null ? h : 190, this.height = (a = e == null ? void 0 : e.height) != null ? a : 190, this.config = {
dragEnabled: (e == null ? void 0 : e.dragEnabled) || !1,
autoFixPCPosition: (e == null ? void 0 : e.autoFixPCPosition) || !1,
initialPosition: (e == null ? void 0 : e.initialPosition) || { left: "0", top: "0" }
};
const s = this.canvas.getContext("2d");
if (!s)
throw new Error("CANNOT CREATE CONTEXT2D");
this.context = s, this.config.dragEnabled && (this.hammer = new C(this.canvas), this.hammer.on("pan", this.onPan), this.hammer.on("panstart", this.onPanstart), this.hammer.on("panend", this.onPanend)), this.initStyle();
}
dispose() {
var t;
this.clear(), this.disable(), (t = this.hammer) == null || t.destroy();
}
enable() {
if (!this.state.enabled)
return this.state.enabled = !0, this.containerDom && this._appendTo(this.containerDom), this;
}
disable() {
if (this.state.enabled)
return this.state.enabled = !1, this.canvas.remove(), this;
}
/** 把放大镜放到某一个容器中 */
appendTo(t) {
return this.containerDom = t, this.state.enabled && this._appendTo(t), this;
}
/** 清除放大镜渲染内容 */
clear() {
return this.context.clearRect(0, 0, this.canvas.width, this.canvas.height), this;
}
/** 放大传入点位周围的内容 */
renderWithPoint(t) {
this.containerDom && this.state.enabled && (this.renderCenter = t, this.render(), this.config.autoFixPCPosition && this.autoFixPCPosition());
}
/** 放大传入点位周围的内容 */
renderWithScreenPoint(t) {
this.containerDom && this.state.enabled && (this.renderCenter = t, this.render(), this.config.autoFixPCPosition && this.autoFixPCPosition());
}
resetOffset() {
this.offset = { x: 0, y: 0 }, this.canvas.style.transform = "translate3d(0px, 0px, 100px)";
}
getCurrentState() {
return { enabled: this.state.enabled };
}
getRenderCenter() {
return this.renderCenter;
}
_appendTo(t) {
if (this.resetOffset(), t.appendChild(this.canvas), !this.offsetRange) {
const e = this.canvas.getBoundingClientRect(), s = t.getBoundingClientRect(), i = s.right - e.right, h = s.bottom - e.bottom, a = s.left - e.left, o = s.top - e.top;
this.offsetRange = {
min: { x: a, y: o },
max: { x: i, y: h }
};
}
}
autoFixPCPosition() {
if (!this.containerDom)
return;
const { width: t, height: e } = this, [s, i, h] = (() => {
if (this.renderCenter instanceof l.Vector3) {
const a = this.renderCenter.clone().project(this.five.camera);
return [
(a.x + 1) / 2 * this.containerDom.clientWidth,
-(a.x - 1) / 2 * this.containerDom.clientWidth,
-(a.y - 1) / 2 * this.containerDom.clientHeight
];
} else
return [this.renderCenter.x, this.containerDom.clientWidth - this.renderCenter.x, this.renderCenter.y];
})();
s < 183 ? (this.canvas.style.top = -e / 2 + "px", this.canvas.style.left = "90px") : h < 183 ? (this.canvas.style.top = "90px", this.canvas.style.left = -t / 2 + "px") : i < 183 ? (this.canvas.style.top = -e / 2 + "px", this.canvas.style.left = -t - 90 + "px") : (this.canvas.style.left = -t / 2 + "px", this.canvas.style.top = -e - 90 + "px"), this.canvas.style.transform = `translate3d(${s}px, ${h}px, 10px)`, this.offset = { x: s, y: h };
}
render() {
if (!this.five.renderer || !this.containerDom)
return;
const { scale: t, context: e, width: s, height: i } = this, h = this.five.renderer.getSize(new l.Vector2()), [a, o] = (() => {
if (this.renderCenter instanceof l.Vector3) {
const y = this.renderCenter.clone().project(this.five.camera);
return [(y.x + 1) / 2 * h.x, (y.y + 1) / 2 * h.y];
} else
return [this.renderCenter.x, h.y - this.renderCenter.y];
})(), f = 1, c = s / t, x = i / t, P = f * t, g = this.five.getPixels(a - c / 2, o - c / 2, c, x, P), m = Math.floor(s * f), u = Math.floor(i * f);
R(g, m, u);
const v = new ImageData(m, u);
v.data.set(g), e.putImageData(v, 0, 0);
}
initStyle() {
const t = this.canvas;
t.classList.add("five-plugin__magnifier"), t.style.position = "absolute", t.style.pointerEvents = "all", t.style.borderRadius = "50%", t.style.zIndex = "99";
const e = 1;
t.setAttribute("width", (this.width * e).toString()), t.setAttribute("height", (this.height * e).toString()), t.style.border = "2px solid rgba(255,255,255,0.20)", t.style.width = this.width + "px", t.style.height = this.height + "px", t.style.top = this.config.initialPosition.top, t.style.left = this.config.initialPosition.left, t.style.transform = "translate(0,0,100px)", this.config.dragEnabled && (this.canvas.style.cursor = "pointer");
}
getPanOffset(t, e) {
const {
min: { x: s, y: i },
max: { x: h, y: a }
} = e, o = this.offset.x + t.deltaX, f = this.offset.y + t.deltaY, c = Math.min(Math.max(o, s), h), x = Math.min(Math.max(f, i), a);
return { translateX: c, translateY: x };
}
}
export {
S as default
};