I am using open layers 4. I am moving and stoping marker animation as this example without any problem. But I want to add pause and continue functionality to marker also. I edit some variables and endeavor on the issue with these functions. When I call continueAnimation function at first, the elapsedTime parameter become negative and give exception on moveFeature function. When I secondly call the continueAnimation function. It is working as expected. It is looking like kind of javascript implementation issue.
function pauseAnimation() {
animating = false;
//I hold elapsed time globally
var index = Math.round($("[id='rightfrm:tbv1:txt1']").val() * elapsedTime / 1000);
(geoMarker.getGeometry()).setCoordinates(line_coordinates[index].lc);
map.un('postcompose', moveFeature);
}
function continueAnimation() {
animating = true;
now = new Date().getTime();
now = now - 10000 + elapsedTime; // --10000-- for negativeness
geoMarker.setStyle(null);
map.on('postcompose', moveFeature);
map.render();
}
I found my problem. It was a logical error. Pause and Continue working now.
now = new Date().getTime() - elapsedTime;
Anyone can use these functions for Pause/Continue functionality.
Related
I have a piece of javascript that I have copied & edited, that is designed for an animated loading ring but the animation only runs once, I would like it to run every 4 seconds, until the page is loaded, but I can't find the right syntax/script to get it to repeat, i do not want it to reload the page only loop that specific script until i set it to stop.
".radial" is the class of the radials contained inside my css & html files.
there is twelve of them & they do-not rotate only the fluorescent .glow animation part makes it appear as they are rotating. the code is;
const radials = [...document.querySelectorAll('.radial')];
let degrees = 29;
for(i=0; i < radials.length; i++) {
degrees += 13;
radials[i].style.transform = `rotate(${degrees}deg)`;
degrees += 34;
}
radials.forEach((radial, index) => {
setTimeout(function() {
radial.classList.add('glow');
},index * 29);
});
:: Update ::
Having read the comments below and searching on Youtube. I think that wrapping the whole script in a function, would be the best option. Including a call to that function within its self & passing it an argument in the parenthesis of a timeout or delay property. But setInterval() & setTimeOut() both use the unsafe eval() function underneath. Which is supposed to be a security concern.
Also a youtube video I watch a while ago, said that setInterval() & setTimeOut() do not achieve 60fps. requestAnimationFrame() Would be A much better option. I'm not sure how legitamate these claims are, or where his sources were from but I will continue searching the Webs.
The glow part looks good but I just haven't been able to get it to repeat.
I am new to Js please be patient.
is there any other workarounds for the setTimeOut() & setInterval().?
Place this code into a function that is passed to a setInterval() timer call.
function loop() {
const radials = [...document.querySelectorAll('.radial')];
let degrees = 29;
for(i=0; i < radials.length; i++) {
degrees += 13;
radials[i].style.transform = `rotate(${degrees}deg)`;
degrees += 34;
}
radials.forEach((radial, index) => {
setTimeout(function() {
radial.classList.add('glow');
},index * 29);
});
setTimeout(loop, 4000);
}
Use setInterval(). The setInterval takes two parameters, the first is the function you want to run and the second is your repeat time in miliseconds. So to run a function every 4 seconds you would do:
setInterval(function() {
// do something
}, 4000);
You can do it with setInterval, as in the other answers, but I think that the logic is clearer if you have an animate function that keeps calling itself.
You are adding a "glow" class, but you are never removing it. The animate function should toggle it on and off. To make it crystal clear, let's make that a separate function, toggleGlow.
Next, each animation loop we kick off the individual toggleGlow functions with a different delay for each radial.
Finally, the animate function will re-call itself after a short, constant, delay each time, until some stop condition is met (like the page loading).
const radials = [...document.querySelectorAll('.radial')];
function toggleGlow(element) {
if (element.classList.contains("glow")) {
element.classList.remove("glow");
} else {
element.classList.add("glow");
}
}
function animate() {
radials.forEach((radial, index) => {
setTimeout(function() {
toggleGlow(radial);
}, index * 29);
});
if (!stopCondition) {
setTimeout(animate, 200);
}
}
// kick it off
animate();
JSFiddle example here: https://jsfiddle.net/duxhy3Lj/
I am using PIXI.extras.MovieClip to play a short animation (about 60 frames) and due to not knowing how many FPS there will be on users device I can't tell how much time exactly does it take to play all the frames. setTimeout also does not guarantee that function will be triggered exactly after specified time so it's kinda not my way of solving this too.
When the playing of animation is finished I want to trigger some events in code to remove the MovieClip and write some logs.
The problem is that I can't find any kind of trigger/callback that will be called when last frame of animation was rendered.
example code:
movie = new PIXI.extras.MovieClip(someFrames);
movie.animationSpeed = 1;
movie.onComplete = animationFinished;
movie.play()
animationFinished = function () {
console.log("Animation just reached it's end.");
movie.gotoAndStop(0);
};
the obvious problem is, that movie.onComplete is never called. Is there any way to make this work?
Thanks for any suggestions and ideas.
Happy coding!
movie = new PIXI.extras.MovieClip(someFrames);
movie.animationSpeed = 1;
movie.onComplete = animationFinished;
movie.loop = false;
movie.play();
animationFinished = function () {
console.log("Animation just reached it's end.");
movie.gotoAndStop(0);
};
I am currently working on a drum machine and I am using setTimeout to make it run. Here is the heart of the code:
var sequencerRun = function(){
var currentTime = 0
var starting = 200;
for(var k = 0; k < 16; k++){
$(".instrument td .beat" + k).each(function(){
setTimeout(blinker, currentTime,$(this));
})
currentTime += starting;
}
}
var timerId, setInt;
var runSeq = function(){
setInt = setInterval(sequencerRun,3200);
}
$('.play').click(function(){
stopped = false
sequencerRun();
runSeq();
})
$('.stop').click(function(){
clearInterval(setInt);
stopped = true;
})
The drum machine has a matrix HTML structure built using a table. When .play is clicked a scheduling process occurs, which is encapsulated in sequencerRun. This involves a run through the columns of my matrix to determine whether there should be a drum hit or not. This is done through blinker. The scheduling creates a check on each column 1 - 16 at times 0,200,...,3200 respectively. This is what creates the effect of a sequencer. I also have a setInterval that reruns this process every 3200, which is how it takes for a run to finish.
Programmatically my code seems to make sense and my hope was that it would execute on time. The thing is that my actual app tends to stutter a lot and is stuttering even more since I deployed it. Here is a deployed version of my app.
This stuttering side effect can be best heard when you click on a full row. My question here is can anyone tell if this side effect is a result of setTimeout's timing inconsistency and if so how could I go about fixing this? Or is this related to something else that I am missing?
I think the stuttering issue has more to do with you not preloading the instruments but rather loading them on every hit, more than it has to do with settimeout.
In any case, I think I would have solved this differently. Rather than setting a fresh timeout for each beat, create one beat timeout and put the logic in there. Something like (pseudo-code-ish, lots of stuff missing just the general idea):
var MAX_BEATS = 16; // I think you had 16 beats in your example?
var BPM = 200;
var preloadedInstruments = [];
function preloadInstruments(){
for(i of myInstruments) { // myInstruments would be a list of your instruments (probably just strings with a filename)
preloadedInstruments.push(new instrument(i)); // You need an instrument class, that would preload the sound and provide a play function
}
}
var currentbeat = 1;
function beat() {
var activeInstruments = getActiveInstruments(currentbeat); // You could cache this also for every beat, but I think a simple loop here would be quick enough
for(instrument of activeInstruments) {
preloadedInstruments[instrument].play(); // play method of the instrument class called
}
currentbeat++;
if (currentbeat > MAX_BEATS) {
currentbeat = 1;
}
}
setInterval(beat, 60e3 / BPM);
In this code, why does the css change not complete until the while loop finishes? I know a loop hangs the browser but I would have thought the css change would be synchronous and therefore finish before the while loop even starts.
Bonus Question: Is there any way for me to get that css change to complete before moving to the while loop without giving up control of the javascript thread?
function run() {
var then = +new Date()
, now
;
$('#mydiv').css('display','block');
now = + new Date();
while (now - then < 5000) {
now = +new Date();
}
}
fiddle: http://jsfiddle.net/ezVZT/2/
Browsers don't always update the page immediately. They'll often wait with updates rendered but not painted while scripts execute and batch all the repainting together.
In your code you're applying a change to the styling, but then executing a 5 second loop which will block everything. The CSS change just has to wait.
If you need to wait five seconds before doing something use a setTimeout() call, or since you're using jQuery, look at .delay().
Would something like $elem.addClass('xyz') solve your problem? you can then assign the display: block to your class in css. Maybe that would be faster?
Try the following code. It might work.
function run() {
var then = +new Date()
, now
;
$('#mydiv').css('display','block');
$("#mydiv", window.parent.document).load($("mydiv").html());
now = + new Date();
while (now - then < 5000) {
now = +new Date();
}
}
function reset() {
$('#mydiv').css('display','none');
}
I've got the following problem:
I'm using Google Maps on my site. I've attached the following eventListener to the map itself:
google.maps.event.addListener(map, 'bounds_changed', scheduleDelayedCallback);
The event bounds_changed is called every time someone drags the map. My Problem is, that it is called several times during the drag process. Now I need to find a way to call the callback function only, if it wasn't called during the last, let's say, 750 milliseconds.
I did this using these two functions:
function fireIfLastEvent() {
var now = new Date().getTime();
if (lastEvent.getTime() + 750 <= now) {
this_function_needs_to_be_delayed();
} else {
$("#main").html('Lade...');
}
}
function scheduleDelayedCallback() {
lastEvent = new Date();
setTimeout(fireIfLastEvent, 750);
}
This method works great in Chrome and Opera. In IE it works sometimes, in Firefox it never works (it calls the functions even if the 750 milliseconds haven passed).
Is there any rock-solid way to timeout a function call?
Thanks.
You shouldn't need a timeout here.
function scheduleDelayedCallback() {
var now = new Date();
if (now.getTime() - lastEvent.getTime() >= 750) {
// minimum time has passed, go ahead and update or whatever
$("#main").html('Lade...');
// reset your reference time
lastEvent = now;
}
else {
this_function_needs_to_be_delayed(); // don't know what this is.
}
}
Your explanation of what you want to happen isn't the clearest so let me know if the flow is wrong.