Start Animation (Animate CC) only when the canvas become visible after scrolling. - javascript

I have an animation (made with Adobe animate CC) that I have included into my html file. I am trying to change its original script in order to start the animation from the beginning only when it becomes visible in the viewport of the browser. Unfortunately, I searched widely but couldn't make any of the solutions I found worked for my case.
This is the original code I'm trying to change:
<html>
<head>
<script>
var canvas, stage, exportRoot, anim_container, dom_overlay_container,
fnStartAnimation;
function init() {
canvas = document.getElementById("canvas");
anim_container = document.getElementById("animation_container");
dom_overlay_container = document.getElementById("dom_overlay_container");
var comp=AdobeAn.getComposition("07578064E5C140B781D146A1AE4968A3");
var lib=comp.getLibrary();
handleComplete({},comp);
}
function handleComplete(evt,comp) {
//This function is always called, irrespective of the content. You can use the variable "stage" after it is created in token create_stage.
var lib=comp.getLibrary();
var ss=comp.getSpriteSheet();
exportRoot = new lib.Water_illustrazione_revista_scrollplay();
stage = new lib.Stage(canvas);
//Registers the "tick" event listener.
fnStartAnimation = function() {
stage.addChild(exportRoot);
createjs.Ticker.setFPS(lib.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
}
//follow a code to support hidpi screens and responsive scaling.
</script>
</head>
<body onload="init();" style="margin:0px;">
<div id="anchor5" class="Anime_p">
<div id="animation_container" style="background-color:rgba(255, 255, 255, 1.00); width:1280px; height:700px">
<canvas id="canvas" width="1280" height="700" style="position: absolute; display: block; background-color:rgba(255, 255, 255, 1.00);"></canvas>
<div id="dom_overlay_container" style="pointer-events:none; overflow:hidden; width:1280px; height:700px; position: absolute; left: 0px; top: 0px; display: block;">
</div>
</div>
</div>
</body>
</html>

You simply need to export the animation as stopped at first and then check when the div comes in browser view. Whenever it does, start the animation.
Add exportRoot.stop(); in the end of fnStartAnimation();
Check for visibility of your animation div in browser as explained here - How to tell if a DOM element is visible in the current viewport?
Whenever the condition is satisfied, add the code - exportRoot.play();

Related

Set position of <div> at runtime

On mouseover I want to move the "imgbox" to a specific absolute position (which might move it on top of the "i" image).
The second image ("newimg") loads, so that part works (including hiding it again in "onmouseout") but it's displayed below everything (like in the HTML code). It seems like setting imgbox.style.left and imgbox.style.top doesn't do anything. If I set "margin" instead, the image is displayed 200px to the right and 200px down from where it originally was (but still below everything else).
What did I miss? How do I move the "imgbox" at runtime with regular Javascript (no JQuery please!)?
function onHoverIn(url) {
var imgbox = document.getElementById("imgbox");
imgbox.style.visibility='visible';
var newimg = document.createElement("img");
newimg.src = url;
var oldimg = document.getElementById("i");
/*if(oldimg.addEventListener){ //Removed so the snippet'll run
oldimg.addEventListener('mouseout',onHoverOut,false);
} else {
oldimg.attachEvent('onmouseout',onHoverOut);
}*/
imgbox.innerHTML='';
imgbox.appendChild(newimg);
imgbox.style.left = '200px';
imgbox.style.top = '200px';
//imgbox.style.marginLeft = '200px';
//imgbox.style.marginTop = '200px';
}
#imgbox {
position : absolute;
border: 1px solid #999;
background : #FFFFFF;
filter: Alpha(Opacity=100);
visibility : hidden;
z-index : 50;
overflow : hidden;
}
<img id="i" src="https://i.pinimg.com/originals/53/02/a4/5302a4c318139bf5753c433b1f4c6aa8.jpg" alt="DP" onmouseover="onHoverIn('https://i.pinimg.com/originals/b2/1b/07/b21b0738ea390fc56a4d3efe76ab88de.jpg')">
<p>Long Teeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeext<br><br><br><br><br>END TEEEEEEEEEEEXT</p>
<div id="imgbox"></div>
Sorry, the images are pretty big, so not sure how well it'll work. I tested the code with Firefox 85.0, Chrome 88, IE and Edge by simply double-clicking the .html file and the positioning doesn't work properly in any of them.
This was quite a bit harder than I thought it would be, made some changes to your code. Hope this still works for you.
NOTE: I implemented an onHoverOut locally and noticed that when I moved my mouse around on the image it would flicker. This happens because the new image is loaded and once moving again the old image registers a onHoverOut (because you hover on top of the new image) which would then remove the new image, at which point the old image registers the onmouseover again and adds the new image. This would keep looping for as long a you move the mouse around.
function onHoverIn(url) {
var imgbox = document.getElementById("imgbox");
imgbox.style.visibility='visible';
var newimg = document.createElement("img");
newimg.src = url;
var oldimg = document.getElementById("i");
if(oldimg.addEventListener){
oldimg.addEventListener('mouseout',onHoverOut,false);
} else {
oldimg.attachEvent('onmouseout',onHoverOut);
}
//imgbox.innerHTML='';
imgbox.appendChild(newimg);
}
function onHoverOut() {
console.log('onHoverOut: not implemented');
}
.article{
width:640px;
padding:0 16px;
}
.image-box{
position:relative;
width:100%;
height:0;
/* 16:9 */
padding-top:56.25%;
overflow:hidden;
}
.image-box img{
position:absolute;
top:0;
width:100%;
}
<div class="article">
<p>content before..</p>
<div id="imgbox" class="image-box">
<img id="i" src="https://i.pinimg.com/originals/53/02/a4/5302a4c318139bf5753c433b1f4c6aa8.jpg" alt="DP" onmouseover="onHoverIn('https://i.pinimg.com/originals/b2/1b/07/b21b0738ea390fc56a4d3efe76ab88de.jpg')">
</div>
<p>content after..</p>
</div>

Creating a fading image in JavaScript by changing opacity over a period of time

I am new to JavaScript. I am really intrigued to figure out an easy technique for changing the opacity of an image that is laying on top of another image to reveal that bottom image gradually. I want to do this by fading out. In other words subtracting from the style.opacity property gradually after each second passes with time.
I came up with the following but it doesn't seem to work for me.
The current state of my code changes the opacity suddenly goes from 1 to the negatives (-0.1, -0.2, -0.3, etc). Which basically does a transition from the top image immediately to revealing the bottom one.
I want to gradually go from opacity of 1 to (0.9, 0.8, 0.7, etc) as each second passes.
I want to accomplish this in pure JavaScript. I found something similar in CSS but I don't want to use that approach.
I assume that (var currentOp = document.getElementById('guitar2').style.opacity;) treats the currentOp variable as a string. Because of this I tried a combination of parsing to float, making the subtraction and changing back to string, setting the opacity gradually over time to not avail.
<!DOCTYPE>
<html>
<head>
<style>
#guitar1
{
position: relative;
top: 0;
left: 0;
}
#guitar2
{
position: absolute;
top: 0px;
left: 0px;
opacity: 1;
}
</style>
</head>
<body onload="runTime()">
<script>
var timer;
function reduceOpacity()
{
var op = document.getElementById('guitar2');
var currentOp = document.getElementById('guitar2').style.opacity;
//currentOp = (parseFloat(currentOp) - 0.1).toString();
currentOp -= 0.1;
op.style.opacity = currentOp;
}
function runTime()
{
timer = setInterval(reduceOpacity, 1000);
}
</script>
<h4 id="header">Gibson Les Paul</h4>
<div style="position: relative; left: 0; top: 0;">
<img src="gibson1.png" id="guitar1" width="500" />
<img src="gibson2.png" id="guitar2" width="500" />
</div>
<button type="button" onclick='document.getElementById("header").innerHTML = "yea"'>Click Me!</button>
</body>
</html>
Use getComputedStyle and getPropertyValue to retrieve an accurate representation of the element's styling on load.
style.property has a habit of not being up to date, will sometimes pull default values inexplicably, and many values aren't able to be grabbed until they are set. If you console.log(op.style.opacity) in your original example you'll see that it pulls an empty string and then counts down from there after transposing it to 0.
You then use clearInterval to stop the function from continuously running after that point.
//get the style value with getComputedStyle, which is an accurate representation of
//all element styling on load.
var currentOp = getComputedStyle(op).getPropertyValue("opacity");
// clear the interval if opacity is less than or equal to 0
if(currentOp <= 0) clearInterval(timer);
console.log(currentOp);
<!DOCTYPE>
<html>
<head>
<style>
#guitar1
{
position: relative;
top: 0;
left: 0;
}
#guitar2
{
position: absolute;
top: 0px;
left: 0px;
opacity: 1;
}
</style>
</head>
<body onload="runTime()">
<script>
var timer;
function reduceOpacity()
{
var op = document.getElementById('guitar2');
//get the style value with getComputedStyle, which is an accurate representation of
//all element styling on load.
var currentOp = getComputedStyle(op).getPropertyValue("opacity");
// clear the interval if opacity is less than or equal to 0
if(currentOp <= 0) clearInterval(timer);
console.log(currentOp);
//currentOp = (parseFloat(currentOp) - 0.1).toString();
currentOp -= 0.1;
op.style.opacity = currentOp;
}
function runTime()
{
timer = setInterval(reduceOpacity, 1000);
}
</script>
<h4 id="header">Gibson Les Paul</h4>
<div style="position: relative; left: 0; top: 0;">
<img src="gibson1.png" id="guitar1" width="500" />
<img src="data:image/png;base64,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" id="guitar2" width="500" />
</div>
<button type="button" onclick='document.getElementById("header").innerHTML = "yea"'>Click Me!</button>
</body>
</html>
Note: I had to replace your image since it's a local file.
I have an alternative if your heart isn't set on JavaScript. Animate.css is an incredible stylesheet that will do the same thing in a much easier fashion. (Plus it's pure CSS so much better and more uniform support)
Import this in the head
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css" />
Then here is your according code:
<div style="position: relative; left: 0; top: 0;">
<img src="gibson1.png" id="guitar1" width="500" />
<img src="gibson2.png" id="guitar2" class="animated fadeOut delay-5s" style="animation-duration: 3s;" width="500" />
</div>
May not be quite the answer you're looking for but it is so much easier to do then JS + JQ animations.
All the best!

centering videojs vertically on a page?

Context: Electron desktop app using Timeline.js which is embedding Video.js through an iFrame. The iFrame source is below.
I've been struggling with this for a few hours now: I need to vertically center the Video.js instance in the iFrame it is within. I can't hardcode values because the app (not only videojs) can go full screen.
Using the "brute force" CSS below, it "works" but obviously the black bars are not acceptable. I removed that an added a ref to the vjs vjs-16-9 CSS and it works great: sets up size based on content, resizes in full screen mode – all good except that I haven't been able to figure out how to center the vjs instance vertically in the iFrame.
Probably something simple but I'm new at all this.
.video-js {
position: absolute;
top: 0;
left: 0;
width: 100%!important;
height: 100%!important;
}
Using vjs-16-9 CSS
iFrame source
<!DOCTYPE html>
<html lang="en">
<head>
<title>Video.JS Example</title>
<link href="../node_modules/video.js/dist/video-js.min.css" rel="stylesheet">
<script src="../node_modules/video.js/dist/video.min.js"></script>
<style>
html, body {
height:100%;
width:100%;
padding: 0px;
margin: 0px;
}
</style>
</head>
<body>
<div>
<video id="videoPlayer" class="video-js vjs-default-skin vjs-16-9" controls preload="auto">
</video>
</div>
<script>
function getParamValue(paramName) {
var url = window.location.search.substring(1);
var qArray = url.split('&');
for (var i = 0; i < qArray.length; i++) {
var pArr = qArray[i].split('=');
if (pArr[0] == paramName)
return pArr[1];
}
}
// grap the video & poster frame refs from url
var videoSrc = getParamValue('videoSrc');
videoSrc = "assets/videos/" + videoSrc;
var poster = getParamValue('poster');
poster = "assets/images/" + poster;
videojs("videoPlayer", {}, function () {
this.src(videoSrc);
this.poster(poster);
this.load();
});
</script>
</body>
</html>
Finally found a solution which doesn't seem fragile: Vertical align anything with just 3 lines of CSS.
Assigned to the div containing the videojs instance
.centerVertically {
position: relative;
top: 50%;
transform: translateY(-50%);
}
<div class="centerVertically">
<video id="videoPlayer" class="video-js vjs-default-skin vjs-16-9" controls preload="auto">
</video>
</div>
Most likely , iframe has its own styling by its own. Hence , brute force Css is needed. But to answer your question regarding aligning center for your iframe. You might want to explore more on using flex , justify content, justify center.
There are also other alternative such as using float but float is not a good practice to use unless you really have no choice of using it. The reason is. Float might react differently and mess up the alignment at certain occasions ..
I hope my information helps.
Cheers.

Javascript: Smoke-Logo effect

I am trying to make a logo to have smoke all over it. I bummped into this jsfiddle:
http://jsfiddle.net/jonnyc/Ujz4P/5/ and now I am trying to change it so it goes over a logo
however it doesn't want to work.
index.html
<html>
<head>
<title>Smoke</title>
<style>
.container
{
width: 360px;
height: 200px;
border: 2px solid black;
}
</style>
<script type="text/javascript" src="smoke_effect.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<div class="container">
<img id="smoke-logo" src="images.jpg"/>
</div>
</body>
</html>
and all of the javascript on the left hand side in the jsfiddle I paste it in a docment called smoke_effect.js however I haven't change the code at all I just change the tag from "myCanvas" to "smoke-logo".
I made 2 big changes to your fiddle
I changed the CSS to read:
#myCanvas{
background:transparent;
}
and the draw function, instead of filling with semi-transparent black, just clears canvas.
// The function to draw the scene
function draw() {
// Clear the drawing surface and fill it with a black background
//context.fillStyle = "rgba(0, 0, 0, 0.5)";
//context.fillRect(0, 0, 400, 400);
context.clearRect(0,0,400,400);
// Go through all of the particles and draw them.
particles.forEach(function(particle) {
particle.draw();
});
}
This will allow you to put an image behind the smoke.

Animate photo (or div) inside a frame div

The picture is pretty much explanatory by itself. The div "behind" contains a bunch of little square photos that I want to animate smoothly. I'm really not good with jQuery animations, could anyone help me out with this?
(Window is fixed, pictures move "inside" it, animating forever since the page load)
You could do something like this
markup:
<div id="mask">
<img id="pic" alt="my img" src="http://www.destination360.com/north-america/us/idaho/images/s/idaho-sawtooth-mountains.jpg">
</div>
css:
#mask{
overflow:hidden;
width:100px;
height:100px;
position:absolute;
border:5px solid #000000;
}
#mask img{
border:none;
position:absolute;
}
js:
$('#pic').animate({left:-200},3000).animate({top:-50},3000); /* and so on... */
fiddle:
http://www.jsfiddle.net/steweb/YHAZ9/
Edit (looping it forever) http://www.jsfiddle.net/steweb/YHAZ9/4/
I'm a fan of SIN/COS functions, so let me share with you my shot at this problem.
The idea is to have a function that runs forever, and as soon as possible so that the animation is smooth. I use a sin/cos functions to determine the new x (left) and y (top) coordenates of the div, and I have a series of parameters that allow the configuration of the speed and range of the animation.
Just paste this into an HTML file and test it in your browser.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
</head>
<body>
<div id="stuff" style="background: red; width: 200px; height: 200px; margin: auto; position: relative;">
a b c<br />
d e f<br />
g h i<br />
j k l<br />
</div>
<script>
var start = new Date();
var x_speed = 0.001, // bigger ---> faster
y_speed = 0.01, // bigger ---> faster
x_multiplier = 300, // how far away I can go on the X axis
y_multiplier = 20, // how far away I can go on the Y axis
x_offset = 0,
y_offset = 0;
function animate() {
var now = new Date();
var elapsed_time = now - start;
var x = Math.sin((elapsed_time)*x_speed) * x_multiplier + x_offset;
var y = Math.cos((elapsed_time)*y_speed) * y_multiplier + y_offset;
$("#stuff").css({
left : x,
top : y
});
setTimeout(animate, 0);
}
setTimeout(animate, 76);
</script>
</body>
</html>
For how long? After a click?
I'm not behind my own computer right now, but try something like this:
This is for after a click:
$("#frame").click(
function(){
$("#photo").animate({"left": "-=100px"}, function(){
$("#photo").animate({"top": "-=100px"}, function(){
$("#photo").animate({"left": "=100px"});
});
});
});
And so forth, after each line you can put a new line, like i did in line 3 and 4 from the code. This way the photo behind moves in a square.
Just a suggestion, don't know if this is exactly what you want.
EDIT: Btw, you can only go left, right or up and down, what might smoothen your animation is to grow the photo and shrink it. Therefore you need for instance the "width" parameter.
Check the jQuery site here.

Categories