I would like to have a clipping animation with the SVG clipping path that would hide the first section and show the second while animating using fullPage.js.
So this is similar to this question:
fullpage JS animation on section
yet I would like to have controlled animation with specific duration (so the transition is smooth).
What I know or have tried now:
FullPage.js onLeave and afterLoad callbacks will have to be used. If I prevent scrolling in onLeave event I can call silentMoveTo only in afterLoad event yet I need what's in the next two points.
Two sections cannot be active (CSS class) with fullPage.js (so for example I would change the section 2 opacity from 0 to 1 as the animation reveals it, while section 1 would be hidden vice versa and the background clipping path would move to top to hide the section 1 image (SVG).
I've tried to animate the clipping path (have similar working example) yet of course the content of the section 2 below is not displayed. Calling silentMoveTo to show section 2 after the animation is not usable so it will have to be synchronized with say 50% of animation duration passed.
What would be the best approach? I have to use fullPage.js (by request, built in WordPress theme used). Ideally I plan to use a timeline in GreenSock javascript library with a callback on animation end to properly signalize fullPage.js main object that active section should now be #2.
ADDED: you can see one approach of using transitions with GreenSock here:
https://youtu.be/gE-Yuu2eEio?t=1694
yet this is the animation AFTER the second section loads. I want to have an animation of the first section contents that at the same time reveals the second section (I am aware of Fading Effect fullPage.js extension, not the solution to this).
So I guess I have to answer this myself.
Short answer: it's not possible to show two sections at the same time using fullPage.js as (it is) designed.
Long answer: you can at least mimick some kind of interaction e.g. longer animation during first section and then quickly show the second one. Like this (you cannot run this code due to removing unnecessary parts for discussion):
var fullPageOBj = new $('#fullpage').fullpage({
...
onLeave: function (origin, destination, direction) {
dir = direction;
...
if(origin == 1 && destination == 2){
$.fn.fullpage.setAutoScrolling(false);
document.body.style.overflow = "hidden";
...
TweenMax.to(bSvg, 2.7, { }, "section1");
...
}
$.fn.fullpage && $.fn.fullpage.setLockAnchors && $.fn.fullpage.setLockAnchors('false');
},
afterLoad: function (origin, destination) {
console.log("aL - origin: " + origin + ", destination: " + destination + ", direction: " + dir);
if(destination == 1){
$("vc-section1").addClass("active");
...
}
if(destination == 2){
TweenMax.to(bSvg, 0, { display: "block", onComplete: Delay2, delay: 3.2});
function Delay2() {
$.fn.fullpage.setAutoScrolling(true);
$.fn.fullpage.silentMoveTo(2);
}
}
}
}
The idea above is that the afterLoad event in fullPage.js is spawned practically immediately after onLeave event so you have to make sure to wait for animation in onLeave event function completes before afterLoad functions take place. So the above code includes spawning the Delay2 function that runs after an animation completes. The timing in afterLoad function is set to respect the time for an animation duration in onLeave function.
You'll have to play with the timings. Default transition time before sections in fullPage.js appears to be 700 ms.
The last idea would probably be to move animation to Section 2 - but the page is already without objects in Section 1 (to animate in transition to Section 2).
You're welcome to add to discussion.
Related
I have been using $().hide and $().show to make a smooth transition between images in a slideshow-like fashion. For example, when the right arrow key is pressed, the current image being displayed will slide to the left and disappear, the image will change, and it will slide into view from the right. This is the code I use for such a transition:
$('#mainImage').hide("slide", { direction: "left" }, 200);
$('#mainImage').show("slide", { direction: "right" }, 700);
setTimeout(function() { changeImg(pageNumberNew); }, 200);
The setTimeout() function is purely to control when in the transition the image source will change. The pageNumberNew variable is the URL of the image to be changed to. Here is the changeImg() function:
function changeImg(number) {
document.getElementById('mainImage').setAttribute('src', "/largefiles/2021roadatlas/Images/" + number + ".jpeg");
curPageNumber = number;
setWidth();
}
However, on the first transition of images, it will become very choppy, because the images haven't been loaded yet. I have tried various methods of preloading images, such as
Preloading images with JavaScript
Preloading images with jQuery
Waiting for image to load in JavaScript
JavaScript waiting until an image is fully loaded before continuing script
But none of these have worked.
Once an image has been loaded for the first time, navigating back to that image will be smooth. I would like a solution where these images can be preloaded before the user starts interacting, possibly loading each image before the transitions take place - causing for a slight delay in starting the animation, but allowing it to be smooth.
You can see what I have so far in action here, if you type in 13 and use the right and left arrow keys. The animations might not be choppy if you use desktop, try that website on mobile to see the issue.
TO BE CLEAR: I want a way to preload images in JavaScript, but I haven't been able to use the normal methods of preloading images, as described above.
The reason it is loading so slow is the large image. You should make the image size of the original photo smaller. I can see that the original size is around 5000 x 6500 and you are scaling it down to around 1000 x 600. The original image is unnecessarily big which causes the slow load.
I am working on a simple slideshow where each slide has its own duration.
I would like to add transitions between the slides using animate.css by adding and removing classes on the current and the next slides.
My problem is that - with my current approach - only the next slide will be animated (it slides in) but the current one is just disappear without any animation.
I have tried to detect the end of the current animation and then change(adding/removing) the classes but in that case there was a huge gap between the slides...
How can make sure that two animations plays at once?`
var slides = $this.find('.slide');
slideIt = function(time) {
setTimeout(function() {
var duration = slides.eq(nextSlide).data('duration');
slides.eq(currentSlide)
.removeClass(animateIn)
.addClass(animateOut)
.hide();
slides.eq(nextSlide)
.removeClass(animateOut)
.addClass(animateIn)
.show();
slideIt(duration);
currentSlide = nextSlide; nextSlide ++;
if (nextSlide == slidesLength) { nextSlide = 0;}
},time);
};
Thank you for the help in advance!
Ps.: While typing this post I have realized that it must be the .hide() but without it only the first slide displayed.
Native CSS animations on two different elements should always run at the same time.
But if you hide an element, it disappears before the animation has even started. You have to add a timer for that.
slides.eq(currentSlide)
.removeClass(animateIn)
.addClass(animateOut);
// save the jQuery instance of the element that should be hidden.
var $currentSlide = slides.eq(currentSlide);
// hide this element later
setTimeout(function() {
$currentSlide.hide();
}, 1000); // 1000 for 1000ms, replace that with the duration of the animateOut animation
If my first answer doesn't satisfy you, because you want so solve that on the CSS side, when there is a second way:
Remove the .hide() in JavaScript.
Make sure your CSS animation ends with a state, there the element cannot be seen anymore (like transform: scale(0) or left: -100%).
Maintain that final state of the CSS animation. To do that, see: Maintaining the final state at end of a CSS3 animation
We have developed a jQuery plugin based on the jQuery Easing and Cycle plugins. A sample can be seen at http://jsfiddle.net/Dx5N4/3/embedded/result/. The idea is to have multiple lists of items (say, images) to which the Cycle plugin is applied. Each list is given a different initial delay so that the jQuery Cycle slideshows on each list begin at a different point in time. A quick sample from the plugin is shown below.
var delay = 100;
$("#slideshow ul").each(function() {
$(this).cycle({ delay : delay
, easing : "easeInOutElastic"
, fx : "scrollUp" });
delay += 100;
});
When the page loads, the plugin works just fine. The Cycle plugin is applied correctly, the slideshows start and slides transition with a delay, as expected.
However, if the user switches to a different browser tab, minimizes the browser window or switches to a different application and then comes back to the browser tab with the slideshows, the delay between individual slideshows is lost. Completely unpredictable behaviour ensues at this point, ranging from all slideshows transitioning at the same time, to none transitioning at all.
Any thoughts on what goes wrong when the browser tab loses focus, and how this can be corrected?
Modified the plugin to trigger slide transitions manually through normal JavaScript.
var slideshows = $("ul", $("#slideshow"));
$(slideshows).each(function() {
$(this).cycle({ easing : "easeOutElastic", fx : "scrollUp", timeout : 0 });
});
setInterval(function() {
var item = 1;
slideshows.each(function() {
var slideshow = $(this);
setTimeout(function() {
slideshow.cycle("next");
}, item++ * 100);
});
}, 4000);
The modified (working) code is available at http://jsfiddle.net/Dx5N4/5/embedded/result/.
I got a div with an image inside it using query
$('#super').animate({
left:'150px'
}, {
duration: 10000,});
What iam trying to figure out is how to stop and start animation. So for example it will start to move left 150px and then will stop for 2 seconds and then move left 300px.
Like this:
$('#super').animate({left : '-=150'}).delay(2000).animate({left : '-=300'});
Demo: http://jsfiddle.net/E7akr/
(You can add duration, easing and complete settings to the .animate() calls as desired - obviously the key thing here is the .delay() method.)
I made a image scrolling with the mouse.
The image scroll to a position based on the mouse position percentage of the window height.
$(imageContainer).mouseenter(function(e){
var scrollingTo = ((e.pageY/$(this).height())-.083) * ( $(imageContainer).prop('scrollHeight') - $(imageContainer).height() );
hijacked = true;
$(imageContainer).animate({scrollTop:scrollingTo},300,function(){hijacked=false;});
}).mousemove(function(e){
if(hijacked) return;
var scrollingTo = ((e.pageY/$(this).height())-.083) * ( $(imageContainer).prop('scrollHeight') - $(imageContainer).height() );
$(imageContainer).scrollTop(scrollingTo);
});
So. in that line
$(imageContainer).animate({scrollTop:scrollingTo},300,function(){hijacked=false;});
I want that scrollingTo change. Because during the animation, the user can move the mouse, changing the scrollingTo variable.
Alright, I managed to cook together a hacky way of dynamically altering an animation. My understanding of the internal animation queue for jQuery is not great, but as far as I know there's no way to alter a queued animation, other than to make it stop. Anyway, here's the key code for an example that alters position, which should be adaptable to scrolling (in fiddle form):
$(document).ready(function () {
var last_update = 0;
$(document).on("mousemove", function (e) {
if (Date.now() - last_update > 50) {
$mover = $("#mover");
$mover.stop();
$mover.animate({ left: e.pageX, top: e.pageY}, 200, "linear");
last_update = Date.now();
}
});
});
There were a couple of tricks to make it work, I'll go through them and try to explain how I believe they could be adapted to scrolling:
The main idea is that on mousemove, the prior event is cancelled, and a new one is started.
I don't believe this will require any changes for scrolling.
Some forms of animation accelerate/decelerate over the course of the animation - it's too hard to preserve this in a constantly changing animation (at least without writing a custom animation function), so the animation easing is set to "linear".
rapidly changing animations takes time (especially for an event as common as mousemove), so there's a limit on how often the animation can change. Before a change to the animation is made, it's ensured that no changes have been made in the last .05 seconds (this is done with "last_update").
I believe if you just swap out the animation properties for your own (scrollTop), this should do what you're looking for.