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:
Kumi 2024-03-27 18:30:26 +01:00
parent 887a55f37c
commit e9eeef512a
Signed by: kumi
GPG key ID: ECBCC9082395383F

View file

@ -1,15 +1,13 @@
import deepEqual from 'deep-equal';
import { Linter } from 'eslint';
import deepEqual from "deep-equal";
const COMPONENT_NAME = 'click-drag';
const DRAG_START_EVENT = 'dragstart';
const DRAG_MOVE_EVENT = 'dragmove';
const DRAG_END_EVENT = 'dragend';
const COMPONENT_NAME = "click-drag";
const DRAG_START_EVENT = "dragstart";
const DRAG_MOVE_EVENT = "dragmove";
const DRAG_END_EVENT = "dragend";
const TIME_TO_KEEP_LOG = 100;
function forceWorldUpdate(threeElement) {
let element = threeElement;
while (element.parent) {
element = element.parent;
@ -36,25 +34,21 @@ function someParent(element, lambda) {
}
function cameraPositionToVec3(camera, vec3) {
vec3.set(
camera.components.position.data.x,
camera.components.position.data.y,
camera.components.position.data.z,
camera.components.position.data.z
);
forEachParent(camera, (element) => {
if (element.components && element.components.position) {
vec3.set(
vec3.x + element.components.position.data.x,
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) {
@ -63,7 +57,6 @@ function localToWorld(THREE, threeCamera, vector) {
}
const { unproject } = (function unprojectFunction() {
let initialized = false;
let matrix;
@ -75,9 +68,7 @@ const {unproject} = (function unprojectFunction() {
}
return {
unproject(THREE, vector, camera) {
const threeCamera = camera.components.camera.camera;
initialized = initialized || initialize(THREE);
@ -86,13 +77,12 @@ const {unproject} = (function unprojectFunction() {
vector.applyMatrix4(matrixInv);
return localToWorld(THREE, threeCamera, vector);
},
};
}());
const {screenCoordsToDirection} = (function screenCoordsToDirectionFunction() {
})();
const { screenCoordsToDirection } =
(function screenCoordsToDirectionFunction() {
let initialized = false;
let mousePosAsVec3;
@ -106,20 +96,15 @@ const {screenCoordsToDirection} = (function screenCoordsToDirectionFunction() {
}
return {
screenCoordsToDirection(
THREE,
aframeCamera,
{x: clientX, y: clientY},
) {
screenCoordsToDirection(THREE, aframeCamera, { x: clientX, y: clientY }) {
initialized = initialized || initialize(THREE);
// 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 left = clientX - bounds.left;
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;
mousePosAsVec3.set(mouseX, mouseY, -1);
@ -131,7 +116,7 @@ const {screenCoordsToDirection} = (function screenCoordsToDirectionFunction() {
return { x, y, z };
},
};
}());
})();
/**
* @param planeNormal {THREE.Vector3}
@ -147,7 +132,6 @@ function rayPlaneIntersection(planeNormal, planeConstant, rayDirection) {
}
const { directionToWorldCoords } = (function directionToWorldCoordsFunction() {
let initialized = false;
let direction;
@ -172,32 +156,32 @@ const {directionToWorldCoords} = (function directionToWorldCoordsFunction() {
aframeCamera,
camera,
{ x: directionX, y: directionY, z: directionZ },
depth,
depth
) {
initialized = initialized || initialize(THREE);
cameraPositionToVec3(aframeCamera, cameraPosAsVec3);
direction.set(directionX, directionY, directionZ);
let camerasWorldDirection = new THREE.Vector3();
camera.getWorldDirection(camerasWorldDirection);
// A line from the camera position toward (and through) the plane
const newPosition = rayPlaneIntersection(
camera.getWorldDirection(),
camerasWorldDirection,
depth,
direction,
direction
);
// Reposition back to the camera position
const { x, y, z } = newPosition.add(cameraPosAsVec3);
return { x, y, z };
},
};
}());
})();
const { selectItem } = (function selectItemFunction() {
let initialized = false;
let cameraPosAsVec3;
@ -220,14 +204,13 @@ const {selectItem} = (function selectItemFunction() {
return {
selectItem(THREE, selector, camera, clientX, clientY) {
initialized = initialized || initialize(THREE);
const {x: directionX, y: directionY, z: directionZ} = screenCoordsToDirection(
THREE,
camera,
{x: clientX, y: clientY},
);
const {
x: directionX,
y: directionY,
z: directionZ,
} = screenCoordsToDirection(THREE, camera, { x: clientX, y: clientY });
cameraPositionToVec3(camera, cameraPosAsVec3);
directionAsVec3.set(directionX, directionY, directionZ);
@ -238,23 +221,19 @@ const {selectItem} = (function selectItemFunction() {
// TODO: Can we do this at some other point instead of every time a ray is
// cast? Is that a micro optimization?
let objects = Array.from(
camera.sceneEl.querySelectorAll(`[${selector}]`),
camera.sceneEl.querySelectorAll(`[${selector}]`)
).map((object) => object.object3D);
const recursive = true;
objects = objects.filter((object) => object !== undefined);
console.log('objects', objects);
const intersected = raycaster
.intersectObjects(objects, recursive)
// Only keep intersections against objects that have a reference to an entity.
.filter((intersection) => !!intersection.object.el)
// Only keep ones that are visible
.filter((intersection) => intersection.object.parent.visible)
// The first element is the closest
[0]; // eslint-disable-line no-unexpected-multiline
.filter((intersection) => intersection.object.parent.visible)[0]; // The first element is the closest // eslint-disable-line no-unexpected-multiline
if (!intersected) {
return {};
@ -264,28 +243,38 @@ const {selectItem} = (function selectItemFunction() {
// Aligned to the world direction of the camera
// At the specified intersection point
var camerasWorldDirection = new THREE.Vector3();
camera.components.camera.camera.getWorldDirection(camerasWorldDirection);
plane.setFromNormalAndCoplanarPoint(
camera.components.camera.camera.getWorldDirection().clone().negate(),
point.clone().sub(cameraPosAsVec3),
camerasWorldDirection.clone().negate(),
point.clone().sub(cameraPosAsVec3)
);
const depth = plane.constant;
const offset = point.sub(object.getWorldPosition());
var objectsWorldPosition = new THREE.Vector3();
object.getWorldPosition(objectsWorldPosition);
const offset = point.sub(objectsWorldPosition);
return { depth, offset, element: object.el };
},
};
}());
})();
function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
const threeCamera = camera.components.camera.camera;
// Setting up for rotation calculations
const startCameraRotationInverse = threeCamera.getWorldQuaternion().inverse();
const startElementRotation = element.object3D.getWorldQuaternion();
var camerasQuaternion = new THREE.Quaternion();
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 rotationQuaternion = new THREE.Quaternion();
@ -295,31 +284,32 @@ function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
let lastMouseInfo = mouseInfo;
const nextRotation = {
x: THREE.Math.radToDeg(rotationEuler.x),
y: THREE.Math.radToDeg(rotationEuler.y),
z: THREE.Math.radToDeg(rotationEuler.z),
x: THREE.MathUtils.radToDeg(rotationEuler.x),
y: THREE.MathUtils.radToDeg(rotationEuler.y),
z: THREE.MathUtils.radToDeg(rotationEuler.z),
};
const activeCamera = element.sceneEl.systems.camera.activeCameraEl;
const isChildOfActiveCamera = someParent(element, (parent) => parent === activeCamera);
const isChildOfActiveCamera = someParent(
element,
(parent) => parent === activeCamera
);
function onMouseMove({ clientX, clientY }) {
lastMouseInfo = { clientX, clientY };
const direction = screenCoordsToDirection(
THREE,
camera,
{x: clientX, y: clientY},
);
const direction = screenCoordsToDirection(THREE, camera, {
x: clientX,
y: clientY,
});
const { x, y, z } = directionToWorldCoords(
THREE,
camera,
camera.components.camera.camera,
direction,
depth,
depth
);
let rotationDiff;
@ -330,8 +320,11 @@ function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
// rotate the offset
offsetVector.set(offset.x, offset.y, offset.z);
var camerasQuaternion = new THREE.Quaternion();
threeCamera.getWorldQuaternion(camerasQuaternion);
// Then add the current camera rotation
rotationDiff = rotationQuaternion.multiply(threeCamera.getWorldQuaternion());
rotationDiff = rotationQuaternion.multiply(camerasQuaternion);
offsetVector.applyQuaternion(rotationDiff);
@ -342,16 +335,19 @@ function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
rotationEuler.setFromQuaternion(rotationDiff, elementRotationOrder);
}
nextRotation.x = THREE.Math.radToDeg(rotationEuler.x);
nextRotation.y = THREE.Math.radToDeg(rotationEuler.y);
nextRotation.z = THREE.Math.radToDeg(rotationEuler.z);
nextRotation.x = THREE.MathUtils.radToDeg(rotationEuler.x);
nextRotation.y = THREE.MathUtils.radToDeg(rotationEuler.y);
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
// into new local position of its parent element
if (element.parentEl !== element.sceneEl) {
// The new world position
offsetVector.set(nextPosition.x, nextPosition.y, nextPosition.z);
@ -364,12 +360,15 @@ function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
}
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] }) {
@ -378,36 +377,34 @@ function dragItem(THREE, element, offset, camera, depth, mouseInfo) {
function onCameraChange({ detail }) {
if (
(detail.name === 'position' || detail.name === 'rotation')
&& !deepEqual(detail.oldData, detail.newData)
(detail.name === "position" || detail.name === "rotation") &&
!deepEqual(detail.oldData, detail.newData)
) {
onMouseMove(lastMouseInfo);
}
}
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('touchmove', onTouchMove);
camera.addEventListener('componentchanged', onCameraChange);
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("touchmove", onTouchMove);
camera.addEventListener("componentchanged", onCameraChange);
// The "unlisten" function
return (_) => {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('touchmove', onTouchMove);
camera.removeEventListener('componentchanged', onCameraChange);
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("touchmove", onTouchMove);
camera.removeEventListener("componentchanged", onCameraChange);
};
}
// Closure to close over the removal of the event listeners
const { didMount, didUnmount } = (function getDidMountAndUnmount() {
let removeClickListeners;
let removeDragListeners;
const cache = [];
function initialize(THREE, componentName) {
// 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
let camera;
let draggedElement;
@ -416,7 +413,10 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
function cleanUpPositionLog() {
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;
positionLog.shift();
}
@ -432,12 +432,17 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
}
function onMouseDown({ clientX, clientY }) {
const {depth, offset, element} = selectItem(THREE, componentName, camera, clientX, clientY);
const { depth, offset, element } = selectItem(
THREE,
componentName,
camera,
clientX,
clientY
);
if (element) {
// If click-drag is not enabled, return.
if (element.getAttribute('click-drag').enabled === 'false') {
if (element.getAttribute("click-drag").enabled === "false") {
return;
}
@ -452,7 +457,7 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
{
clientX,
clientY,
},
}
);
draggedElement = element;
@ -479,7 +484,6 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
}
function calculateVelocity() {
if (positionLog.length < 2) {
return 0;
}
@ -496,7 +500,6 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
}
function onMouseUp({ clientX, clientY }) {
if (!draggedElement) {
return;
}
@ -505,12 +508,12 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
const velocity = calculateVelocity();
draggedElement.emit(
DRAG_END_EVENT,
{
...dragInfo, clientX, clientY, velocity,
},
);
draggedElement.emit(DRAG_END_EVENT, {
...dragInfo,
clientX,
clientY,
velocity,
});
removeDragListeners && removeDragListeners(); // eslint-disable-line no-unused-expressions
removeDragListeners = undefined;
@ -525,32 +528,29 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
}
function run() {
camera = scene.camera.el;
// TODO: Attach to canvas?
document.addEventListener('mousedown', onMouseDown);
document.addEventListener('mouseup', onMouseUp);
document.addEventListener("mousedown", onMouseDown);
document.addEventListener("mouseup", onMouseUp);
document.addEventListener('touchstart', onTouchStart);
document.addEventListener('touchend', onTouchEnd);
document.addEventListener("touchstart", onTouchStart);
document.addEventListener("touchend", onTouchEnd);
removeClickListeners = (_) => {
document.removeEventListener('mousedown', onMouseDown);
document.removeEventListener('mouseup', onMouseUp);
document.removeEventListener("mousedown", onMouseDown);
document.removeEventListener("mouseup", onMouseUp);
document.removeEventListener('touchstart', onTouchStart);
document.removeEventListener('touchend', onTouchEnd);
document.removeEventListener("touchstart", onTouchStart);
document.removeEventListener("touchend", onTouchEnd);
};
}
if (scene.hasLoaded) {
run();
} else {
scene.addEventListener('loaded', run);
scene.addEventListener("loaded", run);
}
}
function tearDown() {
@ -560,7 +560,6 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
return {
didMount(element, THREE, componentName) {
if (cache.length === 0) {
initialize(THREE, componentName);
}
@ -571,7 +570,6 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
},
didUnmount(element) {
const cacheIndex = cache.indexOf(element);
removeDragListeners && removeDragListeners(); // eslint-disable-line no-unused-expressions
@ -587,17 +585,18 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
if (cache.length === 0) {
tearDown();
}
},
};
}());
})();
/**
* @param aframe {Object} The Aframe instance to register with
* @param componentName {String} The component name to use. Default: 'click-drag'
*/
export default function aframeDraggableComponent(aframe, componentName = COMPONENT_NAME) {
export default function aframeDraggableComponent(
aframe,
componentName = COMPONENT_NAME
) {
const { THREE } = aframe;
/**