I am trying to get an animation to move the camera from the current position, to a position passed from the element clicked. The issue seems to be in proper syntax for passing the 'to' position into an animation. Here is what I have.
<a-entity id="cam-position" position="0 0 1.2" rotation="-0 0 0">
<a-camera look-controls wasd-controls>
<a-entity visible="true" cursor="fuse: true; fuse-timeout: 500"
position="0 0 -1"
scale="0.01 0.01 0.01"
geometry="primitive: sphere"
material="color: #6AD7FF; shader: standard">
<a-animation begin="click"
easing="ease-in"
attribute="scale"
dur="2000"
fill="backwards"
from="0.01 0.01 0.01" to="0.04 0.04 0.04">
</a-animation>
<a-animation begin="fusing"
easing="ease-in"
attribute="scale"
fill="forwards"
from="1 1 1" to="0.1 0.1 0.1" >
</a-animation>
</a-entity>
</a-camera>
<a-animation begin="move"
attribute="position"
dur="2000"
from="0 0 1.2"
>
</a-animation>
</a-entity>
document.querySelector('#cam-position').emit('move',{'to': { x: 0, y: 0, z: -88 } });
It works fine without the second argument and the 'to' specified in the a-animation. Any ideas? Thanks
When you are emitting move, the second argument is the event detail. Animations do have a feature to start an animation on an event trigger, but it doesn't look at the event detail.
You'd need to do a animation.setAttribute('to', {...}) rather than trying to have an event handle everything since that's not a feature.
document.querySelector('a-animation[begin="move"]').setAttribute('to', '0 0 -88');
document.querySelector('#cam-position').emit('move')
Related
I have my camera and cursor set up this way:
<a-camera>
<a-cursor
fuse="true"
animation__fusing="property: scale; startEvents: fusing; easing: easeInCubic; dur: 1500; from: 1 1 1; to: 0.1 0.1 0.1"
animation__mouseleave="property: scale; startEvents: mouseleave; easing: easeInCubic; dur: 500; to: 1 1 1">
</a-cursor>
</a-camera>
And a scene looking like this:
<a-entity id="scene1">
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" onclick="changeLevel('scene1', 'scene2')"></a-box>
<a-sky src="background1.png"></a-sky>
</a-entity>
Now the cursor is always fusing, even when looking at the skybox. Is it possible to start the fusing animation only when looking at clickable entities?
Thanks
You can configure the cursor through the raycaster component. In your case:
<a-cursor fuse="true" raycaster="objects: a-box" ....
You can set a class for your interactive objects, to make it clear:
<a-box class="clickable"></a-box>
...
<a-cursor raycaster="objects: .clickable" ...
Check it out here.
I have some objects in aframe with visible="false" meaning they aren't visible but they are still interactable even though you can't see them. Is there a solution to this?
Found a few similar cases online but no clear solution.
https://github.com/aframevr/aframe/issues/3551
https://github.com/aframevr/aframe/issues/979
<!-- CURSOR ENTITY -->
<a-entity rotation="0 0 0" position="0 0 2">
<a-entity id="camera" far: 20; camera look-controls rotation="0 0 0" wasd-controls>
<!-- MAIN CURSOR -->
<a-entity raycaster="interval: 200; objects: .clickable" cursor="fuse: true; maxDistance: 500; timeout: 1500;" id="cursor-main" position="0 0 -1.5" geometry="primitive: ring; radiusOuter: 0.04; radiusInner: 0.03; thetaLength: 360; thetaStart: 90;" material="color: #439DC2;">
<a-animation begin="cursor-fusing" attribute="geometry.thetaLength" fill="forwards" from="360" to="0" easing="ease-in"></a-animation>
<a-animation begin="mouseleave" attribute="geometry.thetaLength" fill="backwards" from="0" to="360" dur="0"></a-animation>
</a-entity>
<a-entity id="cursor-loader" position="0 0 -1.51" geometry="primitive: ring; radiusOuter: 0.04; radiusInner: 0.03;" material="color: #2ADD2A;">
</a-entity>
</a-entity>
</a-entity>
<a-entity ui-modal="triggerElement:#selection;" visible="false">
<a-image position="-0.7 -1 1" class="clickable" src="#one" scale="0.7 0.7 0" link="href:location1.html; on: click; visualAspectEnabled: false" src-fit></a-image>
<a-image position="0 -1 1" class="clickable" src="#two" scale="0.7 0.64 0" link="href:location2.html; on: click; visualAspectEnabled: false" src-fit></a-image>
<a-image position="0.7 -1 1" class="clickable" src="#three" scale="0.7 0.7 0" link="href:location3.html; on: click; visualAspectEnabled: false" src-fit></a-image>
<a-image class="clickable" src="#close" id="closing" scale="0.3 0.3 0" position="-0.5 -0.35 1.1"></a-image>
</a-entity>
Ideally if an object is set to visible="false" the user shouldn't be able to interact with it.
As seen in the discussion, if you want to ignore certain objects, you should not rely on visibility. The proper way would be using the objects whitelist:
<a-scene cursor raycaster='objects: .clickable>
The whitelist uses typical CSS selectors, so in the above example the raycaster would only interact with elements which have a clickable class.
You can add / remove it with the visibility:
if (condition) {
el.setAttribute('visible', 'false')
el.classList.remove('clickable')
} else {
el.setAttribute('visible', 'true')
el.classList.add('clickable')
}
You can check it out in this fiddle. Click the sphere to make the box clickable / not clickable.
A hacky workaround could be also setting the scale to 0 0 0. The element won't be visible, and won't be clickable.
I'm currently trying to animate a camera's rotation in a scene. The animation should occur after looking at a circle for 1 second.
The problem is that the bottom of the scene don't seem reachable after the animation, althrough that it is before the animation occured.
I tried first to animate the camera, then a container of the camera. The second option produced an other problem, it seems that all the sky is displaced and I don't understand how to "correct" that.
Video of the problem when the animation is on the camera
Here are two codepens :
Animation on the camera
<script src="https://aframe.io/releases/0.6.1/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-animation-component/dist/aframe-animation-component.min.js"></script>
<a-scene>
<a-assets>
<img id="city" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/city.jpg" data-position="0 0 0" alt="Table de conférence">
</a-assets>
<a-sky src="#city" rotation="0 0 0"></a-sky>
<a-circle position="-8 -5 2"
rotation="90 0 0"
geometry="radius: 1;"
material="side: double;"
>
</a-circle>
<a-entity id="camera-container" rotation="0 100 0">
<a-entity id="camera" look-controls camera="fov: 80; userHeight: 0" wasd-controls="enabled: false;">
<a-animation attribute="rotation"
dur="1000"
begin="animation__fuse-complete"
from="-31.2 4 0"
to="2 5.5 0"
></a-animation>
<a-entity id="cursor" cursor="fuse: true; fuseTimeout: 100"
position="0 0 -1"
geometry="primitive: ring; radiusInner: 0.013; radiusOuter: 0.02"
material="color: #000; shader: flat"
animation__fuse="startEvents: fusing;
property: scale;
dur: 1000;
to: 0.4 0.4 0.4"
animation__fuseed="startEvents: animation__fuse-complete;
property: scale;
dur: 1;
to: 1 1 1"
>
</a-entity>
</a-entity>
</a-entity>
Animation on a container
<script src="https://aframe.io/releases/0.6.1/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-animation-component/dist/aframe-animation-component.min.js"></script>
<a-scene>
<a-assets>
<img id="city" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/city.jpg" data-position="0 0 0" alt="Table de conférence">
</a-assets>
<a-sky src="#city" rotation="0 0 0"></a-sky>
<a-circle position="-8 -5 2"
rotation="90 0 0"
geometry="radius: 1;"
material="side: double;"
>
</a-circle>
<a-entity id="camera-container" rotation="0 100 0">
<a-animation attribute="rotation"
dur="1000"
begin="animation__fuse-complete"
from="0 100 0"
to="30 100 0"></a-animation>
<a-entity id="camera" look-controls camera="fov: 80; userHeight: 0" wasd-controls="enabled: false;">
<a-entity id="cursor" cursor="fuse: true; fuseTimeout: 100"
position="0 0 -1"
geometry="primitive: ring; radiusInner: 0.013; radiusOuter: 0.02"
material="color: #000; shader: flat"
animation__fuse="startEvents: fusing;
property: scale;
dur: 1000;
to: 0.4 0.4 0.4"
animation__fuseed="startEvents: animation__fuse-complete;
property: scale;
dur: 1;
to: 1 1 1">
</a-entity>
</a-entity>
</a-entity>
</a-scene>
How to correctly animate the rotation of the camera ?
I'm on Windows 10, with Chrome 59, A-Frame 0.6.1 and aframe-animation-component
Thank you in advance and have a nice day !
I came across a similar problem with being unable to reach the bottom rotation position after executing setAttribute on the camera rotation. Here is what I think is happening:
The problem arises because the rotation on the X-axis changes via code, moving from 0 to 30 degrees without there being a corresponding head motion. As a result, 30 degrees are lost off of the lower limit of -90 degrees.
I think that there is a strong intention in the design of A-Frame that visual angles that arise via head position remain consistent. If you are looking straight ahead and suddenly the angle is 30 degrees higher, yet you haven't moved your head, everything will be askew. You'd have to look downward 30 degrees to see "straight ahead", etc.
It is easy to try and code these discontinuities when A-Frame is viewed through a desktop monitor rather than a visor. I think the "solution" is going to have to be to design some way to have the camera return to its starting position when you run your animation so that it doesn't lose its correspondence to the player's head.
I use a-frame to do web-vr. I's good to use but I have some situation don't know how to implement.
First I put a Camera with cursor and set the raycaster intersect with object ".trigger".
<a-entity camera="" look-controls="" position="" rotation="" scale="" visible="">
<a-entity cursor="fuse: true; fuseTimeout: 1500" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: cyan; shader: flat" raycaster="objects: .trigger" rotation="" scale="" visible="">
<a-animation begin="click" easing="ease-in" attribute="scale" fill="forwards" from="0.1 0.1 0.1" to="1 1 1" dur="150"></a-animation>
<a-animation begin="cursor-fusing" easing="ease-in" attribute="scale" fill="backwards" from="1 1 1" to="0.1 0.1 0.1" dur="1500"></a-animation>
</a-entity>
</a-entity>
And create a entity with class "trigger".
<a-entity class="tigger" id="clip01" clip01="on: click; conditionId: ShowClipTrigger" data-is-trigger="true" geometry="primitive: plane; width: 2; height: 3" material=" src: #clip01-pic; opacity: 0.99;" position="-5.913 -3.544 4.675" rotation="-82.048 122.222 11.345" scale="" visible="" animation__move="" animation__rotate=""></a-entity>
The ".trigger" object will trigger some action after on click event received. My question is how to disable the intersect after the trigger been click. I try remove the class "trigger" from the object after the click evnet, but it still can intersect with cursor.
I search the a-frame document raycaster but no clue.
After removing the whitelisted class, You need to refresh the raycaster:
var raycasterEl = AFRAME.scenes[0].querySelector('[raycaster]');
raycasterEl.components.raycaster.refreshObjects();
Also You can achieve this by making a simple switch in the event listener:
var switch=true;
el.addEventListener("click", function(evt) {
if(switch){
//doStuff
switch = false;
}
});
or remove the listener completely, like i did here:
//listener
this.doStuff = this.doStuff.bind(this);
el.addEventListener("click", this.doStuff());
//function
doStuff: function(){
this.el.removeEventListener("click",this.doStuff);
}
I'm trying to play a short rotation animation for this parent camera entity. I have the following a-animation:
<a-animation attribute="rotation" dur="1000" to="0 163.5761975835419 0" fill="forwards" begin="rotateCam"></a-animation>
Then, I try to set the 'to' attribute before emitting rotateCam (with animation.setAttribute(...)), but it only plays the default rotation I set in the HTML. Am I missing something?
See this fiddle for example. v0.5.0.
Thank you for your time.
After some research and talking to dirkk0 on A-Frame Slack it became clear they're going for a component-based approach. I have changed my code to apply ngokevin's animation component and it solved my problem! :)
Relevant test (AFrame v0.5.0)
HTML:
<a-scene>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-box position="-1 0.5 -3" width="1" height="1" depth="1" color="#4CC3D9" animation="property: rotation; dur: 1000; startEvents: rotateBox"></a-box>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
JS:
setTimeout(() => {
let box = document.querySelector('a-box');
box.setAttribute('animation', 'to', '0 20 0');
box.emit('rotateBox');
}, 2000);