cubing.js
cubing.js copied to clipboard
Drag/touch move input
In principle (and as suggested by three.js demos), it's not hard to capture mouse/touch events and use them to animate moves on the cube. I think the main issue here is handling the in-between animation while someone is moving a layer.
Should include:
- rendering the (partial) move, with live updating
- good mobile support
- needs to interact with touch support from the
touch
branch.
- needs to interact with touch support from the
I am going to work on adding this feature. Here's how it works in the Cuber project (and now ThreeTwist):
- Calculate the cube's bounding box within the cube's coordinate system, and save it as a Box3.
- Use the cube's
.matrixWorld
property and the current camera to somehow create a "mouse ray". I'm not completely sure how this works but I know that the code for this is in Cuber's projector.js file, so I can reference that. - Find the intersection point of the cube and the ray.
- Using that intersection point, figure out which face was clicked. Save a reference to that face's THREE.Plane.
- Set some kind of flag such as "interacting" to true, until the mouse is released.
- If the mouse moved, find its intersection on the face's THREE.Plane using a technique similar to step 2.
- Calculate the
direction
vector, which is the difference between the current ray/plane intersection and the initial intersection point. - Take the cross product of the direction and the face's axis (the THREE.Plane's
.normal
property). This is the approximate axis of rotation. - "Snap" the axis of rotation to one of the cube's six axes. For the cube, I just did this by finding the axis with the closest axis vector. There may be more efficient methods.
- Calculate the "sliding axis" using a cross product. It is the axis that is parallel to the plane, perpendicular to the rotation axis, and points in the same direction as the direction vector.
- The angle of rotation is proportional to the magnitude of the direction vector projected onto the sliding axis. This can be calculated using a dot product. There may be other ways to calculate an "angle", but this one works well.
I am going to work on adding this feature.
You're welcome to try. :-)
However, the code is very old and badly designed. I'm hoping to restructure it at a hackathon some time (the core part was written at a hackathon 5 years ago(!)), but I guess it doesn't hurt to add yet. Thanks for your description of how to handler it. :-)