Inverting colours of an image callback in fullpage.js - javascript

I've changed the slide arrows to my own png, black arrows but on some slides, which have darker background I want to invert them so they are white.
-webkit-filter: invert(100%);
works just fine, but how to trigger this only on slides that using a callback?
Quick animation of the invert parameter 0% > 100% would be a cool bonus. Thanks.

I didn't know about fullPage.js, but reading through the docs, I found that you can customize a callback that fires when leaving or entering a slide.
I think this is what you want:
jsFiddle - https://jsfiddle.net/ym3snhu4/1/
Notice that I'm only using -webkit-filter to invert the color, so this might not work in other non-webkit browsers. So test this in Chrome, for instance. Otherwise, just add more prefixes to the filter property when adding/removing the style. It depends on how you are changing your arrows, but you can, for instance (with fullPage.js), just change the border-color instead of using filter.
Basically, we are using the afterSlideLoad and the onSlideLeave callbacks to achieve this. Here's the code with the explanation in comments. It's pretty straightforward. My comments are way longer than the code needed, just hoping it's clear.
Example HTML:
<div class="section">
<div class="slide" data-anchor="slide1"> Slide 1 - Index 0 </div>
<div class="slide" data-anchor="slide2"> Slide 2 - Index 1 </div>
<div class="slide slide-dark" data-anchor="slide3"> Slide 3 - Index 2 <br> I'm black </div>
<div class="slide" data-anchor="slide4"> Slide 4 - Index 3</div>
</div>
JavaScript:
// Just take into consideration the callback methods.
// The body selector is the one I used in the jsFiddle, keep whatever you have.
$(document).ready(function() {
$('body').fullpage({
// The name is self explanatory.
// Fires when a a slide has finished loading
// and returns info about the slide.
// This is helpful so we can know when we are on the
// darker slide(s)
afterSlideLoad: function (anchorLink, index, slideAnchor, slideIndex) {
// Notice that in the HTML I set the data-anchor attribute,
// since that can help us be specific about what slide we are in.
// Otherwise, just use the index, which is probably a good idea
// since onSlideLeave doesn't return the slideAnchor parameter,
// for some reason.
// Change the if statement to whatever fits your needs.
// Check what index and/or anchor your darker slides are.
if(slideAnchor === 'slide3' || slideIndex === 2) {
// This adds the invert filter to the controlArrow(s),
// effectively reversing their color WHEN inside of
// this specific slide.
// (In this example, slideIndex 2 with anchor 'slide3').
$('.fp-controlArrow').css('-webkit-filter', 'invert(100%)');
}
},
// This fires when leaving a slide.
// This will be helpful to return the arrows to their
// default color. (When we know we've inverted them beforehand)
onSlideLeave: function (anchorLink, index, slideIndex, direction) {
// We inverted the color of the arrows in slide 3.
// When leaving this slide, we roll them back to their
// original color, by setting the filter to 'none'.
// I don't know why this 'event' doesn't return the
// slideAnchor parameter, so we will just use the index
// in here, which is slideIndex === 2 for 'slide3'.
// Again, change the if logic to fit your needs, i.e. add
// more slides.
if(slideIndex === 2) {
// This removes the filter, arrows go back to their
// original color.
$('.fp-controlArrow').css('-webkit-filter', 'none');
}
}
});
});
And the CSS needed for the smooth transition on filter (change the animation speed to whatever you wish):
.fp-controlArrow {
-webkit-transition: all 500ms;
transition: all 500ms;
}

Related

How to apply animations on two elements at once with animated.css

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

Clipping path transition between sections with fullPage.js

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.

strange behaviour while sliding images on carousel

I made a jsfiddle so you can reproduce the bug:
FIDDLE
I implemented a carousel to display 3 images. There's a current image (the image being displayed) and the other two remain hidden until I click one of the lateral arrows, causing the next image to slide from the side overlaying the (now previous) current image.
I've been 2 hours trying to figure out why there are certain specific 'transitions' in which the animation doesn't seem to work. For example, when clicking the left arrow to pass from the first image to the second and from the second to the third the animation works fine, but when clicking it again, the transition from 3 to 1 doesn't perform the slide animation. When moving in the opposite direction (using the right arrow) only one transition is animated. I think the problem has to do with that if in the click event handler function, but couldn't spot what's causing it.
Any help would be greatly appreciated.
TIA
The underlying issue here is related to the z-order of the three images. Your slide animations are only showing up where the image being slid in is above the displayed image; the "broken" transitions are actually occurring, they're just obscured by the "higher" visible image.
You can fix this by explicitly setting the z-index of the new and current image. For example, on the right transition:
prevLandscape.zIndex(1);
currLandscape.zIndex(0);
If you do this, you'll also need to increase the z-index of the arrows so they're above the images.
Fiddle
jsfiddle
The issue is with the hide method you just simply hide it add the slide transition for the hide method.
change this line currLandscape.hide(); to currLandscape.hide("slide");
there seemed to be a problem with the order of the images also. please try this code out. The code is reuse of the previous image arrow code. Just try it out.
$('.arrowRight').on('click',function(e) {
var currLandscape = $(this).siblings(".currImg");
var nextLandscape = currLandscape.nextAll(".hiddenImg").first();
var currDesc= $(".currDesc");
var nextDesc= currDesc.nextAll(".hiddenDesc").first();
if (nextLandscape.length == 0) {
nextLandscape = currLandscape.siblings('.hiddenImg').first();
}
if (nextDesc.length == 0) {
nextDesc= currDesc.siblings('.hiddenDesc').first();
}
nextLandscape.show("slide", { direction: "right" }, 400, function() {
currLandscape.hide("slide");
});
currDesc.fadeOut().removeClass('currDesc').addClass('hiddenDesc');
nextDesc.fadeIn().removeClass('hiddenDesc').addClass('currDesc');
currLandscape.removeClass('currImg').addClass('hiddenImg');
nextLandscape.removeClass('hiddenImg').addClass('currImg');
});

fadeTo two objects

I want to make an image on my site to opacity 0.5 and then i want to "pop out" on this image a word with opacity equal to 1. The problem is that when i set image on whatever speed it starts to queue all functions as many times as i enter/leave image with my cursor.
the word is loading faster (immadietly) than image with 'slow' and
the word doesn't change opacity to 1, cus it's loosing opacity with
image (which is set to 0.5)
How to make "word" to load later than image?
How to make function not repeatable whenever I'm moving my cursor through image (like 10x/sec) so it won't queue everything and
continue to fadeTo until everything is done?
(the most important) How to make word to not inherit opacity from image?
$(document).ready(function(){
$('#classic').mouseenter(function(){
$('#classic').fadeTo('slow', 0.25)
{
$('#classic').append("Classic");
$("Classic").fadeTo('slow', 1);
};
});
$('#classic').mouseleave(function(){
$('#classic').fadeTo('slow', 1);
{
$('#classic').empty();
};
});
});
First of all, make sure that either (a) the element that has id="classic" is not an img--because imges should not have children--or (b) you are adding the text after the img and not appending it to it. I'm going to assume that there's a div with id="classic" which has an img child:
1) You have it almost right. To make the word fade in after the image has faded out you need to use a callback function. The syntax for this is:
$('#classic').fadeTo('slow', 0.25, function() {
// now the fading is done!
});
And not
$('#classic').fadeTo('slow', 0.25)
{
....
}
You'll also probably want to add opacity: 0 for an initial value on the text that you add to the DOM so you can then fade it in.
2) jQuery has a function just for this called .stop(). Call this function whenever you need to stop animations from queuing up. So change the above to:
$('#classic').stop().fadeTo('slow', 0.25, function() {
// now the fading is done!
});
3) In CSS all elements inherit opacity from their parent. The easiest fix for this is simply to make the added element a sibling (or any other DOM element) of the transparent element and not a child. Then use negative relative positioning to stick it over the transparent element. So, assuming this structure:
<div id="classic">
<img src="myPicture" />
</div>
you'd use this jQuery:
$('#classic img').stop().fadeTo('slow', 0.25, function() {
$('#classic').append("<span>Classic</span>");
$("#classic span").fadeTo('slow', 1);
});
Make only the image fade out and in, so its siblings are unaffected. And in CSS:
#classic span {
display: inline-block;
opacity: 0; /* make it 0 initially so we can fade it in */
position: relative;
top: -48px; /* or whatever value */
left: -88px; /* or whatever value */
}
So here's the combined jQuery:
$('#classic').mouseenter(function () {
$('#classic img').stop().fadeTo('slow', 0.25, function() {
$('#classic').append("<span>Classic</span>");
$("#classic span").fadeTo('slow', 1);
});
});
$('#classic').mouseleave(function () {
$('#classic img').stop().fadeTo('slow', 1, function() {
$('#classic span').remove();
});
});
Here's a JSFiddle. Hope this helps!
I've updated your code here: http://jsfiddle.net/3dytbr3m/1/
You should use classes on your buttons. Classes are identifiers that can be applied on multiple elements. That way you don't have to use double code.
I also use $(this) which means that you are targeting the element that has the mouse over.

Change opacity of an element during drag with Jquery

Hi there,
I'm currently working on a slider made with RoyalSlider. In this slider I've got arrows left and right. So, my code, to made it simple, is something like that :
<div class="royalslider">
<div class="slide">Slide Content</div>
<div class="slide">Slide Content</div>
<div class="slide">Slide Content</div>
<div class="arrowleft"></div>
<div class="arrowright"></div>
</div>
The slides are draggable by the mouse, or you can click arrow to go next or previous...
with the API of royalSlider, I can manage, event like this :
slider.ev.on('rsDragStart', function(event) {
// mouse/touch drag start
});
slider.ev.on('rsDragRelease', function() {
// mouse/touch drag end
});
My question is :
I want to animate the opacity of my arrow from 1 (initial state) to 0 when i'm dragging my slides, I mean in relation to the slide position.
eg :
I start dragging my slide, the opacity begin to fadeOut, I stop dragging but don't release my slide, the opacity stop fading, I move the other side, opacity fadeIn....
Is it possible with jquery to do something like this ??
Hope I'm clear :-/
Many thanks
PS: Sorry for my frenglish :)
If your question is about how to handle opacity of the element in jquery, yes you can do it very elegantly.
Here is the API link, http://api.jquery.com/category/effects/fading/
And if you want to play with Fiddle, here it is, http://jsfiddle.net/80kqetf4/
Now coming back to your case, something like below would help,
slider.ev.on('rsDragStart', function(event) {
// mouse/touch drag start
var visibility = <calculate visibility based on slider position>; // 0-min & 1-max
$('selector').fadeTo(1000, visibility);
});
slider.ev.on('rsDragRelease', function() {
// mouse/touch drag end
var visibility = <calculate visibility based on slider position>; // 0-min & 1-max
$('selector').fadeTo(1000, visibility);
});
Of course you could optimize this code further..

Categories