UNPKG

@evoke-ui/zsort3d

Version:

TypeScript z-plane rendering engine with 3D depth simulation using Canvas 2D and mouse-based navigation

137 lines 4.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Z3DSVG = void 0; const Z3DSortable_1 = require("../core/Z3DSortable"); class Z3DSVG extends Z3DSortable_1.Z3DSortable { constructor(svgContent, width = 50, height = 50, title = '', url = '') { super(); this.svgElement = null; this.containerElement = null; this.cachedImage = null; this.svgContent = svgContent || Z3DSVG.DEFAULT_SVG; this.width = width; this.height = height; this.title = title; this.url = url; this.instanceId = `z3dsvg-${Math.random().toString(36).substr(2, 9)}`; this.createSVGElement(); } createSVGElement() { const parser = new DOMParser(); const doc = parser.parseFromString(this.svgContent, 'image/svg+xml'); this.svgElement = doc.documentElement; if (this.svgElement) { this.updateSVGTransform(); } this.createCachedImage(); } createCachedImage() { const cacheKey = btoa(this.svgContent); if (Z3DSVG.imageCache.has(cacheKey)) { this.cachedImage = Z3DSVG.imageCache.get(cacheKey); return; } const img = new Image(); const svgDataUrl = `data:image/svg+xml;base64,${cacheKey}`; img.onload = () => { Z3DSVG.imageCache.set(cacheKey, img); this.cachedImage = img; }; img.src = svgDataUrl; } updateSVGTransform() { if (!this.svgElement) return; this.svgElement.style.position = 'absolute'; this.svgElement.style.left = `${this.x - (this.width * this.scaleX) / 2}px`; this.svgElement.style.top = `${this.y - (this.height * this.scaleY) / 2}px`; this.svgElement.style.transform = `scale(${this.scaleX}, ${this.scaleY})`; this.svgElement.style.opacity = this.alpha.toString(); this.svgElement.style.transformOrigin = 'center center'; } render(ctx) { if (!this.cachedImage) return; const scaledWidth = this.width * this.scaleX; const scaledHeight = this.height * this.scaleY; ctx.save(); ctx.globalAlpha = this.alpha; ctx.drawImage(this.cachedImage, this.x - scaledWidth / 2, this.y - scaledHeight / 2, scaledWidth, scaledHeight); ctx.restore(); } setSVGContent(svgContent) { this.svgContent = svgContent; this.createSVGElement(); } getSVGContent() { return this.svgContent; } getInstanceId() { return this.instanceId; } addEventListener(canvas, handler) { this.clickHandler = (e) => { const rect = canvas.getBoundingClientRect(); const mouseX = e.clientX - rect.left; const mouseY = e.clientY - rect.top; const scaledWidth = this.width * this.scaleX; const scaledHeight = this.height * this.scaleY; const left = this.x - scaledWidth / 2; const top = this.y - scaledHeight / 2; if (mouseX >= left && mouseX <= left + scaledWidth && mouseY >= top && mouseY <= top + scaledHeight) { handler(e); } }; canvas.addEventListener('click', this.clickHandler); } removeEventListener(canvas) { if (this.clickHandler) { canvas.removeEventListener('click', this.clickHandler); this.clickHandler = undefined; } } addTouchEventListener(handler) { this.touchHandler = handler; } removeTouchEventListener() { this.touchHandler = undefined; } checkTouchHit(touchData) { if (!touchData.center) return false; const touchX = touchData.center.x; const touchY = touchData.center.y; const scaledWidth = this.width * this.scaleX; const scaledHeight = this.height * this.scaleY; const left = this.x - scaledWidth / 2; const top = this.y - scaledHeight / 2; return touchX >= left && touchX <= left + scaledWidth && touchY >= top && touchY <= top + scaledHeight; } handleTouchEvent(data) { if (!this.touchHandler || !this.checkTouchHit(data)) { return false; } this.touchHandler(data); return true; } getTouchHandler() { return this.touchHandler; } destroy() { super.destroy(); this.svgElement = null; this.containerElement = null; this.clickHandler = undefined; this.touchHandler = undefined; } } exports.Z3DSVG = Z3DSVG; Z3DSVG.imageCache = new Map(); Z3DSVG.DEFAULT_SVG = ` <svg width="50" height="50" xmlns="http://www.w3.org/2000/svg"> <circle cx="25" cy="25" r="20" fill="#FF6B6B" stroke="#333" stroke-width="2"/> </svg> `; //# sourceMappingURL=Z3DSVG.js.map