Idle animation camera Aframe - javascript

I'm using aframe 0.8.2 and I'm trying to add a camera idle animation (only for the rotation component). I've done this so far :
HTML:
<!-- Camera-->
<a-entity id = "my_c" position="8.435 0 -3.579" > <a-camera></a-camera></a-entity>
Javascript :
var scene = document.getElementById("my_s");
var camera = document.getElementById("my_c");
var anime_1 = document.createElement("a-animation");
/* Add a time of "not moving" */
var t;
window.onload = resetTimer;
// DOM Events
document.onkeypress = resetTimer;
document.onmousedown = resetTimer;
function standby() {
console.log("Start standby.");
anime_1.setAttribute("attribute","rotation");
console.log(camera.getAttribute("rotation"));
anime_1.setAttribute("dur", "80000");
anime_1.setAttribute("to", "0 360 0");
anime_1.setAttribute("easing", "linear");
anime_1.setAttribute("repeat", "indefinite");
camera.appendChild(anime_1);
}
function resetTimer() {
clearTimeout(t);
t = setTimeout(standby, 3000);
camera.removeChild(anime_1);
// 1000 milisec = 1 sec
}
The problem is, I think that my camera does not upload its position and rotation : when I do rotate my camera, the camera idle animation does not start at the same position.
Thanks for your support :)

You could handle the from and to properties differently:
...
let initCamRotation = camera.getAttribute("rotation")
let endCamRotation = initCameraRotation
endCamRotation.y += 360
anime_1.setAttribute("from", initCamRotation);
anime_1.setAttribute("to", endCamRotation);
....
A bit offtop, but the animation components animation can be paused when given pauseEvents, i'd try using it instead of the a-animation entity. Here im not sure if you can interrupt the animation while it started.

Related

CreateJs - Controlling timeline playhead with click & drag

First time posting here, hope I'm doing this right :) I am trying to create a 360 spin in Adobe Animate with createJS, using a sequence of images embedded in a MovieClip. I have managed to get control of the timeline playhead using the code below:-
var start_x;
var startFrame;
var changeDistance;
var travelDistance;
this.threeSixty.addEventListener("mousedown", onMouseDown.bind(this));
this.threeSixty.addEventListener("pressup", onMouseUp.bind(this));
function onMouseDown(e) {
start_x = e.stageX;
startFrame = this.threeSixty.timeline.position;
this.threeSixty.addEventListener("pressmove", onMouseMove.bind(this));
}
function onMouseUp(e) {
this.threeSixty.removeEventListener("pressmove", onMouseMove.bind(this));
}
function onMouseMove(e) {
var changeDistance = e.stageX-start_x;
var travelDistance = startFrame+changeDistance;
if (travelDistance > this.threeSixty.timeline.duration){
this.threeSixty.gotoAndStop(travelDistance % this.threeSixty.timeline.duration);
}else if (travelDistance < 0){
this.threeSixty.gotoAndStop (this.threeSixty.timeline.duration + (travelDistance % threeSixty.timeline.duration));
} else {
this.threeSixty.gotoAndStop(travelDistance);
}
}
The problem is, when you click and drag the image along the X axis, the image sequence only moves forward/backwards by a single frame, as opposed to continuing the image sequence until the either mouse has stopped moving, or the mouse click is released. Any ideas where I might be going wrong here?
Thanks

Lowering bg music while another track plays and returning it to the previous volume afterwards

Basically i have a background track and a play and pause button for a voiceover, when you play the voiceover the background drops to 0.25 and when the voiceover stops it's supposed to go back up to 1.0. You can see below the code i use for it, it does drop the bg music volume but when the vo is ended the bg music stays at the lower level. Oh and if you're wondering the if statement in StopBG is the start of trying to make the bg music return to normal only if it's playing, there's an option to silence it altogether. The site is here for those who want to have a look.
function PlayVO()
{
document.getElementById("vostate").value = "0";
var voAudio = document.getElementById("voiceover_audio");
var bgAudio = document.getElementById("background_audio");
bgAudio.volume = 0.25;
voAudio.volume = 1.0;
voAudio.play();
if(voAudio.ended)
{
bgAudio.volume = 1.0;
}
}
function StopVO()
{
document.getElementById("vostate").value = "1";
var voAudio = document.getElementById("voiceover_audio");
voAudio.volume = 0.0;
voAudio.pause();
voAudio.currentTime = 0;
if(voAudio.volume == 0.25)
{
bgAudio.volume = 1.0;
}
}
Try the following:
//global variable
var oldBGVolume, voAudio, bgAudio;
document.onload = function(){
voAudio = document.getElementById("voiceover_audio");
bgAudio = document.getElementById("background_audio");
voAudio.addEventListener("ended", function() {
StopVO();
});
}
function PlayVO()
{
document.getElementById("vostate").value = "0";
oldBGVolume = bgAudio.volume;
bgAudio.volume = 0.25;
//If volume does not default to 1.0 keep this. Otherwise it is unneeded.
voAudio.volume = 1.0;
voAudio.play();
}
function StopVO()
{
document.getElementById("vostate").value = "1";
voAudio.pause();
voAudio.currentTime = 0;
bgAudio.volume = oldBGVolume;
}
Let me go through the changes a little bit... I am storing your background audio volume in the global variable oldBGVolume. I added a function for document.onload to set up your voAudio and bgAudio variables, and an event listener for the ended event. The StopVO function is called once playback ends.
Finally, in your StopVO function, I restore the previous volume of the background audio.

Javascript create an image and make it move

I'm trying to make a little browser game where you can shoot bullets.
Right now I am able to make a bullet, but I don't know how to get in moving.
I have done this:
var bullet_id = 1;
var timer_id; // reference of the timer, needed to stop it
var speed = 350; // pixels/second
var period = 10; // milliseconds
var sprite; // the element that will move
var sprite_speed = 0; // move per period
var sprite_position = 315; // pixels
function createbullet() {
var img = document.createElement("img");
img.src = "images/bullet.png";
img.id = "bullet";
img.name = "bullet";
var foo = document.getElementById("fooBar");
foo.appendChild(img);
move(1);
bullet_id++;
}
function animate ()
{
document.getElementById("bullet").style.left=340 + "px";
sprite_position += sprite_speed;
sprite.style.left = sprite_position+'px';
}
function move(direction)
{
if (timer_id) stop();
sprite_speed = speed * period/1000 * direction;
timer_id = setInterval (animate, period);
}
function stop()
{
clearInterval (timer_id);
timer_id = null;
}
function init()
{
sprite = document.getElementById ("bullet"); // the HTML element we will move
animate(); // just to initialize sprite position
}
window.onload = init; // start doing things once the page has loaded */
I tried to add a bullet_id system but I couldn't get it working really.
Here is my html
<a onmousedown="document.jack.src=image2.src;" onmouseup="document.jack.src=image1.src;" onclick="createbullet()"><img id="jack" name="jack" src="/images/jack1.png" /></a>
<div id="fooBar"></div>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
document.getElementById('jack').addEventListener('click',function(){...})
Ok so maybe I didn't think that one through, have just designed one to see if I could and it works, hope it helps:
/********************************************************/
stg=0
bgx=0
spd=70
buls=0
act=false
/********************************************************/
function ani(){
var int
act=true
bgx-=52
stg++
$('#jack').css('background-position','-52px 0px')
int=setInterval(function(){
if(stg<4){bgx-=52; stg++}
else{ bgx=0; stg=0 }
$('#jack').css('background-position',bgx+'px 0px')
if(stg==4) new Bullet();
if(!stg){
act=false
clearInterval(int)
}
},spd)
}
/********************************************************/
function Bullet(){
var x,img,int
x=52
img=document.createElement('img')
img.src='bullet.png'
img.setAttribute('class','mh posAbs')
img.setAttribute('style','top:0px;left:'+x+'px')
img.setAttribute('id','bul'+buls)
scre.appendChild(img)
img=document.getElementById('bul'+buls)
buls++
int=setInterval(function(){
if(x<300){
x+=13
img.setAttribute('style','top:0px;left:'+x+'px')
}
else{
img.src='exp.png'
clearInterval(int)
setTimeout(function(){ scre.removeChild(img) },100)
}
},spd)
}
/********************************************************/
$(document).ready(function(){
$('html').keydown(function(){
if(!act){
if(event.keyCode==13) ani();
}
})
$('html').click(function(){
if(!act) ani();
})
})
/********************************************************/
<div id="scre" class="posRel">
<div id="jack"></div>
</div>
<style>
#jack{
width:52px;
height:37px;
background:url('02.png') no-repeat;
background-position:0px 0px;
background-size:auto 100%
}
</style>
Ok so what's happening above is every time you click or press Enter, the firing animation is called, which is animated in stages and when it gets to a certain stage it calls upon the Bullet() constructor to create a new Object or bullet.
While creating the bullet, the constructor generates an <img> and gives it a unique id based upon the buls variable, which is then incremented to keep the id's unique.
This is the most important part:
img=document.getElementById('bul'+buls)
It will NOT work without it as any references to img in the code after it will refer to the last img created and not say:- 'bullet 5 of 10 that are on screen'.
Once created the Bullet object handles the movement of the image it is referenced to, removing the need to move it with any other code...
P.S. The $('html').keydown(...) acts as an auto-fire!

How to Optimize js animation with requestAnimationFrame and introduce delta?

I have a basic animation of a ball falling with a gradually increasing velocity.
DEMO
It is somewhat working as expected with an expected velocity initially. So on click on the canvas we can repeat the animation , so each time we can see the ball speed keeps increasing. After 5-6 click the ball is moving with high velocity.
So is the issue is with frame rate , and expected unit move per frame. ?
1. How to reduce/optimize the loop call ? , and get a constant velocity in each click.
I wont prefer to change the value inside Ball model, but the time of ball.update() must be reduced.
var ball = new Ball(10,10,20);
function animate() {
ctx.fillStyle = "#CCC";
ctx.fillStyle = "#CCC";
ctx.fillRect(0, 0, 500, 500);
ball.update();
ball.draw(ctx);
requestAnimationFrame(animate); // add timestamp to optimize ?
}
and on click the reset animation is like this
$("#element").on('click', function () {
ball = new Ball(10,10,20)
requestAnimationFrame(animate);
});
and 2. Why it is working with expected speed initialy ? and I prefer to clear the animation after the ball moves out of canvas.
The main reason is that you are combining setTimeout with requestAnimationFrame which kind of defeat its purpose.
Not only are your rAF triggered by an inaccurate timer but when rAF kicks in it is not sure you will get a frame for that round which can produce jerky result.
Change these lines:
setTimeout(function () {
animationId = requestAnimationFrame(animate);
}, 1000/60);
to
//setTimeout(function () {
animationId = requestAnimationFrame(animate);
//}, 1000/60);
Then reset your ball as with Greg's answer. There is no need to call rAF again as it is already running:
$(function(){
requestAnimationFrame(animate);
$("#element").on('click', function () {
ball = new Ball(10,10,20);
});
});
Modified fiddle
You could also reset the ball by updating its properties.
Here's a fork of your fiddle that works: http://jsfiddle.net/8egrw/
Comment out this line:
$("#element").on('click', function () {
ball = new Ball(10,10,20)
//animationId = requestAnimationFrame(animate);
});

Custom progress bar for <audio> and <progress> HTML5 elements

I am mind boggled at working out how to create a custom seekbar for an audio player using the tag and simple Javascript.
Current Code:
<script>
function play() {
document.getElementById('player').play();
}
function pause() {
document.getElementById('player').pause();
}
</script>
<audio src="sample.mp3" id="player"></audio>
<button onClick="javascript:play()" >Play</button>
<button onClick="javascript:pause()" >Pause</button>
<progress id="seekbar"></progress>
Would it be possible to link the progress bar so that when i play a song the progress is shown?
Yes, it is possible using the timeupdate event of the audio tag. You receive this event every time the position of the playback is updated. Then, you can update your progress bar using the currentTime and duration properties of the audio element.
You can see a working example in this fiddle
If you want smooth progress bar,try somethink like that
HTML:
<div class="hp_slide">
<div class="hp_range"></div>
</div>
CSS:
.hp_slide{
width:100%;
background:white;
height:25px;
}
.hp_range{
width:0;
background:black;
height:25px;
}
JS:
var player = document.getElementById('player');
player.addEventListener("timeupdate", function() {
var currentTime = player.currentTime;
var duration = player.duration;
$('.hp_range').stop(true,true).animate({'width':(currentTime +.25)/duration*100+'%'},250,'linear');
});
Pretty rough,but works
Here's a simple vanilla example:
const url = "https://upload.wikimedia.org/wikipedia/en/a/a9/Webern_-_Sehr_langsam.ogg";
const audio = new Audio(url);
const playBtn = document.querySelector("button");
const progressEl = document.querySelector('input[type="range"]');
let mouseDownOnSlider = false;
audio.addEventListener("loadeddata", () => {
progressEl.value = 0;
});
audio.addEventListener("timeupdate", () => {
if (!mouseDownOnSlider) {
progressEl.value = audio.currentTime / audio.duration * 100;
}
});
audio.addEventListener("ended", () => {
playBtn.textContent = "▶️";
});
playBtn.addEventListener("click", () => {
audio.paused ? audio.play() : audio.pause();
playBtn.textContent = audio.paused ? "▶️" : "⏸️";
});
progressEl.addEventListener("change", () => {
const pct = progressEl.value / 100;
audio.currentTime = (audio.duration || 0) * pct;
});
progressEl.addEventListener("mousedown", () => {
mouseDownOnSlider = true;
});
progressEl.addEventListener("mouseup", () => {
mouseDownOnSlider = false;
});
button {
font-size: 1.5em;
}
<button>▶️</button>
<input type="range" value="0" min="0" max="100" step="1">
The approach is to use an input[type="range"] slider to reflect the progress and allow the user to seek through the track. When the range changes, set the audio.currentTime attribute, using the slider as a percent (you could also adjust the max attribute of the slider to match the audio.duration).
In the other direction, I update the slider's progress on timeupdate event firing.
One corner case is that if the user scrolls around with their mouse down on the slider, the timeupdate event will keep firing, causing the progress to hop around between wherever the user's cursor is hovering and the current audio progress. I use a boolean and the mousedown/mouseup events on the slider to prevent this from happening.
See also JavaScript - HTML5 Audio / custom player's seekbar and current time for an extension of this code that displays the time.
First of all, don't use the progress element, it's a shitty element (for now) and styling it is a huge pain in... well it's boring (look at a little project I made, look at it (and it's juste webkit/moz)).
Anyway, you should read the doc on MDN, it's very easy and with a lot of examples. What you are looking for is the currentTime attribute, here a little snippet :
var audio = document.querySelector('#player')
audio.currentTime = 60 // will go to the 60th second
So what you need is to use the cross-multiplication (div is the element you use as a progress bar) :
Where I clicked on div | THE TIME I WANT TO KNOW
————————————————————————————————————————
Total length of div | The total time of my video/audio (audio.seekable.end())

Categories

Resources