UNPKG

threepipe

Version:

A modern 3D viewer framework built on top of three.js, written in TypeScript, designed to make creating high-quality, modular, and extensible 3D experiences on the web simple and enjoyable.

150 lines 6.03 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { AViewerPluginSync } from '../../viewer'; import { createDiv, createStyles, getOrCall, onChange } from 'ts-browser-helpers'; import styles from './GeometryUVPreviewPlugin.css?inline'; import { CustomContextMenu } from '../../utils'; import { uiFolderContainer, uiToggle } from 'uiconfig.js'; import { UVsDebug } from 'three/examples/jsm/utils/UVsDebug.js'; let GeometryUVPreviewPlugin = class GeometryUVPreviewPlugin extends AViewerPluginSync { constructor(enabled = true) { super(); this.enabled = true; this.toJSON = null; this.mainDiv = createDiv({ id: 'GeometryUVPreviewPluginContainer', addToBody: false }); this.targetBlocks = []; this._postRender = () => { if (!this._viewer) return; for (const target of this.targetBlocks) { if (!target.visible) continue; const geo = getOrCall(target.target); if (!geo?.attributes?.uv) { // todo draw white or pink continue; } if (!target.uvCanvas) { target.uvCanvas = UVsDebug(geo, 1024); target.uvCanvas.style.width = '100%'; target.uvCanvas.style.height = '100%'; } if (target.uvCanvas && target.uvCanvas.parentElement !== target.div) target.div.appendChild(target.uvCanvas); } }; this.enabled = enabled; } onAdded(viewer) { super.onAdded(viewer); viewer.addEventListener('postRender', this._postRender); this.stylesheet = createStyles(styles, viewer.container); this.refreshUi(); } onRemove(viewer) { viewer.removeEventListener('postRender', this._postRender); this.stylesheet?.remove(); this.stylesheet = undefined; this.refreshUi(); super.onRemove(viewer); } addGeometry(target, name, visible = true) { if (!target) return this; const div = document.createElement('div'); const targetDef = { target, name, div, visible }; div.classList.add('GeometryUVPreviewPluginTarget'); if (!targetDef.visible) div.classList.add('GeometryUVPreviewPluginCollapsed'); const header = document.createElement('div'); header.classList.add('GeometryUVPreviewPluginTargetHeader'); header.innerText = name; header.onclick = () => { targetDef.visible = !targetDef.visible; if (!targetDef.visible) div.classList.add('GeometryUVPreviewPluginCollapsed'); else div.classList.remove('GeometryUVPreviewPluginCollapsed'); this._viewer?.setDirty(); }; header.oncontextmenu = (e) => { e.preventDefault(); e.stopPropagation(); CustomContextMenu.Create({ 'Download': () => this.downloadGeometryUV(targetDef), 'Remove': () => this.removeGeometry(target), }, e.clientX, e.clientY); }; div.appendChild(header); this.mainDiv.appendChild(div); this.targetBlocks.push(targetDef); this.refreshUi(); return this; } removeGeometry(target) { const index = this.targetBlocks.findIndex(t => t.target === target); if (index >= 0) { const t = this.targetBlocks[index]; this.targetBlocks.splice(index, 1); t.div.remove(); } this.refreshUi(); return this; } downloadGeometryUV(targetDef) { if (!this._viewer) return this; if (!targetDef.uvCanvas) return this; const canvas = targetDef.uvCanvas; const url = canvas.toDataURL('image/png'); const link = document.createElement('a'); document.body.appendChild(link); link.style.display = 'none'; link.href = url; link.download = 'renderTarget.' + 'png'; link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); return this; } refreshUi() { if (!this.mainDiv) return; if (!this._viewer) { if (this.mainDiv.parentElement) this.mainDiv.remove(); this.mainDiv.style.display = 'none'; this.mainDiv.style.zIndex = '1000'; return; } if (!this.mainDiv.parentElement) this._viewer.container?.appendChild(this.mainDiv); this.mainDiv.style.display = !this.isDisabled() ? 'flex' : 'none'; this.mainDiv.style.zIndex = parseInt(this._viewer.canvas.style.zIndex || '0') + 1 + ''; this._viewer?.setDirty(); } setDirty() { this.refreshUi(); } dispose() { for (const target of this.targetBlocks) { this.removeGeometry(target.target); } super.dispose(); } }; GeometryUVPreviewPlugin.PluginType = 'GeometryUVPreviewPlugin'; __decorate([ uiToggle('Enabled'), onChange(GeometryUVPreviewPlugin.prototype.refreshUi) ], GeometryUVPreviewPlugin.prototype, "enabled", void 0); GeometryUVPreviewPlugin = __decorate([ uiFolderContainer('Render Target Preview Plugin') ], GeometryUVPreviewPlugin); export { GeometryUVPreviewPlugin }; //# sourceMappingURL=GeometryUVPreviewPlugin.js.map