import AFRAME from 'aframe' const THREE = AFRAME.THREE export const ComponentName = 'arrow' export interface ArrowData { [key: string]: any, x: number, y: number, z: number, direction: string, angle: number, width: number height: number depth: number color: number, opacity: number disabledopacity: number } export const ArrowComponentSchema: AFRAME.MultiPropertySchema = { x: { type: 'number', default: 0 }, y: { type: 'number', default: 0 }, z: { type: 'number', default: 0 }, direction: { default: 'up' }, // oneOf: ['left', 'right', 'up', 'down', 'angle'] angle: { type: 'number', default: 0 }, width: { type: 'number', default: 1 }, height: { type: 'number', default: 1 }, depth: { type: 'number', default: 0.01 }, color: { default: 0xe8f1ff }, opacity: { type: 'number', default: 1 }, disabledopacity: { type: 'number', default: 0.2 } } export interface Props { createArrow: () => void, } export const ArrowComponent: AFRAME.ComponentDefinition = { schema: ArrowComponentSchema, data: { } as ArrowData, // dependencies: ['highlight'], init: function() { if (this.el.sceneEl?.hasLoaded) this.createArrow() else this.el.sceneEl?.addEventListener('loaded', this.createArrow.bind(this)) }, update: function(oldData: ArrowData) { const changedData = Object.keys(this.data).filter(x => this.data[x] !== oldData[x]) if (changedData.includes('disabled') && !!this.el.getAttribute('highlight')) { this.el.setAttribute('highlight', { disabled: this.data.disabled }) } }, remove: function () { // eslint-disable-next-line no-prototype-builtins if (this.el.object3DMap.hasOwnProperty('mesh')) { this.el.removeObject3D('mesh') } }, createArrow() { const self = this const data = self.data data.offset = { x: 0 + data.x, y: 0 + data.y, z: 0 + data.z } const shape = new THREE.Shape() const width = data.width const height = data.height shape.moveTo(0, height / 2) shape.lineTo(width / 2, -height / 2) shape.lineTo(-width / 2, -height / 2) shape.lineTo(0, height / 2) const geom = new THREE.ShapeBufferGeometry(shape) let rotationZ = data.angle switch (data.direction) { case 'up': break case 'left': rotationZ = 90 break case 'down': rotationZ = 180 break case 'right': rotationZ = -90 break default: break } geom.rotateZ(2 * Math.PI * rotationZ / 360) geom.translate(data.offset.x, data.offset.y, data.offset.z) // var color = data.color const opacity = data.disabled ? data.disabledopacity : data.opacity const transparent = !!data.disabled const mat = new THREE.MeshBasicMaterial({ // color: new THREE.Color(color), transparent: transparent, opacity: opacity, side: THREE.DoubleSide }) const mesh = new THREE.Mesh(geom, mat) mesh.name = 'arrow' self.el.setObject3D('mesh', mesh) } } export const ArrowPrimitive: AFRAME.PrimitiveDefinition = { defaultComponents: { ComponentName: {} // 'highlight': { // type: 'color', // borderbaseopacity: 0.7, // disabledopacity: 0.2, // color: 0xe8f1ff, // } }, mappings: { direction: ComponentName + '.direction', color: ComponentName + '.color', width: ComponentName + '.width', height: ComponentName + '.height' // hover: 'highlight.hover', // active: 'highlight.active', // disabled: 'highlight.disabled', // hovercolor: 'highlight.hoverColor', // activecolor: 'highlight.activeColor' } } const ComponentSystem = { name: ComponentName, // system: ArrowSystemDef, component: ArrowComponent, primitive: ArrowPrimitive } export default ComponentSystem