@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 4.12 kB
JavaScript
import{platform as e}from"../../../core/platform.js";import{EventHandler as t}from"../../../core/event-handler.js";import{Quat as i}from"../../../core/math/quat.js";import{Vec2 as s}from"../../../core/math/vec2.js";import{Vec3 as o}from"../../../core/math/vec3.js";import{ElementComponent as n}from"./component.js";import{Ray as r}from"../../../core/shape/ray.js";import{Plane as a}from"../../../core/shape/plane.js";const h=new s,c=new o,l=new r,_=new a,g=new o,m=new o,d=new i,u={x:"y",y:"x"};class p extends t{constructor(e,t){if(super(),!(e&&e instanceof n))throw new Error("Element was null or not an ElementComponent");if(t&&"x"!==t&&"y"!==t)throw new Error(`Unrecognized axis: ${t}`);this._element=e,this._app=e.system.app,this._axis=t||null,this._enabled=!0,this._dragScale=new o,this._dragStartMousePosition=new o,this._dragStartHandlePosition=new o,this._deltaMousePosition=new o,this._deltaHandlePosition=new o,this._isDragging=!1,this._toggleLifecycleListeners("on")}_toggleLifecycleListeners(e){this._element[e]("mousedown",this._onMouseDownOrTouchStart,this),this._element[e]("touchstart",this._onMouseDownOrTouchStart,this),this._element[e]("selectstart",this._onMouseDownOrTouchStart,this)}_toggleDragListeners(t){const i="on"===t;this._hasDragListeners&&i||(this._app.mouse&&(this._element[t]("mousemove",this._onMove,this),this._element[t]("mouseup",this._onMouseUpOrTouchEnd,this)),e.touch&&(this._element[t]("touchmove",this._onMove,this),this._element[t]("touchend",this._onMouseUpOrTouchEnd,this),this._element[t]("touchcancel",this._onMouseUpOrTouchEnd,this)),this._element[t]("selectmove",this._onMove,this),this._element[t]("selectend",this._onMouseUpOrTouchEnd,this),this._hasDragListeners=i)}_onMouseDownOrTouchStart(e){if(this._element&&!this._isDragging&&this.enabled){this._dragCamera=e.camera,this._calculateDragScale();const t=this._screenToLocal(e);t&&(this._toggleDragListeners("on"),this._isDragging=!0,this._dragStartMousePosition.copy(t),this._dragStartHandlePosition.copy(this._element.entity.getLocalPosition()),this.fire("drag:start"))}}_onMouseUpOrTouchEnd(){this._isDragging&&(this._isDragging=!1,this._toggleDragListeners("off"),this.fire("drag:end"))}_screenToLocal(e){return e.inputSource?l.set(e.inputSource.getOrigin(),e.inputSource.getDirection()):(this._determineInputPosition(e),this._chooseRayOriginAndDirection()),g.copy(this._element.entity.forward).mulScalar(-1),_.setFromPointNormal(this._element.entity.getPosition(),g),_.intersectsRay(l,m)?(d.copy(this._element.entity.getRotation()).invert().transformVector(m,m),m.mul(this._dragScale),m):null}_determineInputPosition(e){const t=this._app.graphicsDevice.maxPixelRatio;void 0!==e.x&&void 0!==e.y?(h.x=e.x*t,h.y=e.y*t):e.changedTouches?(h.x=e.changedTouches[0].x*t,h.y=e.changedTouches[0].y*t):console.warn("Could not determine position from input event")}_chooseRayOriginAndDirection(){this._element.screen&&this._element.screen.screen.screenSpace?(l.origin.set(h.x,-h.y,0),l.direction.copy(o.FORWARD)):(c.copy(this._dragCamera.screenToWorld(h.x,h.y,1)),l.origin.copy(this._dragCamera.entity.getPosition()),l.direction.copy(c).sub(l.origin).normalize())}_calculateDragScale(){let e=this._element.entity.parent;const t=this._element.screen&&this._element.screen.screen,i=t&&t.screenSpace,s=i?t.scale:1,o=this._dragScale;for(o.set(s,s,s);e&&(o.mul(e.getLocalScale()),e=e.parent,!i||!e.screen););o.x=1/o.x,o.y=1/o.y,o.z=0}_onMove(e){const{_element:t,_deltaMousePosition:i,_deltaHandlePosition:s,_axis:o}=this;if(t&&this._isDragging&&this.enabled&&t.enabled&&t.entity.enabled){const n=this._screenToLocal(e);if(n){if(i.sub2(n,this._dragStartMousePosition),s.add2(this._dragStartHandlePosition,i),o){const e=t.entity.getLocalPosition(),i=u[o];s[i]=e[i]}t.entity.setLocalPosition(s),this.fire("drag:move",s)}}}destroy(){this._toggleLifecycleListeners("off"),this._toggleDragListeners("off")}set enabled(e){this._enabled=e}get enabled(){return this._enabled}get isDragging(){return this._isDragging}}p.EVENT_DRAGSTART="drag:start",p.EVENT_DRAGEND="drag:end",p.EVENT_DRAGMOVE="drag:move";export{p as ElementDragHelper};