jQuery window in/out of view handler - javascript

I want to stop the animation on an HTML page once it is out of view
I tried to use
$(window).focus(function () {
// start animation
}).blur(function () {
// stop animation
});
but this code also stops the animation if it is the background of another window.
Is there an handler for window in/out of view in JS or jQuery?
i.e. something like:
$(window).windowInView(function () {
// start animation
}).windowOutView(function () {
// stop animation
});

There's two ways:
window.requestAnimationFrame()
example taken/modified from linked page
<div id="rec" style="width: 5px; height: 5px; background: black;"></div>
var start = null;
var left=false;
var element = document.getElementById('rec');
element.style.position = 'absolute';
function step(timestamp) {
if (!start) start = timestamp;
if(!left){
var progress = timestamp - start;
element.style.left = Math.min(progress / 10, 600) + 'px';
if (progress < 6000) {
window.requestAnimationFrame(step);
}else{
start = timestamp;
left = true;
window.requestAnimationFrame(step);
}
}else{
var progress = (start+6000)-timestamp;
element.style.left = Math.max(progress / 10, 0) + 'px';
if (progress > 0) {
window.requestAnimationFrame(step);
}else{
start = timestamp;
left=false;
window.requestAnimationFrame(step);
}
}
}
or Page Visibility API
document.addEventListener("visibilitychange", function(){
if (document.hidden) {
console.log('hidden');
}else{
console.log('visible');
}}, false);

Related

Measure scroll velocity Javascript and trigger event

I would like to trigger an event when the window scroll velocity goes above a certain value. I found some code that will help measure the velocity but I can't work out why the if statement is not triggered when the speed goes above 150. Any help would be greatly appreciated.
const checkScrollSpeed = (function(settings){
settings = settings || {};
let lastPos, newPos, timer, delta,
delay = settings.delay || 50;
function clear() {
lastPos = null;
delta = 0;
}
clear();
return function(){
newPos = window.scrollY;
if ( lastPos != null ){ // && newPos < maxScroll
delta = newPos - lastPos;
}
lastPos = newPos;
clearTimeout(timer);
timer = setTimeout(clear, delay);
return delta;
};
})();
const container = document.querySelector('#container');
window.addEventListener('scroll', function() {
console.log(checkScrollSpeed());
if (checkScrollSpeed() > 150) {
console.log('150+')
container.classList.add('red');
}
});
#container {
width: 75%;
height: 170vh;
background-color: yellow;
}
#container.red {
background-color: red !important;
}
<div id="container"></div>
You are calling checkScrollSpeed in succession and when it's called the second time delta is 0. Either remove the console.log or assign delta to some variable and use that for logging and the condition.
I think it's because you have a little delay between the first time you call checkScrollSpeed() in your console.log and then in your if statement. You can try to call it only once and save the value for your console.log and if statement. It works for me with this solution:
const checkScrollSpeed = (function(settings) {
settings = settings || {};
let lastPos, newPos, timer, delta,
delay = settings.delay || 50;
function clear() {
lastPos = null;
delta = 0;
}
clear();
return function() {
newPos = window.scrollY;
if (lastPos != null) { // && newPos < maxScroll
delta = newPos - lastPos;
}
lastPos = newPos;
clearTimeout(timer);
timer = setTimeout(clear, delay);
return delta;
};
})();
const container = document.querySelector('#container');
window.addEventListener('scroll', function() {
var speed = checkScrollSpeed();
console.log(speed);
if (speed > 150) {
console.log('150+');
container.classList.add('red');
}
});
#container {
width: 75%;
height: 170vh;
background-color: yellow;
}
#container.red {
background-color: red !important;
}
<div id="container"></div>

Javascript Frame Animation Flashing on Load

Here is the CodePen of the animation. It flashes for the first cycle of the frames displayed. Is there a way to stop this from happening?
Any help would be very much appreciated!
let frames = [
"http://i.imgur.com/QhvQuaG.png",
"http://i.imgur.com/VjSpZfB.png",
"http://i.imgur.com/Ar1czX0.png",
"http://i.imgur.com/ROfhCv4.png",
"http://i.imgur.com/6B32vk7.png",
"http://i.imgur.com/2t5MWOL.png",
"http://i.imgur.com/a9wLBbc.png",
"http://i.imgur.com/OBKcW8f.png",
"http://i.imgur.com/RC6wLgw.png",
"http://i.imgur.com/2HyI8yS.png"];
let startframe = 0;
function arrow(){
let start = Date.now();
let timer = setInterval(function() {
let timePassed = Date.now() - start;
if (timePassed >= 20000) {
clearInterval(timer); // finish the animation after 2 seconds
return;
}
move();
}, 200);
}
function move(){
if (startframe==(frames.length-1)){
startframe=0;
} else {
startframe++;
}
// document.getElementById('continue').style.backgroundSize = "100%";
document.getElementById('continue').style.background = "url(" + frames[startframe] +")";
document.getElementById('continue').style.backgroundSize = "100%";
}
#continue {
width: 80px;
height:40px;
}
<div onclick = "arrow()">Start</div>
<div id="continue"></div>
If you look at the network tab of your browser dev tools, you'll see that the flashing happens when the browser is loading the images.
You should preload all the images before starting the animation, like so:
let frames = [
"http://i.imgur.com/QhvQuaG.png",
"http://i.imgur.com/VjSpZfB.png",
"http://i.imgur.com/Ar1czX0.png",
"http://i.imgur.com/ROfhCv4.png",
"http://i.imgur.com/6B32vk7.png",
"http://i.imgur.com/2t5MWOL.png",
"http://i.imgur.com/a9wLBbc.png",
"http://i.imgur.com/OBKcW8f.png",
"http://i.imgur.com/RC6wLgw.png",
"http://i.imgur.com/2HyI8yS.png"
]
var startframe = 0
var images = [] // This array will contain all the downloaded images
function preloadImages() {
var loaded = 0
for (i = 0; i < frames.length; i++) {
images[i] = new Image();
images[i].onload = function() {
loaded += 1
if (loaded >= frames.length) {
arrow()
}
}
images[i].src = frames[i]
}
}
function arrow(){
let start = Date.now();
let timer = setInterval(function() {
let timePassed = Date.now() - start;
if (timePassed >= 20000) {
clearInterval(timer) // finish the animation after 2 seconds
return;
}
move()
}, 200)
}
function move() {
var c = document.getElementById('continue')
c.innerHTML = '' // remove the content of #continue
// Insert the already exiting image from the images array
// into the container instead of downloading again with css
c.append(images[startframe])
if (startframe >= frames.length - 1) {
startframe = 0
}
else {
startframe++
}
}
#continue {
width: 80px;
height:40px;
}
#continue > img {
max-width: 100%;
}
<div onclick = "preloadImages()">Start</div>
<div id="continue"></div>
This is because the images need to be loaded when viewed for the first time. It is possible to pre-load images in different ways. Here are three ways to preload images.

image animation issue when clicking a button

I have this code:
function CreateAndAnimateEnemyImg() {
var nh = Math.floor(Math.random() * w + 30);
var enemy = document.createElement('img');
enemy.src = 'enemy.jpg';
enemy.className = 'Enemy';
pane.append(enemy);
enemy.onload = function () {
enemy.style.top = nh + 'px';
}
}
$("#Start").click(function () {
var x = setInterval(function () {
CreateAndAnimateEnemyImg();
$('.Enemy').animate({ 'left': '-=20px' });
time--;
}, 20);
if (time == 0) {
timeElapsed = true;
clearInterval(x);
}
});
And this is the jsfiddle
I know my logic is wrong and I want u to help me to fix my problem on click an new image should be created and animated and a a counter should be initialize when the counter is set to 0 the creation of the new images should be stopped but the created images should still animate to left -20px
i have changed the position of the clear interval and adde some condition check
if (time > 0) {
$('.Enemy').animate({ 'left': '-=20px' });
time--;
console.log(time);
if(time == 0){
timeElapsed = true;
clearInterval(x);
}
}
check here Fiddle
Modified the Start click handler little bit. Enemy animate is moved to its own timer and inside the create new enemies interval added check to see if created time reached max.
Here is the new code, updated fiddle demo
$("#Start").click(function () {
intervalPoint = setInterval(function () {
CreateAndAnimateEnemyImg();
time--;
if (time == 0)
StopTimer();
}, 20);
setInterval(function () {
$('.Enemy').animate({ 'left': '-=20px' });
}, 20);
});
function StopTimer(){
timeElapsed = true;
clearInterval(intervalPoint);
time = 3;
}

modifying a sliding javascript div

I got some code off the net to make a box slide in. However it slid in from the top left and I wanted it to slide in from the bottom. I changed the css position from top:-200px to bottom:-200px and changed the part of the code that alters the position from
{
popup.style.top = (currentTop + speed) + "px";
keepMoving = true;
}
to
{
popup.style.bottom = (currentTop + speed) + "px";
keepMoving = true;
}
now it doesn't work. I cannot see what variable I should be making. Here is the full code (which works if I change them back to 'top')
<html>
<head>
<title>Moving Pop Up Samplet</title>
<style>
#popup
{
height:200px;
width:200px;
border:1px solid #000;
background:#CC9900;
position:absolute;
bottom:-200px;
left:-200px;
}
</style>
<script>
var timer = null;
var speed = 3; //1 is slow
var endTop = 0;
var endLeft = 0;
//******************************************************
// Simple little function to get Elements as an object
//******************************************************
function getEl(id)
{
var el = document.getElementById(id);
return el;
}
//******************************************************
// Function to show Elements
//******************************************************
function showEl(id)
{
getEl(id).style.display ="";
}
//******************************************************
// Function to hide Elements
//******************************************************
function hideEl(id)
{
getEl(id).style.display ="none";
}
//******************************************************
// Function to move Element
//******************************************************
function moveEl(id)
{
var popup = getEl(id);
var currentTop = parseInt(popup.offsetTop);
var currentLeft = parseInt(popup.offsetLeft);
var keepMoving = false;
//Move
if (currentTop <= endTop)
{
popup.style.bottom = (currentTop + speed) + "px";
keepMoving = true;
}
if(currentLeft <= endLeft)
{
popup.style.left = (currentLeft + speed) + "px";
keepMoving = true;
}
if (keepMoving)
{
startMove(id);
}
else
{
endMove();
}
}
//******************************************************
// Function to start the move
//******************************************************
function startMove(id)
{
timer = setTimeout("moveEl('"+id+"')", 1);
}
//******************************************************
// Function to end the move
//******************************************************
function endMove()
{
clearTimeout(timer);
}
</script>
</head>
<body onload="startMove('popup');">
<!-- POP UP DIV -->
<div id="popup">
<center><span onclick="hideEl('popup');" style="cursor:pointer;"> Close</span></center>
</div>
<!--END POP UP DIV -->
<center><span onclick="startMove('popup');" style="cursor:pointer;"> Show Pop Up</span></center>
</body>
</html>
You'll just need to rejiggle your inequalities a bit.
Given that there's no offset bottom property in javascript, it'll be easier to still work with top values, even if you want to come in from the bottom.
function moveEl(id) {
var popup = getEl(id);
var currentTop = parseInt(popup.offsetTop);
var currentLeft = parseInt(popup.offsetLeft);
var keepMoving = false;
//Move
if (currentTop >= endTop) {
popup.style.top = (currentTop - speed) + "px";
keepMoving = true;
}
if (currentLeft <= endLeft) {
popup.style.left = (currentLeft + speed) + "px";
keepMoving = true;
}
if (keepMoving) {
startMove(id);
}
else {
endMove();
}
}
Here's a working jsFiddle.
If you think about the way the function is checking to see if it's finished yet, and adding on the speed variable each time, you should be able to step through the original version compared to this and see how the logic is working.
Instead writing something from scratch consider using jQuery's slideToggle method.

change an image onload

I have a simple webpage with an image in a div on the homepage and would like to use javascript to change the image for an alternative image after the page has loaded (only once) using a slow fade, i am currently using an animated gif to do this but would prefer to use javascript.
I have limited javascript skills.
thanks
I'm assuming that you won't use jQuery so i've created simple js eample which fades out one image and fades in other after page is loaded. You can check the example here http://jsfiddle.net/rJzPV/7/
function fadeOut(elem, time, callbackFn) {
var startOpacity = elem.style.opacity || 1;
elem.style.opacity = startOpacity;
(function go() {
elem.style.opacity -= startOpacity / (time / 100);
// for IE
elem.style.filter = 'alpha(opacity=' + elem.style.opacity * 100 + ')';
if (elem.style.opacity > 0.11)
setTimeout(go, 100);
else {
elem.style.display = 'none';
if (callbackFn)
callbackFn();
}
})();
}
function fadeIn(elem, time) {
var startOpacity = 0.1;
elem.style.opacity = startOpacity;
elem.style.display = "";
(function go() {
elem.style.opacity -= -startOpacity / (time / 1000);
// for IE
elem.style.filter = 'alpha(opacity=' + elem.style.opacity * 100 + ')';
if (elem.style.opacity < 1)
setTimeout(go, 100);
})();
}
window.addEvent('load', function () {
function changePicture() {
var _myImg = document.getElementById("myImage");
_myImg.src = "http://www.google.com/logos/2012/klimt12-hp.jpg";
fadeIn(_myImg, 1000);
}
var _myImg = document.getElementById("myImage");
fadeOut(_myImg, 1000, changePicture);
});

Categories

Resources