UNPKG

@mlightcad/three-viewcube

Version:

A highly customizable standalone view cube addon for three.js

266 lines 11.9 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; import * as THREE from 'three'; import { DEFAULT_FACENAMES } from './faceNames'; import { FACES } from './viewCubeData'; import { ViewCube } from './viewCube'; import { FixedPosGizmo, ObjectPosition } from './fixedPosGizmo'; var MAIN_COLOR = 0xdddddd; var HOVER_COLOR = 0xf2f5ce; var OUTLINE_COLOR = 0xcccccc; /** * Default view cube option values */ export var DEFAULT_VIEWCUBE_OPTIONS = { pos: ObjectPosition.RIGHT_TOP, dimension: 150, faceColor: MAIN_COLOR, hoverColor: HOVER_COLOR, outlineColor: OUTLINE_COLOR, faceNames: DEFAULT_FACENAMES, fontSize: 60, }; /** * A highly customizable standalone view cube gizmo for three.js. */ var ViewCubeGizmo = /** @class */ (function (_super) { __extends(ViewCubeGizmo, _super); /** * Construct one instance of view cube gizmo * @param camera Camera used in your canvas * @param renderer Renderer used in your canvas * @param options Options to customize view cube gizmo */ function ViewCubeGizmo(camera, renderer, options) { if (options === void 0) { options = DEFAULT_VIEWCUBE_OPTIONS; } var _this = this; var mergedOptions = __assign(__assign({}, DEFAULT_VIEWCUBE_OPTIONS), options); _this = _super.call(this, camera, renderer, options.dimension, options.pos) || this; _this.cube = new ViewCube(2, 0.2, true, mergedOptions.faceColor, mergedOptions.outlineColor, mergedOptions.faceNames, mergedOptions.fontSize); _this.add(_this.cube); _this.handleMouseMove = _this.handleMouseMove.bind(_this); _this.handleMouseClick = _this.handleMouseClick.bind(_this); _this.listen(renderer.domElement); return _this; } /** * Free the GPU-related resources allocated by this instance. Call this method whenever this instance * is no longer used in your app. */ ViewCubeGizmo.prototype.dispose = function () { this.cube.dispose(); }; ViewCubeGizmo.prototype.listen = function (domElement) { domElement.addEventListener('mousemove', this.handleMouseMove); domElement.addEventListener('click', this.handleMouseClick); }; ViewCubeGizmo.prototype.handleMouseClick = function (event) { var bbox = this.calculateViewportBbox(); if (bbox.containsPoint(new THREE.Vector2(event.offsetX, event.offsetY))) { var pos = this.calculatePosInViewport(event.offsetX, event.offsetY, bbox); this.checkSideTouch(pos.x, pos.y); } }; ViewCubeGizmo.prototype.handleMouseMove = function (event) { var bbox = this.calculateViewportBbox(); if (bbox.containsPoint(new THREE.Vector2(event.offsetX, event.offsetY))) { var pos = this.calculatePosInViewport(event.offsetX, event.offsetY, bbox); this.checkSideOver(pos.x, pos.y); } }; ViewCubeGizmo.prototype.checkSideTouch = function (x, y) { var e_1, _a; var raycaster = new THREE.Raycaster(); raycaster.setFromCamera(new THREE.Vector2(x, y), this.gizmoCamera); var intersects = raycaster.intersectObjects(this.cube.children, true); if (intersects.length) { try { for (var intersects_1 = __values(intersects), intersects_1_1 = intersects_1.next(); !intersects_1_1.done; intersects_1_1 = intersects_1.next()) { var object = intersects_1_1.value.object; if (object.name) { var quaternion = this.getRotation(object.name); this.dispatchEvent({ type: 'change', quaternion: quaternion }); break; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (intersects_1_1 && !intersects_1_1.done && (_a = intersects_1.return)) _a.call(intersects_1); } finally { if (e_1) throw e_1.error; } } } }; ViewCubeGizmo.prototype.checkSideOver = function (x, y) { var e_2, _a; var raycaster = new THREE.Raycaster(); raycaster.setFromCamera(new THREE.Vector2(x, y), this.gizmoCamera); var intersects = raycaster.intersectObjects(this.cube.children, true); // unhover this.cube.traverse(function (obj) { if (obj.name) { var mesh = obj; mesh.material.color.setHex(MAIN_COLOR); } }); // check hover if (intersects.length) { var _loop_1 = function (object) { if (object.name) { object.parent.children.forEach(function (child) { if (child.name === object.name) { var mesh = child; mesh.material.color.setHex(HOVER_COLOR); } }); return "break"; } }; try { for (var intersects_2 = __values(intersects), intersects_2_1 = intersects_2.next(); !intersects_2_1.done; intersects_2_1 = intersects_2.next()) { var object = intersects_2_1.value.object; var state_1 = _loop_1(object); if (state_1 === "break") break; } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (intersects_2_1 && !intersects_2_1.done && (_a = intersects_2.return)) _a.call(intersects_2); } finally { if (e_2) throw e_2.error; } } } }; ViewCubeGizmo.prototype.getRotation = function (side) { var targetQuaternion = new THREE.Quaternion(); switch (side) { case FACES.FRONT: targetQuaternion.setFromEuler(new THREE.Euler()); break; case FACES.RIGHT: targetQuaternion.setFromEuler(new THREE.Euler(0, Math.PI * 0.5, 0)); break; case FACES.BACK: targetQuaternion.setFromEuler(new THREE.Euler(0, Math.PI, 0)); break; case FACES.LEFT: targetQuaternion.setFromEuler(new THREE.Euler(0, -Math.PI * 0.5, 0)); break; case FACES.TOP: targetQuaternion.setFromEuler(new THREE.Euler(-Math.PI * 0.5, 0, 0)); break; case FACES.BOTTOM: targetQuaternion.setFromEuler(new THREE.Euler(Math.PI * 0.5, 0, 0)); break; case FACES.TOP_FRONT_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(-Math.PI * 0.25, 0, 0)); break; case FACES.TOP_RIGHT_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(-Math.PI * 0.25, Math.PI * 0.5, 0, 'YXZ')); break; case FACES.TOP_BACK_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(-Math.PI * 0.25, Math.PI, 0, 'YXZ')); break; case FACES.TOP_LEFT_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(-Math.PI * 0.25, -Math.PI * 0.5, 0, 'YXZ')); break; case FACES.BOTTOM_FRONT_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(Math.PI * 0.25, 0, 0)); break; case FACES.BOTTOM_RIGHT_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(Math.PI * 0.25, Math.PI * 0.5, 0, 'YXZ')); break; case FACES.BOTTOM_BACK_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(Math.PI * 0.25, Math.PI, 0, 'YXZ')); break; case FACES.BOTTOM_LEFT_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(Math.PI * 0.25, -Math.PI * 0.5, 0, 'YXZ')); break; case FACES.FRONT_RIGHT_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(0, Math.PI * 0.25, 0)); break; case FACES.BACK_RIGHT_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(0, Math.PI * 0.75, 0)); break; case FACES.BACK_LEFT_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(0, -Math.PI * 0.75, 0)); break; case FACES.FRONT_LEFT_EDGE: targetQuaternion.setFromEuler(new THREE.Euler(0, -Math.PI * 0.25, 0)); break; case FACES.TOP_FRONT_RIGHT_CORNER: targetQuaternion.setFromEuler(new THREE.Euler(-Math.PI * 0.25, -Math.PI * 1.75, 0)); break; case FACES.TOP_BACK_RIGHT_CORNER: targetQuaternion.setFromEuler(new THREE.Euler(Math.PI * 0.25, -Math.PI * 1.25, 0)); break; case FACES.TOP_BACK_LEFT_CORNER: targetQuaternion.setFromEuler(new THREE.Euler(Math.PI * 0.25, -Math.PI * 0.75, 0)); break; case FACES.TOP_FRONT_LEFT_CORNER: targetQuaternion.setFromEuler(new THREE.Euler(-Math.PI * 0.25, -Math.PI * 0.25, 0)); break; case FACES.BOTTOM_FRONT_RIGHT_CORNER: targetQuaternion.setFromEuler(new THREE.Euler(Math.PI * 0.25, -Math.PI * 1.75, 0)); break; case FACES.BOTTOM_BACK_RIGHT_CORNER: targetQuaternion.setFromEuler(new THREE.Euler(-Math.PI * 0.25, -Math.PI * 1.25, 0)); break; case FACES.BOTTOM_BACK_LEFT_CORNER: targetQuaternion.setFromEuler(new THREE.Euler(-Math.PI * 0.25, -Math.PI * 0.75, 0)); break; case FACES.BOTTOM_FRONT_LEFT_CORNER: targetQuaternion.setFromEuler(new THREE.Euler(Math.PI * 0.25, -Math.PI * 0.25, 0)); break; default: console.error("[ViewCubeGizmo]: Invalid face, edge, or corner name '".concat(side, "'!")); break; } return targetQuaternion; }; return ViewCubeGizmo; }(FixedPosGizmo)); export { ViewCubeGizmo }; //# sourceMappingURL=viewCubeGizmo.js.map