Chain linking animations with aframe.io - animation

Is there a way to chainlink an animation in aframe? I am trying to once clicked move a cube to a position, hold that position for x amount of time, then animate back to the original spot.
So far I have just 2 animations the second is beginning when listening for an animationend event. Problem is, then both animations emit an animationend which in turn triggers the second animation over and over. This approach doesn't seem to be right
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Curved Images</title>
<meta name="description" content="Curved Images - A-Frame">
<script src="https://aframe.io/releases/0.2.0/aframe.min.js"></script>
</head>
<body>
<a-scene>
<a-entity position="0 1.8 4">
<a-entity camera look-controls wasd-controls>
<a-entity position="0 0 -3"
geometry="primitive: ring; radiusOuter: 0.30;
radiusInner: 0.20;"
material="color: cyan; shader: flat"
cursor="maxDistance: 30; fuse: true">
<a-animation begin="click" easing="ease-in" attribute="scale"
fill="backwards" from="0.1 0.1 0.1" to="1 1 1" dur="150"></a-animation>
<a-animation begin="fusing" easing="ease-in" attribute="scale"
fill="forwards" from="1 1 1" to="0.1 0.1 0.1" dur="1500"></a-animation>
</a-entity>
</a-entity>
</a-entity>
<a-box id="orange-cube" position="0 3.5 -2" rotation="30 30 0" width="2" depth="2"
height="2" color="#583C87" roughness="0.8">
<a-animation begin="click" attribute="position" from="0 3.5 -2" to="3 2 -2"
easing="linear" dur="2000" fill="forward"></a-animation>
<a-animation begin="fade" attribute="position" from="3 2 -2" to="0 3.5 -2"
easing="linear" dur="2000" fill="backwards"></a-animation>
</a-box>
</a-scene>
<script type="text/javascript">
document.querySelector('#orange-cube').addEventListener('animationend', function () {
document.querySelector('#orange-cube').emit('fade');
});
//document.querySelector('#orange-cube').emit('fade');
</script>
</body>
</html>

You can play animations by doing animationEl.play(). You could write some JS to trigger the animations based on the conditions you want. The declarative API (A-Frame 0.2.0) does not currently support animation sequences.

A D3 approach.
Here is a CodePen example that demonstrates what you ask for (I hope!). Using D3, you can schedule a second animation/transition after the first finishes with:
.each('end', <function>);
I wasn't sure how long to hold the cube in its new position, if 1 second is too short you can change the delay by modifying line 19 (in milliseconds):
.delay(1000)

A-Frame exposes the tween.js object so you can wire it up yourself.
AFRAME.TWEEN
https://github.com/tweenjs/tween.js/
I will be writing my own new animation components to hopefully deprecate <a-animation> tags which are limited and don't fit within the framework.

Related

How to set entity rotation using document.querySelector or other script techniques?

I'm trying to set up a simple a-frame physics demonstration that replays on click. Following basic examples from the aframe physics system and the orange shooter demo, I've simplified things to the code bellow which seems to work fine except for the rotation.set action. The block resets position, velocity and angularVelocity just fine but does not update rotation as it seems it should. Browser console message is Uncaught TypeError: Cannot read property 'set' of undefined
What would be the simplest way to set the rotation from within this script?
<html>
<head>
<script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-physics-system#1.4.0/dist/aframe-physics-system.min.js"></script>
</head>
<body>
<a-scene physics background="color: #ccddff">
<a-box id="dropped" position="-1 4 -3" rotation="40 45 0" color="#5577D9" dynamic-body></a-box>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="brown" static-body></a-plane>
</a-scene>
</body>
<script>
window.addEventListener('click', function () {
// METHOD2 - MOVE THE EXISTING ORANGE
document.querySelector("#dropped").body.position.set(-1, 4, -3);
document.querySelector("#dropped").body.velocity.set(0, 0, 0);
document.querySelector("#dropped").body.angularVelocity.set(0, 0, 0);
document.querySelector("#dropped").body.rotation.set(40, 45, 0);
});
</script>
</html>
It is document.querySelector("#dropped").components.body.body.position.set(-1, 4, -3);
This seems to work:
document.querySelector("#dropped").body.quaternion.set(0.3535533905932738,0.3535533905932738,0.14644660940672624,0.8535533905932737);
Apparently you have to use quaternions for rotations while physics is added, it looks like it overrides the native rotation. This works for getting one from degrees (45,45,0):
q=new THREE.Quaternion().setFromEuler(new THREE.Euler(THREE.Math.degToRad(45),THREE.Math.degToRad(45),0,'XYZ'));
And then:
document.querySelector("#dropped").body.quaternion.set(q.x,q.y,q.z,q.w);
But neither of this worked for me:
document.querySelector("#dropped").body.quaternion=q
document.querySelector("#dropped").body.quaternion.setFromEuler(e)
Where e is an Euler and q is a quaternion. Also the following works, albeit the result is not quite what you need:
document.querySelector("#dropped").body.quaternion=document.querySelector("#dropped").body.initQuaternion;
Should probably ask about it on A-frame github. Hope that this helps, happy coding ))

AFrame and the camera motion - identical to the inspector

I am interested in setting up an AFrame scene which has the exact same camera motion than the one we get when we invoke the 'Inspector (Ctrl+Alt+I)'.
left click used to move the camera
wheel for zooming
right click moves with no rotations the camera
It is an equivalent set up that would be found in the CAD - CAO softwares like rhino for example.
For the moment I have this set up, which has not the wheel-zooming, and that is not natural:
<a-entity look-at="#WorldFrame" look-controls>
<a-entity position="7 0 -7" rotation="0 135 0">
<a-camera fov="20" zoom="0.6" look-controls="enabled:false">
<a-cursor></a-cursor>
</a-camera>
</a-entity>
</a-entity>
Any clue?
thanks
EDIT:
the right configuration for the left-click seems to be the following:
<a-entity id="cameraTarget" position="0 0 0" rotation="0 0 0" look-controls >
<a-entity position="7 0 7" >
<!-- Disable the default wasd controls we are using those to control the ship -->
<a-camera id="cameraID" fov="20" zoom="0.6" look-controls="enabled:false">
<a-cursor></a-cursor>
</a-camera>
</a-entity>
</a-entity>
I still have no clue for the wheel and right click?
You can use aframe-orbit-controls
<head>
<title>My A-Frame Scene</title>
<script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-orbit-controls#1.2.0/dist/aframe-orbit-controls.min.js"></script>
<script src="https://unpkg.com/aframe-supercraft-loader#1.1.3/dist/aframe-supercraft-loader.js"></script>
</head>
<body>
<a-scene>
<a-entity supercraft-loader="name: icky-snake"></a-entity>
<a-entity camera look-controls orbit-controls="target: 0 1.6 -0.5; minDistance: 0.5; maxDistance: 180; initialPosition: 0 5 15"></a-entity>
</a-scene>
</body>

aframe zoom animation in vr-mode

i have an issue with the camera zoom in AFRAME vr-mode on mobile or in other vr gear. i have built a zoom animation it doesnt work on mobile or in other vr gear.
can someone help pls.
here is the code:
<a-entity id="cam-vr" camera="zoom:1; active:false " rotation="0 0 0" look-controls>
<a-animation begin="cursor-fusing" delay=" 3000" attribute="camera.zoom" from="1" to="4" dur="1000"></a-animation>
<a-animation begin="click" delay="500" attribute="camera.zoom" from="4" to="1" dur="1000"></a-animation>
<a-entity id="cursor" visible="false" cursor="fuse: true; fuseTimeout:4000" geometry="primitive: ring; radiusInner: 0.012; radiusOuter: 0.02; thetaLength: 360; thetaStart: 0" rotation="0 0 90" position="0 0 -1" material="color: black; side: double; shader: flat">
<a-animation begin="cursor-fusing" attribute="geometry.thetaLength" from="360" to="0" easing="linear" dur="3000"></a-animation>
<a-animation begin="mouseleave" attribute="geometry.thetaLength" from="360" to="360" dur="0"></a-animation>
</entity>
</a-entity>
This isn't possible — in VR with A-Frame or three.js, you are rendering with THREE.VREffect, not simply a THREE.PerspectiveCamera, and there is not a simple equivalent of zooming in while preserving correct left/right eye alignment.
FPS patterns don't always work so well in VR, either. You could move the camera closer to the content, but this can also create nausea for users in VR. It may be better to consider VR-appropriate alternatives, like teleporting.

Why does the A-Sky element show up in Firefox, but not in Chrome (A-Frame)

I have a A-Sky image that appears fine in Firefox, but doesn't appear in Chrome.
All other images work fine across both browsers, so not sure why this problem is occurring.
Github: https://github.com/ybinstock/OzymandiasWebVR
Github Pages: https://ybinstock.github.io/OzymandiasWebVR/
<a-scene>
<a-camera wasd-controls-enabled="false"></a-camera>
<a-mountain color="#F8981E"></a-mountain>
<a-sky src="desert.jpg" rotation="0 0 0"></a-sky>
<a-image id="trader" src="trader.jpg">
<a-animation attribute="position" from="0 2 -20" to="0 2 -1" dur="5000"
></a-animation>
<a-animation attribute="material.opacity" begin="fade" to="0"></a-animation>
</a-image>
<a-image id="legs" src="legs1.jpg" position="4 2 -4" material="opacity: 0">
<a-animation attribute="material.opacity" begin="fade" to=".8"></a-animation>
</a-image>
<a-image id="head" src="head1.jpg" position="-2 0 -4" rotation="0 0 90" material="opacity: 0">
<a-animation attribute="material.opacity" begin="fade" to=".8"></a-animation>
</a-image>
<a-image id="text" src="text.png" position="0 1.5 -1" material="opacity: 0">
<a-animation attribute="material.opacity" begin="fade" to="1"></a-animation>
</a-image>
<a-entity id="poem" geometry="primitive: plane" visible="false" material="color: blue"
sound="src: url(poetry2.mp3); volume: 3; autoplay: true; loop: false"></a-entity>
<a-entity id="wind" geometry="primitive: plane" visible="false" material="color: blue"
sound="src: url(wind2.mp3); volume: 3; autoplay: true; loop: true"></a-entity>
</a-scene>
The image is huge and taking time to load. 13000x6500 pixels. Try resizing it down.

how to interact with obj or collada-model in AFrame

<a-assets>
<a-mixin id="ring" geometry="primitive: ring; radiusOuter: 0.20;
radiusInner: 0.15;"
material="color: cyan; shader: flat"
cursor=" fuse: true"></a-mixin>
<a-asset-item id="mancloth" src="../models/man.obj"></a-asset-item>
<a-asset-item id="manclothmtl" src="../models/man.mtl"></a-asset-item>
</a-assets>
<a-entity camera look-controls wasd-controls><a-entity mixin="ring" position="0 0 -3">
<a-animation begin="cursor-click" easing="ease-in" attribute="scale"
fill="backwards" from="0.3 0.3 0.3" to="1 1 1"></a-animation>
<a-animation begin="cursor-fusing" easing="ease-in" attribute="scale"
fill="forwards" from="1 1 1" to="0.3 0.3 0.3"></a-animation>
</a-entity>
</a-entity>
<a-obj-model scale="1 1 1" src="#mancloth" mtl="#manclothmtl"></a-obj-model>
I use the camera to interact with the obj but aframe.js shows an error on line 57766. How can I solve this problem without changing aframe.js.
var intersectedEl = intersection.object.el;
intersectedEl.emit('raycaster-intersected', {el: el,intersection:intersection});
intersection.object is a THREE.Mesh, so intersection.object.el is undefined!
This problem has been fixed at https://github.com/aframevr/aframe/pull/1497 by binding the A-Frame entity to each child of the model.
You can wait for A-Frame 0.3.0 or use the latest A-Frame master. Right now, the cursor uses a raycaster to see what object was intersected. With OBJ/COLLADA models, it creates a tree of objects. However, A-Frame was only treating the top-level object as an entity. So when the raycaster returned the object, it did not have an associated entity to emit an event with.
Now it should just work:
<a-camera><a-cursor></a-cursor></a-camera>
<a-obj-model></a-obj-model>

Resources