I've been trying to implement a global pause for all tweens. If in my animate loop I just don't update TWEEN, it stops but then after I unpause jumps ahead to the position it should have as if I never paused.
TWEEN.update(time);
To tackle this I want to have a separate timeline as an argument of update function. I've tried to create a different value and update it independently, but then the tween won't start at all.
So here's the thing that ended up working, wondering if there is a more elegant way to do it using Tween's internal variables like elapsed.
var delta = 0;
var tmp = 0;
var recorded = false;
function animate(timestamp) {
if(paused){
if(!recorded) {
tmp=timestamp;
recorded=true;
}
}
else {
if(recorded){
delta += timestamp-tmp;
recorded=false;
}
TWEEN.update(timestamp-delta);
}
Keep the time in TWEEN.update(time) will pause the tween. #Eugene was right.
cache the pause times;
TWEEN.update(timenow - pause times).
For more detail, see:
https://github.com/tweenjs/tween.js/issues/341#issuecomment-447653541
Today i have written little code, that can help you with pause for your tweens.
//First you need set some id for your tween animation.
var myTween = createjs.Tween.get(your_object).to({your_animation_params} ...);
//When you need to paused your tween by some event
//just get this object and set it on the same coordinates(by example),
//with time animation = 0 to have accses to use Pause method
c.Tween.get(your_object).to({x:your_object.x}, 0).pause(myTween);
//Later you can just play(unpause) it again using same trick
c.Tween.get(your_object).to({x:your_object.x}, 0).play(myTween);
Related
So far I have a little script that detects the scroll top position and at a set level I want it to trigger a jquery counter. So far I have an array with the maximum number inside var = eightyS = [3]; then there is..
if (y > 630) {
$('.targetS').each(function() {
//counter
delay(1000);
});
} else {
return false;
}
Now I've made something similar in C++ years ago (couldn't do it now with a gun to my head) so I followed a similar logic. But this is where I'm stuck. The idea behind this function is that it will do a read out on screen of 0 then 1 then 2 then 3. Any help is greatly appreciated
You could use a setInterval() which executes a function ever second such as below:
var count = 0;
var interval = setInterval(function(){
count++;
$('#counter').text(count);
}, 1000);
I've created a quick JSFiddle
You should be able to wrap this in to your code fairly easily. You may also want to use clearInterval(interval) to stop the function executing when you scroll back up the page; or when you get in to your else block, which would have the same effect. I've added a clearInterval() example to the JSFiddle on click of the stop link. You'll need to make sure the interval variable is in scope when clearing it.
I have programmed a video player in Javascript and I am trying to implement a rewind / forward functionality.
The aim is that the video will rewind in when the button is held down. I programmed a version of this which would rewind once when the button is clicked but then you have to keep clicking it to rewind continuously.
So far I have done this:
HTML
<video id="media" width="600" height="400" preload="none">
<source src="files/Best of 60s.m4v">
</video>
<input type="button" id="skipTrackBackward" value="Backward" onmousedown="rewind()" onmouseup="stoprewind()"/>
Javascript:
var skipB
function initiate(){
mmedia = document.getElementById('media');
skipB = document.getElementById('skipTrackBackward');
function rewind(){
while (!mmedia.paused && !mmedia.ended){
for (var i = mmedia.currentTime; i != 0; i--){
mmedia.currentTime=i;
}
}
}
function stoprewind(){
mmedia.play();
}
The above code causes my Chrome tab to crash so obviously I have done something very wrong! But my understanding is that I only want the rewind function to start provided the video has not reached its end or has been paused. So while it is in that state it should run the for loop which takes into account the currentTime which has elapsed and subtract 1 second while the mouse is pressed down (currentTime takes integers which are interpreted as seconds). It should keep updating currentTime as long as it has not reached 0 seconds.
The above code has been minimised for convenience. Any suggestion greatly appreciated.
I think you've created either an infinite loop or your setting mmedia.currentTime to a bogus value.
First lets cover trouble shooting. See what the console outputs, Add some console.log statements to see what the values are as it runs and what the values are just before it crashes, step through the code in the debugger (use conditional breakpoints to filter out the noise).
Now code analysis. Try replacing the variables with hard coded values and see if the logic pans out:
while (!mmedia.paused && !mmedia.ended) {
^1 ^2 ^3
Why the while? is there a case where you need to run the for loop until mmedia.paused and mmedia.ended?
When does this variable change to break out of the loop?
Or this variable?
So when the for loop executes there is nothing to cause mmedia.paused or mmedia.ended to be changed from false to true and that is an infinite loop.
Also you check that i != 0 is it possible for i to be < 0? And if so will mmedia.currentTime handle values less than 0?
Last but not least if you were to have a break out of the while / for loop it is in a blocking process. This means that if you rely on user interaction to flip one of the cancel flags it will never happen because the thread is waiting for the while / for loops to finish before registering that the user did something. If the infinite loop was fixed one click would prevent the pause / stop button from being clicked till it reached the beginning (obviously this is silly since you could just set currentTime to 0 in the first place). Another effect is that you won't see the rewind process because it won't update the display till the thread is finished executing code.
What you will need it to rewrite the logic in a non-blocking fashion. This is called asynchronous code and is a lot more complicated then a simple loop.
var stopRewinding;
function rewind() {
var timeout = 100;
stopRewinding = false;
if (mmedia.paused || mmedia.ended) {
console.log("Media state unable to rewind");
return;
}
function worker() {
if (stopRewinding || mmedia.currentTime <= 0) {
return; // All done so get outa here
}
mmedia.currentTime--;
setTimeout(worker, timeout);
}
worker();
}
Now you can interrupt the loop by setting stopRewinding to true or when the currentTime reaches 0.
You can then either have a button or use the mousedown and mouseup events to trigger rewind() and stopRewinding = true.
I want to learn the JavaScript as well. and looking the various jQuery functions to their equivalent JavaScript.
I want to convert this jQuery function to its equivalent JavaScript functions? How can I do this?
$('.sample').stop().animate({
left: '-102px'
}, 1000);
In a nutshell, a jQuery animation is a recurring timer that changes one or more CSS properties on each timer tick.
In addition jQuery implements a tweening algorithm that calculates on each timer tick, whether the animation is ahead or behind schedule and adjusts so that the animation always completes in the exact time specified.
In addition jQuery implements an animation queue so that multiple animations can be chained together (start the next one when the previous one completes).
In addition jQuery supports easing functions which allow you to specify a non-linear animation that varies it's speed during the time according to a specific algorithm.
FYI, the jQuery javascript source code is fully available if you want more details. The core of the work is in a local function called doAnimation(), though much of the work is done in functions called step and update which can be found with the definition of jQuery.fx.prototype.
Here's another answer that shows a simple fade animation in pure javascript.
Here's a general tutorial on animation.
You can see a discussion of using a timer for an animation here.
You can see a discussion of tweening here.
Here's a javascript version of your specific animation:
// node is the DOM element to animate
// prop is the CSS property name to animate
// end is the CSS value to animate to (only supports px units)
// duration is the time of the animation in ms
// fn is an optional callback when the animation is done
// fn is called like this fn(node, arg)
// arg is an optional argument that is passed to the callback
// context is an optional argument that is the this pointer for the function
function animate(node, prop, end, duration, fn, arg, context) {
var stepTime = 20;
var startTime = new Date().getTime();
var start = parseInt(getComputedStyle(node).getPropertyValue(prop), 10);
if (typeof end === "string") {
end = parseInt(end, 10);
}
function step() {
// calc how much time has elapsed
var nextValue, done, portionComplete;
var timeRunning = new Date().getTime() - startTime;
if (timeRunning >= duration) {
nextValue = end;
done = true;
} else {
portionComplete = timeRunning / duration;
nextValue = ((end - start) * portionComplete) + start;
done = false;
}
// set the next value
node.style[prop] = nextValue + "px";
if (!done) {
setTimeout(step, stepTime);
} else {
if (fn) {
context = context || window;
fn.call(context, node, arg);
}
}
}
// start the animation
step();
}
Working demo: http://jsfiddle.net/jfriend00/Mc3xD/
For simplicity of understanding, this doesn't implement the .stop() part of your jQuery example as that would need a separate data structure to keep track of each animation timer running on a given object which can be seen in a more involved version that supports stop(): http://jsfiddle.net/jfriend00/mp4Yq/.
you remind me when i started learning js , and then was very happy to find jquery , anyway i dont know why you are doing vice versa , but to answer you question
Animation in javascript can be used using setInterval function with changing the top , left .. etc attributes over a very small amount of time ( usually 24 milli secconds ) which to the human eye are like a stream and not like seperate shots of positions , also you may consider using pure css3 , however a function like this may be used
var position,ratio,time,mytimer;
document.getElementById("hi").style.left=0;
function animate_left(position,time)
{
ratio=position/time;
if(parseInt(document.getElementById("hi").style.left)<=position)
{
document.getElementById("hi").style.left=(parseInt(document.getElementById("hi").style.left)+ratio*100).toString()+"px"
}
else
{
clearInterval(mytimer)
}
}
function animate(value1,value2)
{
mytimer=setInterval(function(){animate_left(value1,value2)},10) //where 10 is minimum smooth animation factor for human eye
}
animate(600,1000);
http://jsfiddle.net/prollygeek/er67f/6/
I've background image and by using small javascript code, it moves from right to left.
HTML code
<div id="clouds_image"></div>
Javascript code
var g=0;
var speed=30;
function rollClouds() {
document.getElementById('clouds_image').style.backgroundPosition=g+'px 0';
g--;
scroller=setTimeout(function(){rollClouds()},speed);
}
window.addEventListener?
window.addEventListener('load',rollClouds,false):
window.attachEvent('onload',rollClouds);
But i've noticed that, with time my PC CPU memory usage increased ! causing overload on my pc and if i disabled that javascript code, it back to normal.
My question
so i think i need to modify this javascript code that it not keep working forever, i mean, i want to make it to repeat that action only 5 times then stop , maybe i need to define value of g but i'm not good in javascript so any help ~ Thanks.
You need to use a variable to count how many times that function was executed, and use setInterval instead of setTimeout: See example
http://jsfiddle.net/EQDjx/206/ (my counter start from 100 and goes down to 0)
for a more nice effect i recomand you to use jquery. See animate function
http://api.jquery.com/animate/
var g = 1000;
var speed=300;
var counter = 100;
function rollClouds() {
document.getElementById('clouds_image').style.backgroundPosition=g+'px 0';
g--;
if (counter < 1) clearInterval(interval);
}
interval = setInterval(function(){rollClouds()}, speed)
A cleaner solution might be to use jQuery to move the background:
function moveClouds() {
$("#clouds_image").css({left:"-2000px"});
$("#clouds_image").animate({left:"2000px"},10000);
}
Then you might set an interval to trigger it every x milliseconds.
setInterval(moveClouds,10000)
JSFiddle is here: http://jsfiddle.net/qXpVX/
I have a function that runs on a click event that uses javascript's setIterval for some of my animations (i'm doing a game) so the problem is that if a user clicks while the animation is still displaying (setInterval is still executing) the setInterval is stacking up in the event stack or that is what I found out thus either crushing my game or running twice as fast (the animation). My question is is there any way to prevent event stacking? I do not want the setInterval to stack up on the previous setInterval and so on. I know that I could use clearInterval function like so:
var timerInterval = setInterval(drawPlayerRunning, 50);
clearInterval(timerInterval);
but it does not really work as I want it to, because what if user clicks many times while the function is still is executing, the clearInterval will only get rid of last event of the event stack leaving all the previous ones still in the "game". Any idea how to prevent this event stack up, or at least removing them efficiently?
You can create a flag that monitors the interval state:
1)
var isIntervalInProgress = false;
setInterval(function()
{
if ( isIntervalInProgress )
return false;
isIntervalInProgress = true;
drawPlayerRunning();
isIntervalInProgress = false;
}, 50);
or just a timeout that will run itself once it's finished:
2)
var func = function()
{
setTimeout(function()
{
drawPlayerRunning();
func();
}, 50)
}
whichever you like
You want to use requestAnimationFrame. It is designed with games in mind, and if your code happens to be too slow, it will reduce your frame rate accordingly (from 60 fps to 30 fps for instance). But it won't stack-up events.
Edit: Sorry, I think I misunderstood your question. Let me try again.
You should have only one draw function which is called every few milliseconds (set the interval up with requestAnimationFrame(draw)).
A click should not add a new interval, but rather create a floatingAnimation object and add it to the list of objects to render. All animation objects will be rendered by the draw function everytime the browser calls draw. In the arguments passed to draw, there will be a timestamp. Use this timestamp minus the creation date of floatingAnimation to determine how to draw the floating thing above the character.