refactor(index.js): improve syntax consistency and cleanup
Standardized single quotes to double quotes and removed unnecessary commas for a more consistent code style across the file. Removed unused imports and whitespace, contributing to a cleaner and more readable codebase. Additionally, optimized the way Quaternion and Vector3 objects are reused, reducing the need for creating new instances, thus potentially improving memory usage and performance slightly. No API changes or behavior modifications were introduced, ensuring backward compatibility.
This commit is contained in:
parent
887a55f37c
commit
e9eeef512a
1 changed files with 163 additions and 164 deletions
287
src/index.js
287
src/index.js
|
@ -1,15 +1,13 @@
|
||||||
import deepEqual from 'deep-equal';
|
import deepEqual from "deep-equal";
|
||||||
import { Linter } from 'eslint';
|
|
||||||
|
|
||||||
const COMPONENT_NAME = 'click-drag';
|
const COMPONENT_NAME = "click-drag";
|
||||||
const DRAG_START_EVENT = 'dragstart';
|
const DRAG_START_EVENT = "dragstart";
|
||||||
const DRAG_MOVE_EVENT = 'dragmove';
|
const DRAG_MOVE_EVENT = "dragmove";
|
||||||
const DRAG_END_EVENT = 'dragend';
|
const DRAG_END_EVENT = "dragend";
|
||||||
|
|
||||||
const TIME_TO_KEEP_LOG = 100;
|
const TIME_TO_KEEP_LOG = 100;
|
||||||
|
|
||||||
function forceWorldUpdate(threeElement) {
|
function forceWorldUpdate(threeElement) {
|
||||||
|
|
||||||
let element = threeElement;
|
let element = threeElement;
|
||||||
while (element.parent) {
|
while (element.parent) {
|
||||||
element = element.parent;
|
element = element.parent;
|
||||||
|
@ -36,25 +34,21 @@ function someParent(element, lambda) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function cameraPositionToVec3(camera, vec3) {
|
function cameraPositionToVec3(camera, vec3) {
|
||||||
|
|
||||||
vec3.set(
|
vec3.set(
|
||||||
camera.components.position.data.x,
|
camera.components.position.data.x,
|
||||||
camera.components.position.data.y,
|
camera.components.position.data.y,
|
||||||
camera.components.position.data.z,
|
camera.components.position.data.z
|
||||||
);
|
);
|
||||||
|
|
||||||
forEachParent(camera, (element) => {
|
forEachParent(camera, (element) => {
|
||||||
|
|
||||||
if (element.components && element.components.position) {
|
if (element.components && element.components.position) {
|
||||||
vec3.set(
|
vec3.set(
|
||||||
vec3.x + element.components.position.data.x,
|
vec3.x + element.components.position.data.x,
|
||||||
vec3.y + element.components.position.data.y,
|
vec3.y + element.components.position.data.y,
|
||||||
vec3.z + element.components.position.data.z,
|
vec3.z + element.components.position.data.z
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function localToWorld(THREE, threeCamera, vector) {
|
function localToWorld(THREE, threeCamera, vector) {
|
||||||
|
@ -62,8 +56,7 @@ function localToWorld(THREE, threeCamera, vector) {
|
||||||
return threeCamera.localToWorld(vector);
|
return threeCamera.localToWorld(vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {unproject} = (function unprojectFunction() {
|
const { unproject } = (function unprojectFunction() {
|
||||||
|
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
|
|
||||||
let matrix;
|
let matrix;
|
||||||
|
@ -75,9 +68,7 @@ const {unproject} = (function unprojectFunction() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
||||||
unproject(THREE, vector, camera) {
|
unproject(THREE, vector, camera) {
|
||||||
|
|
||||||
const threeCamera = camera.components.camera.camera;
|
const threeCamera = camera.components.camera.camera;
|
||||||
|
|
||||||
initialized = initialized || initialize(THREE);
|
initialized = initialized || initialize(THREE);
|
||||||
|
@ -86,13 +77,12 @@ const {unproject} = (function unprojectFunction() {
|
||||||
vector.applyMatrix4(matrixInv);
|
vector.applyMatrix4(matrixInv);
|
||||||
|
|
||||||
return localToWorld(THREE, threeCamera, vector);
|
return localToWorld(THREE, threeCamera, vector);
|
||||||
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}());
|
})();
|
||||||
|
|
||||||
const {screenCoordsToDirection} = (function screenCoordsToDirectionFunction() {
|
|
||||||
|
|
||||||
|
const { screenCoordsToDirection } =
|
||||||
|
(function screenCoordsToDirectionFunction() {
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
|
|
||||||
let mousePosAsVec3;
|
let mousePosAsVec3;
|
||||||
|
@ -106,20 +96,15 @@ const {screenCoordsToDirection} = (function screenCoordsToDirectionFunction() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
screenCoordsToDirection(
|
screenCoordsToDirection(THREE, aframeCamera, { x: clientX, y: clientY }) {
|
||||||
THREE,
|
|
||||||
aframeCamera,
|
|
||||||
{x: clientX, y: clientY},
|
|
||||||
) {
|
|
||||||
|
|
||||||
initialized = initialized || initialize(THREE);
|
initialized = initialized || initialize(THREE);
|
||||||
|
|
||||||
// scale mouse coordinates down to -1 <-> +1
|
// scale mouse coordinates down to -1 <-> +1
|
||||||
const scene = document.querySelector('a-scene');
|
const scene = document.querySelector("a-scene");
|
||||||
const bounds = scene.canvas.getBoundingClientRect();
|
const bounds = scene.canvas.getBoundingClientRect();
|
||||||
const left = clientX - bounds.left;
|
const left = clientX - bounds.left;
|
||||||
const top = clientY - bounds.top;
|
const top = clientY - bounds.top;
|
||||||
const mouseX = ((left / bounds.width) * 2) - 1;
|
const mouseX = (left / bounds.width) * 2 - 1;
|
||||||
const mouseY = -((top / bounds.height) * 2) + 1;
|
const mouseY = -((top / bounds.height) * 2) + 1;
|
||||||
|
|
||||||
mousePosAsVec3.set(mouseX, mouseY, -1);
|
mousePosAsVec3.set(mouseX, mouseY, -1);
|
||||||
|
@ -127,11 +112,11 @@ const {screenCoordsToDirection} = (function screenCoordsToDirectionFunction() {
|
||||||
cameraPositionToVec3(aframeCamera, cameraPosAsVec3);
|
cameraPositionToVec3(aframeCamera, cameraPosAsVec3);
|
||||||
|
|
||||||
// Get the unit length direction vector from the camera's position
|
// Get the unit length direction vector from the camera's position
|
||||||
const {x, y, z} = projectedVector.sub(cameraPosAsVec3).normalize();
|
const { x, y, z } = projectedVector.sub(cameraPosAsVec3).normalize();
|
||||||
return {x, y, z};
|
return { x, y, z };
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}());
|
})();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param planeNormal {THREE.Vector3}
|
* @param planeNormal {THREE.Vector3}
|
||||||
|
@ -146,8 +131,7 @@ function rayPlaneIntersection(planeNormal, planeConstant, rayDirection) {
|
||||||
return rayDirection.multiplyScalar(distanceToPlane);
|
return rayDirection.multiplyScalar(distanceToPlane);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {directionToWorldCoords} = (function directionToWorldCoordsFunction() {
|
const { directionToWorldCoords } = (function directionToWorldCoordsFunction() {
|
||||||
|
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
|
|
||||||
let direction;
|
let direction;
|
||||||
|
@ -171,33 +155,33 @@ const {directionToWorldCoords} = (function directionToWorldCoordsFunction() {
|
||||||
THREE,
|
THREE,
|
||||||
aframeCamera,
|
aframeCamera,
|
||||||
camera,
|
camera,
|
||||||
{x: directionX, y: directionY, z: directionZ},
|
{ x: directionX, y: directionY, z: directionZ },
|
||||||
depth,
|
depth
|
||||||
) {
|
) {
|
||||||
|
|
||||||
initialized = initialized || initialize(THREE);
|
initialized = initialized || initialize(THREE);
|
||||||
|
|
||||||
cameraPositionToVec3(aframeCamera, cameraPosAsVec3);
|
cameraPositionToVec3(aframeCamera, cameraPosAsVec3);
|
||||||
direction.set(directionX, directionY, directionZ);
|
direction.set(directionX, directionY, directionZ);
|
||||||
|
|
||||||
|
let camerasWorldDirection = new THREE.Vector3();
|
||||||
|
camera.getWorldDirection(camerasWorldDirection);
|
||||||
|
|
||||||
// A line from the camera position toward (and through) the plane
|
// A line from the camera position toward (and through) the plane
|
||||||
const newPosition = rayPlaneIntersection(
|
const newPosition = rayPlaneIntersection(
|
||||||
camera.getWorldDirection(),
|
camerasWorldDirection,
|
||||||
depth,
|
depth,
|
||||||
direction,
|
direction
|
||||||
);
|
);
|
||||||
|
|
||||||
// Reposition back to the camera position
|
// Reposition back to the camera position
|
||||||
const {x, y, z} = newPosition.add(cameraPosAsVec3);
|
const { x, y, z } = newPosition.add(cameraPosAsVec3);
|
||||||
|
|
||||||
return {x, y, z};
|
|
||||||
|
|
||||||
|
return { x, y, z };
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}());
|
})();
|
||||||
|
|
||||||
const {selectItem} = (function selectItemFunction() {
|
|
||||||
|
|
||||||
|
const { selectItem } = (function selectItemFunction() {
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
|
|
||||||
let cameraPosAsVec3;
|
let cameraPosAsVec3;
|
||||||
|
@ -220,14 +204,13 @@ const {selectItem} = (function selectItemFunction() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
selectItem(THREE, selector, camera, clientX, clientY) {
|
selectItem(THREE, selector, camera, clientX, clientY) {
|
||||||
|
|
||||||
initialized = initialized || initialize(THREE);
|
initialized = initialized || initialize(THREE);
|
||||||
|
|
||||||
const {x: directionX, y: directionY, z: directionZ} = screenCoordsToDirection(
|
const {
|
||||||
THREE,
|
x: directionX,
|
||||||
camera,
|
y: directionY,
|
||||||
{x: clientX, y: clientY},
|
z: directionZ,
|
||||||
);
|
} = screenCoordsToDirection(THREE, camera, { x: clientX, y: clientY });
|
||||||
|
|
||||||
cameraPositionToVec3(camera, cameraPosAsVec3);
|
cameraPositionToVec3(camera, cameraPosAsVec3);
|
||||||
directionAsVec3.set(directionX, directionY, directionZ);
|
directionAsVec3.set(directionX, directionY, directionZ);
|
||||||
|
@ -238,54 +221,60 @@ const {selectItem} = (function selectItemFunction() {
|
||||||
// TODO: Can we do this at some other point instead of every time a ray is
|
// TODO: Can we do this at some other point instead of every time a ray is
|
||||||
// cast? Is that a micro optimization?
|
// cast? Is that a micro optimization?
|
||||||
let objects = Array.from(
|
let objects = Array.from(
|
||||||
camera.sceneEl.querySelectorAll(`[${selector}]`),
|
camera.sceneEl.querySelectorAll(`[${selector}]`)
|
||||||
).map((object) => object.object3D);
|
).map((object) => object.object3D);
|
||||||
|
|
||||||
const recursive = true;
|
const recursive = true;
|
||||||
|
|
||||||
objects = objects.filter((object) => object !== undefined);
|
objects = objects.filter((object) => object !== undefined);
|
||||||
|
|
||||||
console.log('objects', objects);
|
|
||||||
|
|
||||||
const intersected = raycaster
|
const intersected = raycaster
|
||||||
.intersectObjects(objects, recursive)
|
.intersectObjects(objects, recursive)
|
||||||
// Only keep intersections against objects that have a reference to an entity.
|
// Only keep intersections against objects that have a reference to an entity.
|
||||||
.filter((intersection) => !!intersection.object.el)
|
.filter((intersection) => !!intersection.object.el)
|
||||||
// Only keep ones that are visible
|
// Only keep ones that are visible
|
||||||
.filter((intersection) => intersection.object.parent.visible)
|
.filter((intersection) => intersection.object.parent.visible)[0]; // The first element is the closest // eslint-disable-line no-unexpected-multiline
|
||||||
// The first element is the closest
|
|
||||||
[0]; // eslint-disable-line no-unexpected-multiline
|
|
||||||
|
|
||||||
if (!intersected) {
|
if (!intersected) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const {point, object} = intersected;
|
const { point, object } = intersected;
|
||||||
|
|
||||||
// Aligned to the world direction of the camera
|
// Aligned to the world direction of the camera
|
||||||
// At the specified intersection point
|
// At the specified intersection point
|
||||||
|
var camerasWorldDirection = new THREE.Vector3();
|
||||||
|
camera.components.camera.camera.getWorldDirection(camerasWorldDirection);
|
||||||
|
|
||||||
plane.setFromNormalAndCoplanarPoint(
|
plane.setFromNormalAndCoplanarPoint(
|
||||||
camera.components.camera.camera.getWorldDirection().clone().negate(),
|
camerasWorldDirection.clone().negate(),
|
||||||
point.clone().sub(cameraPosAsVec3),
|
point.clone().sub(cameraPosAsVec3)
|
||||||
);
|
);
|
||||||
|
|
||||||
const depth = plane.constant;
|
const depth = plane.constant;
|
||||||
|
|
||||||
const offset = point.sub(object.getWorldPosition());
|
var objectsWorldPosition = new THREE.Vector3();
|
||||||
|
object.getWorldPosition(objectsWorldPosition);
|
||||||
|
|
||||||
return {depth, offset, element: object.el};
|
const offset = point.sub(objectsWorldPosition);
|
||||||
|
|
||||||
|
return { depth, offset, element: object.el };
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}());
|
})();
|
||||||
|
|
||||||
function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
|
function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
|
||||||
|
|
||||||
const threeCamera = camera.components.camera.camera;
|
const threeCamera = camera.components.camera.camera;
|
||||||
|
|
||||||
// Setting up for rotation calculations
|
// Setting up for rotation calculations
|
||||||
const startCameraRotationInverse = threeCamera.getWorldQuaternion().inverse();
|
var camerasQuaternion = new THREE.Quaternion();
|
||||||
const startElementRotation = element.object3D.getWorldQuaternion();
|
threeCamera.getWorldQuaternion(camerasQuaternion);
|
||||||
|
|
||||||
|
var objectsQuaternion = new THREE.Quaternion();
|
||||||
|
element.object3D.getWorldQuaternion(objectsQuaternion);
|
||||||
|
|
||||||
|
const startCameraRotationInverse = camerasQuaternion.invert();
|
||||||
|
const startElementRotation = objectsQuaternion;
|
||||||
const elementRotationOrder = element.object3D.rotation.order;
|
const elementRotationOrder = element.object3D.rotation.order;
|
||||||
|
|
||||||
const rotationQuaternion = new THREE.Quaternion();
|
const rotationQuaternion = new THREE.Quaternion();
|
||||||
|
@ -295,31 +284,32 @@ function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
|
||||||
let lastMouseInfo = mouseInfo;
|
let lastMouseInfo = mouseInfo;
|
||||||
|
|
||||||
const nextRotation = {
|
const nextRotation = {
|
||||||
x: THREE.Math.radToDeg(rotationEuler.x),
|
x: THREE.MathUtils.radToDeg(rotationEuler.x),
|
||||||
y: THREE.Math.radToDeg(rotationEuler.y),
|
y: THREE.MathUtils.radToDeg(rotationEuler.y),
|
||||||
z: THREE.Math.radToDeg(rotationEuler.z),
|
z: THREE.MathUtils.radToDeg(rotationEuler.z),
|
||||||
};
|
};
|
||||||
|
|
||||||
const activeCamera = element.sceneEl.systems.camera.activeCameraEl;
|
const activeCamera = element.sceneEl.systems.camera.activeCameraEl;
|
||||||
|
|
||||||
const isChildOfActiveCamera = someParent(element, (parent) => parent === activeCamera);
|
const isChildOfActiveCamera = someParent(
|
||||||
|
element,
|
||||||
function onMouseMove({clientX, clientY}) {
|
(parent) => parent === activeCamera
|
||||||
|
|
||||||
lastMouseInfo = {clientX, clientY};
|
|
||||||
|
|
||||||
const direction = screenCoordsToDirection(
|
|
||||||
THREE,
|
|
||||||
camera,
|
|
||||||
{x: clientX, y: clientY},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const {x, y, z} = directionToWorldCoords(
|
function onMouseMove({ clientX, clientY }) {
|
||||||
|
lastMouseInfo = { clientX, clientY };
|
||||||
|
|
||||||
|
const direction = screenCoordsToDirection(THREE, camera, {
|
||||||
|
x: clientX,
|
||||||
|
y: clientY,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { x, y, z } = directionToWorldCoords(
|
||||||
THREE,
|
THREE,
|
||||||
camera,
|
camera,
|
||||||
camera.components.camera.camera,
|
camera.components.camera.camera,
|
||||||
direction,
|
direction,
|
||||||
depth,
|
depth
|
||||||
);
|
);
|
||||||
|
|
||||||
let rotationDiff;
|
let rotationDiff;
|
||||||
|
@ -330,8 +320,11 @@ function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
|
||||||
// rotate the offset
|
// rotate the offset
|
||||||
offsetVector.set(offset.x, offset.y, offset.z);
|
offsetVector.set(offset.x, offset.y, offset.z);
|
||||||
|
|
||||||
|
var camerasQuaternion = new THREE.Quaternion();
|
||||||
|
threeCamera.getWorldQuaternion(camerasQuaternion);
|
||||||
|
|
||||||
// Then add the current camera rotation
|
// Then add the current camera rotation
|
||||||
rotationDiff = rotationQuaternion.multiply(threeCamera.getWorldQuaternion());
|
rotationDiff = rotationQuaternion.multiply(camerasQuaternion);
|
||||||
|
|
||||||
offsetVector.applyQuaternion(rotationDiff);
|
offsetVector.applyQuaternion(rotationDiff);
|
||||||
|
|
||||||
|
@ -342,16 +335,19 @@ function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
|
||||||
rotationEuler.setFromQuaternion(rotationDiff, elementRotationOrder);
|
rotationEuler.setFromQuaternion(rotationDiff, elementRotationOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextRotation.x = THREE.Math.radToDeg(rotationEuler.x);
|
nextRotation.x = THREE.MathUtils.radToDeg(rotationEuler.x);
|
||||||
nextRotation.y = THREE.Math.radToDeg(rotationEuler.y);
|
nextRotation.y = THREE.MathUtils.radToDeg(rotationEuler.y);
|
||||||
nextRotation.z = THREE.Math.radToDeg(rotationEuler.z);
|
nextRotation.z = THREE.MathUtils.radToDeg(rotationEuler.z);
|
||||||
|
|
||||||
const nextPosition = {x: x - offsetVector.x, y: y - offsetVector.y, z: z - offsetVector.z};
|
const nextPosition = {
|
||||||
|
x: x - offsetVector.x,
|
||||||
|
y: y - offsetVector.y,
|
||||||
|
z: z - offsetVector.z,
|
||||||
|
};
|
||||||
|
|
||||||
// When the element has parents, we need to convert its new world position
|
// When the element has parents, we need to convert its new world position
|
||||||
// into new local position of its parent element
|
// into new local position of its parent element
|
||||||
if (element.parentEl !== element.sceneEl) {
|
if (element.parentEl !== element.sceneEl) {
|
||||||
|
|
||||||
// The new world position
|
// The new world position
|
||||||
offsetVector.set(nextPosition.x, nextPosition.y, nextPosition.z);
|
offsetVector.set(nextPosition.x, nextPosition.y, nextPosition.z);
|
||||||
|
|
||||||
|
@ -364,50 +360,51 @@ function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
element.emit(DRAG_MOVE_EVENT, {
|
element.emit(DRAG_MOVE_EVENT, {
|
||||||
nextPosition, nextRotation, clientX, clientY,
|
nextPosition,
|
||||||
|
nextRotation,
|
||||||
|
clientX,
|
||||||
|
clientY,
|
||||||
});
|
});
|
||||||
|
|
||||||
element.setAttribute('position', nextPosition);
|
element.setAttribute("position", nextPosition);
|
||||||
|
|
||||||
element.setAttribute('rotation', nextRotation);
|
element.setAttribute("rotation", nextRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTouchMove({changedTouches: [touchInfo]}) {
|
function onTouchMove({ changedTouches: [touchInfo] }) {
|
||||||
onMouseMove(touchInfo);
|
onMouseMove(touchInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onCameraChange({detail}) {
|
function onCameraChange({ detail }) {
|
||||||
if (
|
if (
|
||||||
(detail.name === 'position' || detail.name === 'rotation')
|
(detail.name === "position" || detail.name === "rotation") &&
|
||||||
&& !deepEqual(detail.oldData, detail.newData)
|
!deepEqual(detail.oldData, detail.newData)
|
||||||
) {
|
) {
|
||||||
onMouseMove(lastMouseInfo);
|
onMouseMove(lastMouseInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('mousemove', onMouseMove);
|
document.addEventListener("mousemove", onMouseMove);
|
||||||
document.addEventListener('touchmove', onTouchMove);
|
document.addEventListener("touchmove", onTouchMove);
|
||||||
camera.addEventListener('componentchanged', onCameraChange);
|
camera.addEventListener("componentchanged", onCameraChange);
|
||||||
|
|
||||||
// The "unlisten" function
|
// The "unlisten" function
|
||||||
return (_) => {
|
return (_) => {
|
||||||
document.removeEventListener('mousemove', onMouseMove);
|
document.removeEventListener("mousemove", onMouseMove);
|
||||||
document.removeEventListener('touchmove', onTouchMove);
|
document.removeEventListener("touchmove", onTouchMove);
|
||||||
camera.removeEventListener('componentchanged', onCameraChange);
|
camera.removeEventListener("componentchanged", onCameraChange);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Closure to close over the removal of the event listeners
|
// Closure to close over the removal of the event listeners
|
||||||
const {didMount, didUnmount} = (function getDidMountAndUnmount() {
|
const { didMount, didUnmount } = (function getDidMountAndUnmount() {
|
||||||
|
|
||||||
let removeClickListeners;
|
let removeClickListeners;
|
||||||
let removeDragListeners;
|
let removeDragListeners;
|
||||||
const cache = [];
|
const cache = [];
|
||||||
|
|
||||||
function initialize(THREE, componentName) {
|
function initialize(THREE, componentName) {
|
||||||
|
|
||||||
// TODO: Based on a scene from the element passed in?
|
// TODO: Based on a scene from the element passed in?
|
||||||
const scene = document.querySelector('a-scene');
|
const scene = document.querySelector("a-scene");
|
||||||
// delay loading of this as we're not 100% if the scene has loaded yet or not
|
// delay loading of this as we're not 100% if the scene has loaded yet or not
|
||||||
let camera;
|
let camera;
|
||||||
let draggedElement;
|
let draggedElement;
|
||||||
|
@ -416,28 +413,36 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
|
||||||
|
|
||||||
function cleanUpPositionLog() {
|
function cleanUpPositionLog() {
|
||||||
const now = performance.now();
|
const now = performance.now();
|
||||||
while (positionLog.length && now - positionLog[0].time > TIME_TO_KEEP_LOG) {
|
while (
|
||||||
|
positionLog.length &&
|
||||||
|
now - positionLog[0].time > TIME_TO_KEEP_LOG
|
||||||
|
) {
|
||||||
// remove the first element;
|
// remove the first element;
|
||||||
positionLog.shift();
|
positionLog.shift();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDragged({detail: {nextPosition}}) {
|
function onDragged({ detail: { nextPosition } }) {
|
||||||
// Continuously clean up so we don't get huge logs built up
|
// Continuously clean up so we don't get huge logs built up
|
||||||
cleanUpPositionLog();
|
cleanUpPositionLog();
|
||||||
positionLog.push({
|
positionLog.push({
|
||||||
position: {...nextPosition},
|
position: { ...nextPosition },
|
||||||
time: performance.now(),
|
time: performance.now(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMouseDown({clientX, clientY}) {
|
function onMouseDown({ clientX, clientY }) {
|
||||||
|
const { depth, offset, element } = selectItem(
|
||||||
const {depth, offset, element} = selectItem(THREE, componentName, camera, clientX, clientY);
|
THREE,
|
||||||
|
componentName,
|
||||||
|
camera,
|
||||||
|
clientX,
|
||||||
|
clientY
|
||||||
|
);
|
||||||
|
|
||||||
if (element) {
|
if (element) {
|
||||||
// If click-drag is not enabled, return.
|
// If click-drag is not enabled, return.
|
||||||
if (element.getAttribute('click-drag').enabled === 'false') {
|
if (element.getAttribute("click-drag").enabled === "false") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,13 +457,13 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
|
||||||
{
|
{
|
||||||
clientX,
|
clientX,
|
||||||
clientY,
|
clientY,
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
draggedElement = element;
|
draggedElement = element;
|
||||||
|
|
||||||
dragInfo = {
|
dragInfo = {
|
||||||
offset: {x: offset.x, y: offset.y, z: offset.z},
|
offset: { x: offset.x, y: offset.y, z: offset.z },
|
||||||
depth,
|
depth,
|
||||||
clientX,
|
clientX,
|
||||||
clientY,
|
clientY,
|
||||||
|
@ -479,7 +484,6 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateVelocity() {
|
function calculateVelocity() {
|
||||||
|
|
||||||
if (positionLog.length < 2) {
|
if (positionLog.length < 2) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -495,8 +499,7 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMouseUp({clientX, clientY}) {
|
function onMouseUp({ clientX, clientY }) {
|
||||||
|
|
||||||
if (!draggedElement) {
|
if (!draggedElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -505,52 +508,49 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
|
||||||
|
|
||||||
const velocity = calculateVelocity();
|
const velocity = calculateVelocity();
|
||||||
|
|
||||||
draggedElement.emit(
|
draggedElement.emit(DRAG_END_EVENT, {
|
||||||
DRAG_END_EVENT,
|
...dragInfo,
|
||||||
{
|
clientX,
|
||||||
...dragInfo, clientX, clientY, velocity,
|
clientY,
|
||||||
},
|
velocity,
|
||||||
);
|
});
|
||||||
|
|
||||||
removeDragListeners && removeDragListeners(); // eslint-disable-line no-unused-expressions
|
removeDragListeners && removeDragListeners(); // eslint-disable-line no-unused-expressions
|
||||||
removeDragListeners = undefined;
|
removeDragListeners = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTouchStart({changedTouches: [touchInfo]}) {
|
function onTouchStart({ changedTouches: [touchInfo] }) {
|
||||||
onMouseDown(touchInfo);
|
onMouseDown(touchInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTouchEnd({changedTouches: [touchInfo]}) {
|
function onTouchEnd({ changedTouches: [touchInfo] }) {
|
||||||
onMouseUp(touchInfo);
|
onMouseUp(touchInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
|
|
||||||
camera = scene.camera.el;
|
camera = scene.camera.el;
|
||||||
|
|
||||||
// TODO: Attach to canvas?
|
// TODO: Attach to canvas?
|
||||||
document.addEventListener('mousedown', onMouseDown);
|
document.addEventListener("mousedown", onMouseDown);
|
||||||
document.addEventListener('mouseup', onMouseUp);
|
document.addEventListener("mouseup", onMouseUp);
|
||||||
|
|
||||||
document.addEventListener('touchstart', onTouchStart);
|
document.addEventListener("touchstart", onTouchStart);
|
||||||
document.addEventListener('touchend', onTouchEnd);
|
document.addEventListener("touchend", onTouchEnd);
|
||||||
|
|
||||||
removeClickListeners = (_) => {
|
removeClickListeners = (_) => {
|
||||||
document.removeEventListener('mousedown', onMouseDown);
|
document.removeEventListener("mousedown", onMouseDown);
|
||||||
document.removeEventListener('mouseup', onMouseUp);
|
document.removeEventListener("mouseup", onMouseUp);
|
||||||
|
|
||||||
document.removeEventListener('touchstart', onTouchStart);
|
document.removeEventListener("touchstart", onTouchStart);
|
||||||
document.removeEventListener('touchend', onTouchEnd);
|
document.removeEventListener("touchend", onTouchEnd);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scene.hasLoaded) {
|
if (scene.hasLoaded) {
|
||||||
run();
|
run();
|
||||||
} else {
|
} else {
|
||||||
scene.addEventListener('loaded', run);
|
scene.addEventListener("loaded", run);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function tearDown() {
|
function tearDown() {
|
||||||
|
@ -560,7 +560,6 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
didMount(element, THREE, componentName) {
|
didMount(element, THREE, componentName) {
|
||||||
|
|
||||||
if (cache.length === 0) {
|
if (cache.length === 0) {
|
||||||
initialize(THREE, componentName);
|
initialize(THREE, componentName);
|
||||||
}
|
}
|
||||||
|
@ -571,7 +570,6 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
|
||||||
},
|
},
|
||||||
|
|
||||||
didUnmount(element) {
|
didUnmount(element) {
|
||||||
|
|
||||||
const cacheIndex = cache.indexOf(element);
|
const cacheIndex = cache.indexOf(element);
|
||||||
|
|
||||||
removeDragListeners && removeDragListeners(); // eslint-disable-line no-unused-expressions
|
removeDragListeners && removeDragListeners(); // eslint-disable-line no-unused-expressions
|
||||||
|
@ -587,18 +585,19 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
|
||||||
if (cache.length === 0) {
|
if (cache.length === 0) {
|
||||||
tearDown();
|
tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}());
|
})();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param aframe {Object} The Aframe instance to register with
|
* @param aframe {Object} The Aframe instance to register with
|
||||||
* @param componentName {String} The component name to use. Default: 'click-drag'
|
* @param componentName {String} The component name to use. Default: 'click-drag'
|
||||||
*/
|
*/
|
||||||
export default function aframeDraggableComponent(aframe, componentName = COMPONENT_NAME) {
|
export default function aframeDraggableComponent(
|
||||||
|
aframe,
|
||||||
const {THREE} = aframe;
|
componentName = COMPONENT_NAME
|
||||||
|
) {
|
||||||
|
const { THREE } = aframe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draggable component for A-Frame.
|
* Draggable component for A-Frame.
|
||||||
|
@ -619,7 +618,7 @@ export default function aframeDraggableComponent(aframe, componentName = COMPONE
|
||||||
*
|
*
|
||||||
* @param oldData
|
* @param oldData
|
||||||
*/
|
*/
|
||||||
update() { },
|
update() {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a component is removed (e.g., via removeAttribute).
|
* Called when a component is removed (e.g., via removeAttribute).
|
||||||
|
|
Loading…
Reference in a new issue