I want a Scroll-Based Animation with image sequences like this:
https://www.wayoutintl.com/
when visit above link ,see section-3 when we scroll down, beach image move from day to night. This animation seems scroll smoothly. my animation scroll smoothly on local and when i put same code on server,sequences images choppy on scroll. not smoothly work on scroll. So what should i do now ? Please help me ..... thanks in advance.... below is my code....
// define images
var images = [
"imgs/0001/0001-compress2.jpg",
"imgs/0001/0002-compress2.jpg",
"imgs/0001/0003-compress2.jpg",
"imgs/0001/0004-compress2.jpg",
"imgs/0001/0005-compress2.jpg",
"imgs/0001/0006-compress2.jpg",
"imgs/0001/0007-compress2.jpg",
"imgs/0001/0008-compress2.jpg",
"imgs/0001/0009-compress2.jpg",
"imgs/0001/0010-compress2.jpg",
"imgs/0001/0011-compress2.jpg",
"imgs/0001/0012-compress2.jpg",
"imgs/0001/0013-compress2.jpg",
"imgs/0001/0014-compress2.jpg",
"imgs/0001/0015-compress2.jpg",
"imgs/0001/0016-compress2.jpg",
"imgs/0001/0017-compress2.jpg",
"imgs/0001/0018-compress2.jpg",
"imgs/0001/0019-compress2.jpg",
"imgs/0001/0020-compress2.jpg",
"imgs/0001/0021-compress2.jpg",
"imgs/0001/0022-compress2.jpg",
"imgs/0001/0023-compress2.jpg",
"imgs/0001/0024-compress2.jpg",
"imgs/0001/0025-compress2.jpg",
"imgs/0001/0026-compress2.jpg",
"imgs/0001/0027-compress3.jpg",
"imgs/0001/0028-compress3.jpg",
"imgs/0001/0029-compress3.jpg",
"imgs/0001/0030-compress3.jpg",
"imgs/0001/0031-compress3.jpg",
"imgs/0001/0032-compress3.jpg",
"imgs/0001/0033-compress3.jpg",
"imgs/0001/0034-compress3.jpg",
"imgs/0001/0035-compress3.jpg",
"imgs/0001/0036-compress3.jpg",
"imgs/0001/0037-compress3.jpg",
"imgs/0001/0038-compress3.jpg",
"imgs/0001/0039-compress3.jpg",
"imgs/0001/0040-compress3.jpg",
"imgs/0001/0041-compress3.jpg",
"imgs/0001/0042-compress3.jpg",
"imgs/0001/0043-compress3.jpg",
"imgs/0001/0044-compress3.jpg",
"imgs/0001/0045-compress3.jpg",
"imgs/0001/0046-compress3.jpg",
"imgs/0001/0047-compress3.jpg",
"imgs/0001/0048-compress3.jpg",
"imgs/0001/0049-compress3.jpg",
"imgs/0001/0050-compress3.jpg",
"imgs/0001/0051-compress3.jpg",
"imgs/0001/0052-compress3.jpg",
"imgs/0001/0053-compress3.jpg",
"imgs/0001/0054-compress3.jpg",
"imgs/0001/0055-compress3.jpg",
"imgs/0001/0056-compress3.jpg",
"imgs/0001/0057-compress3.jpg",
"imgs/0001/0058-compress3.jpg",
"imgs/0001/0059-compress3.jpg",
"imgs/0001/0060-compress3.jpg",
"imgs/0001/0061-compress3.jpg",
"imgs/0001/0062-compress3.jpg",
"imgs/0001/0063-compress3.jpg",
"imgs/0001/0064-compress3.jpg",
"imgs/0001/0065-compress3.jpg",
"imgs/0001/0066-compress3.jpg",
"imgs/0001/0067-compress3.jpg",
"imgs/0001/0068-compress3.jpg",
"imgs/0001/0069-compress2.jpg",
"imgs/0001/0070-compress3.jpg",
"imgs/0001/0071-compress3.jpg",
"imgs/0001/0072-compress2.jpg",
"imgs/0001/0073-compress3.jpg",
"imgs/0001/0074-compress3.jpg",
"imgs/0001/0075-compress3.jpg",
"imgs/0001/0076-compress2.jpg",
"imgs/0001/0077-compress2.jpg",
"imgs/0001/0078-compress2.jpg",
"imgs/0001/0079-compress3.jpg",
"imgs/0001/0080-compress3.jpg"
];
// TweenMax can tween any property of any object. We use this object to cycle through the array
var obj = {curImg: 0};
// create tween
var tween = TweenMax.to(obj, 0.5,
{
curImg: images.length - 1, // animate propery curImg to number of images
roundProps: "curImg", // only integers so it can be used as an array index
repeat: 0, // repeat 3 times
immediateRender: true, // load first image automatically
ease: Linear.easeNone, // show every image the same amount of time
onUpdate: function () {
$("#myimg").attr("src", images[obj.curImg]); // set the image source
}
}
);
// init controller
var controller = new ScrollMagic.Controller();
// build scene
var scene = new ScrollMagic.Scene({triggerElement: "#trigger", duration: 800})
.setTween(tween)
.addTo(controller);
<div class="image-seq">
<section class="demo">
<div class="spacer s0" id="trigger"></div>
<div id="imagesequence">
<img id="myimg" class="lazy"/><br>
</div>
</section>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.0/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/ScrollMagic.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/plugins/animation.gsap.min.js"></script>
<script type="text/javascript" src="js/as.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazyload/1.9.7/jquery.lazyload.js"></script>
</body>
When you scroll, you are queuing up the images (maybe many) to be loaded on the next requestAnimationFrame which is why it works ok on local, but not when on a server.
Some of the images are fairly large (the stadium ones are around 150kB each, and you seem to have over 300 of them). The total page size is around 65MB.
Things to try:
Preload the images before initializing the scroller.
Reduce the amount of images and maybe their size.
Try using webP images to reduce their size.
Use vanilla JS to set the image source instead of jQuery.
Use the browser dev tools (network and performance tabs) to check where you bottlenecks are. It might be helpful to set the throttling to 3g so you can test performance on your local version.
Related
I am using Bodymovin in combination with ScrollMagic and GSAP to animate through series of images as you scroll back and forth. Everything works great, except, when I reach the end it doesn't stay on the final image, but goes white.
Libraries that I load first:
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.5.9/lottie.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/ScrollMagic.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/animation.gsap.js"></script>
Then my code:
var controller = new ScrollMagic.Controller();
var animation = bodymovin.loadAnimation({
container: document.getElementById('hero-anim'),
animationData: animationframes,
renderer: 'svg',
autoplay: false,
});
var tl = new TimelineMax();
tl.to({frame:0}, 1, {
frame: animation.totalFrames-1,
onUpdate:function(){
animation.goToAndStop((Math.round(this.progress() * 60)), true)
},
ease: Linear.easeNone
})
var lottieScene = new ScrollMagic.Scene({
duration: '100%',
offset: 600
})
.setPin("#hero-anim")
.setTween(tl)
.addTo(controller);
Any ideas what could be causing that? Looking at browser's Inspect Element, it basically adds display:block to the image that is supposed to be currently visible and applies display:none to the previous image, but at the end, they all have display:none, and it doesn't stay visible
RESOLVED
As Zach pointed out, I tried Math.floor and at first it didn't help, but afterwards I tried adjusting animation.goToAndStop((Math.floor(this.progress() * 60)), true) to * 59 (one frame less than the total frame count and now it works, perfectly. Math.round with * total frame count or even * total frames - 1 didn't work, strangely.
I have purchase the Megazoom Image Viewer and want to add featured image dynamically in Megazoom Image Viewer jQuery script bellow, Please help me how can I use this script, here is the script of jQuery.
<div id="productHolder"></div>
<script type="text/javascript">
var megazoom;
FWDUtils.onReady(function(){
init();
setupZoomer("round_silver_graphics/imageToZoom.jpg", "megazoomPlayList", "round_silver_graphics/navigatorImage.jpg", 4324, 2530);
});
function setupZoomer(imagePath, playListAndSkinId, navigatorImagePath, imageWidth, imageHeight){
if(megazoom){
megazoom.destroy();
megazoom = null;
}
megazoom = new FWDMegazoom({
//----main----//
parentId:"productHolder",
playListAndSkinId:playListAndSkinId,
displayType:"responsive",
skinPath:"skin_round_silver/skin/",
imagePath:imagePath,
preloaderText:"Loading image...",
useEntireScreen:"yes",
addKeyboardSupport:"yes",
addDoubleClickSupport:"yes",
imageWidth:imageWidth,
imageHeight:imageHeight,
zoomFactor:1.4,
doubleClickZoomFactor:1,
startZoomFactor:"default",
panSpeed:8,
zoomSpeed:.1,
backgroundColor:"#FFFFFF",
preloaderFontColor:"#585858",
preloaderBackgroundColor:"#FFFFFF",
//----lightbox-----//
lightBoxWidth:800,
lightBoxHeight:550,
lightBoxBackgroundOpacity:.8,
lightBoxBackgroundColor:"#000000",
//----controller----//
buttons:"moveLeft, moveRight, moveDown, moveUp, scrollbar, hideOrShowMarkers, hideOrShowController, info, fullscreen",
buttonsToolTips:"Move left, Move right, Move down, Move up, Zoom level: , Hide markers/Show markers, Hide controller/Show controller, Info, Full screen/Normal screen",
controllerPosition:"bottom",
inversePanDirection:"yes",
startSpaceBetweenButtons:10,
spaceBetweenButtons:10,
startSpaceForScrollBarButtons:20,
startSpaceForScrollBar:6,
hideControllerDelay:3,
controllerMaxWidth:800,
controllerBackgroundOpacity:1,
controllerOffsetY:3,
scrollBarOffsetX:0,
scrollBarHandlerToolTipOffsetY:4,
zoomInAndOutToolTipOffsetY:-4,
buttonsToolTipOffsetY:0,
hideControllerOffsetY:2,
buttonToolTipFontColor:"#585858",
//----navigator----//
showNavigator:"yes",
navigatorImagePath:navigatorImagePath,
navigatorPosition:"topright",
navigatorOffsetX:6,
navigatorOffsetY:6,
navigatorHandlerColor:"#FF0000",
navigatorBorderColor:"#FFFFFF",
//----info window----//
infoWindowBackgroundOpacity:.6,
infoWindowBackgroundColor:"#FFFFFF",
infoWindowScrollBarColor:"#585858",
//----markers-----//
showMarkersInfo:"no",
markerToolTipOffsetY:2,
//----context menu----//
showScriptDeveloper:"no",
contextMenuLabels:"Move left, Move right, Move down, Move up, Zoom in/Zoom out, Hide markers/Show markers, Hide controller/Show controller, Info, Full screen/Normal screen",
contextMenuBackgroundColor:"#d1cfcf",
contextMenuBorderColor:"#8f8d8d",
contextMenuSpacerColor:"#acacac",
contextMenuItemNormalColor:"#585858",
contextMenuItemSelectedColor:"#FFFFFF",
contextMenuItemDisabledColor:"#b7b4b4"
});
}
</script>
that i don't know if it's even possible. I wanna try to load content with Ajax, and animate it right away, piece by piece. I have empty body. And on server side i have document with with h1 paragraph and two images. I wanna load them with ajax with animation from different angles (left, top, right, bottom). I know how to animate but as soon as i load them they are already on the page and i want to animate them into the page. Code looks like this:
<body>
<button id="load"></button>
</body>
My jquery script
<script>
$('#load').click(function() {
callAjax();
return false;
});// end of click function
});
function callAjax() {
$.ajax({
type: "POST",
cache: false,
url: 'content.html',
success: function(data){
if(data !== ""){
$("html").prepend(data);
}
},
error: function () {
console.log('error', data);
},
complete: function () {
console.log("done"); }
}); //ajax call
} //document ready
</script>
server side data
<section class="content">
<h1>About</h1>
<p> Text</p>
<img src="ipad.png" class="rotate">
<img src="ipad1.png" class="circle">
</section>
To animate the elements you'd need more than 1 key frame. Currently you only have 1: the end-state. You'd need another one to animate from. Think of a move: to have a character walk on screen you'd have to position them off-screen first.
I'm going to assume we're doing just that: loading your content off-screen, then walking it on-screen.
Set the position for the elements (via CSS, or explicitly, but do so in the original file) off-screen. For example, use this CSS:
position: absolute;
left: -1000;
which would place the element 1000 pixels to the left of the window. That's your starting position, which is where you're going to "start" at after you have loaded the content (asynchronously).
The next part is the transition phase moving them from START to END via a series of intermediate steps computed by your code. There are many robust JS/HTML/CSS/SVG animation libraries, but I'm going to use a basic JS function: setInterval.
var thing = $('#yourThing'); // select your thing
var distInterval = 1000 / 60; // we're going to move 1000px every 60 steps
var code = function() {
thing.position().left = thing.position().left + distInterval; // move by the distance
// destination is an abs position of 100px from the left
if (thing.position().left == 100) {
window.clearInterval(); // stops the loop
}
};
var delay: 16.7; // 1/60th of a second, in ms
var intervalID = window.setInterval(code, delay); // set and start the loop
Once you are comfortable with this concept you'll soon find that this is a poor implementation choice. Some keywords to google for will be the "requestAnimationFrame()" function and the term "easings".
You could hide 'data' and then animate it in.
$(data).hide().fadeIn("slow");
I'm currently experimenting a bit with Famo.us and there is actually one thing I can't yet wrap my head around.
In a small example i tried to create a HeaderFooterLayout, where the header contains a simple icon left aligned. A click on it will bounce it to the right end of the header.
Now with a simple Transform.translate this works not as smooth as expected on my Nexus4 and Nexus 7, but hell changing it to a SpringTransition rocks. Here is the code example:
var Transitionable = require('famous/transitions/Transitionable');
var SpringTransition = require('famous/transitions/SpringTransition');
Transitionable.registerMethod('spring', SpringTransition);
var logoStateModifier = new StateModifier({});
var logo = new ImageSurface({
size: [186, 43],
content: 'images/my-logo.png'
});
var posX = 0;
var adjustment = 20;
// Click event on image
logo.on('click', function() {
if(posX === 0) {
posX = (window.innerWidth - logo.size[0] - adjustment);
} else {
posX = 0;
}
var spring = {
method: 'spring',
period: 10,
dampingRatio: 0.3,
};
// transform translate with Easing
logoStateModifier.setTransform(
Transform.translate(posX,0,0),
{ duration: 1000, curve: Easing.inOutBack}
);
// spring transition
logoStateModifier.setTransform(
Transform.translate(posX, 0, 0), spring
);
});
So what I don't understand here is why Easing is so "slow" compared to the Physics driven SpringTransition?
The spring transition your requesting has a period of 10ms while the easing transition is 1000ms or 100 times slower. I tried your code "as is" and with a modification that compares more apples to apples and the transitions can run at the same speed (both laptop and devices.) First you should note that the minimum spring period is 150ms so the 10ms your asking for is actually 150. Second you are stacking the transitions so that one follows the other. The easing will take 1 second and then the spring will oscillate. You may want to try something slightly different... set the transitions to the following:
// transform translate with Easing
logoStateModifier.setTransform(
Transform.translate(posX,0,0),
{ duration: 150, curve: Easing.inOutBack}
);
// spring transition
logoStateModifier.setTransform(
Transform.translate(0, 0, 0), spring
);
This will behave slightly differently. On click (every other click actually) the logo will cross the screen at high speed and then come back. I expect you'll find that these transitions run at comparable high speeds. Of course for a slower more viewable test you can set the spring period to 1000 and the easing duration to the same and again the speeds should be comparable.
I have my Index.cshtml view, and for some reason, the JQuery is having a hard time firing the jqFancyTransitions method (it's acting as if the jqFancyTransitions library isn't included). The JavaScript IS firing though. For testing, I even put $('#rotatingImages').html('blah'); to see if it would find my ID and replace it's HTML contents, but it didn't.
I do get a JS error in my Firebug console: TypeError: $(...).jqFancyTransitions is not a function. Yet, I get jqFancyTransitions intellisense after I type a dot at the end of the parenthesis.
EDIT:
The jqFancyTransitions.js library IS in fact being loaded into the browser according to Firebug. To test it out, I removed the reference to it, and then I didn't see the library was loaded. I added it back in to my view, and I see it.
Here's the code on Index.cshtml:
<script src="~/Scripts/jqFancyTransitions.1.8.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#rotatingImages').jqFancyTransitions({
effect: 'wave', // wave, zipper, curtain
width: 959, // width of panel
height: 300, // height of panel
strips: 20, // number of strips
delay: 4000, // delay between images in ms
stripDelay: 50, // delay beetwen strips in ms
titleOpacity: 0.7, // opacity of title
titleSpeed: 1000, // speed of title appereance in ms
position: 'alternate', // top, bottom, alternate, curtain
direction: 'fountainAlternate', // left, right, alternate, random, fountain, fountainAlternate
navigation: false, // prev and next navigation buttons
links: false // show images as links
});
// $('#rotatingImages').html('blah'); // just for testing
});
</script>
<div id="rotatingImages">
<img src="Images/Background/bg1.jpg" />
<img src="Images/Background/bg2.jpg" />
<img src="Images/Background/bg3.jpg" />
<img src="Images/Background/bg4.jpg" />
</div>
Any ideas what's going on?
I believe your JavaScript reference needs to be changed to
<script src="#Url.Content("~/Scripts/jqFancyTransitions.1.8.js")"></script>
for Razor ViewEngine, or
<script src="<%=Url.Content("~/Scripts/jqFancyTransitions.1.8.js")%>"></script>
for WebForms ViewEngine.
Real simple. All I had to do was include my scripts in a "scripts" section inside the view I was working in, which was Index.cshtml, as follows:
#section scripts
{
#Scripts.Render("~/bundles/fancyTransitions")
<script type="text/javascript">
$(document).ready(function () {
$('#rotatingImages').jqFancyTransitions({
effect: 'wave', // wave, zipper, curtain
width: 959, // width of panel
height: 300, // height of panel
strips: 20, // number of strips
delay: 4000, // delay between images in ms
stripDelay: 50, // delay beetwen strips in ms
titleOpacity: 0.7, // opacity of title
titleSpeed: 1000, // speed of title appereance in ms
position: 'alternate', // top, bottom, alternate, curtain
direction: 'fountainAlternate', // left, right, alternate, random, fountain, fountainAlternate
navigation: false, // prev and next navigation buttons
links: false // show images as links
});
});
</script>
}
I thing u forgot to link jQuery library on the top. before
<script src="~/Scripts/jqFancyTransitions.1.8.js"> </script>