while having elements slide, make wrapper div width decrease - javascript

I have a simple div wrapper called .falling within this div I have 10 small images. I created a simple function that allows them to 'slide down' when I desire. That code is below.
JS:
function slide(){
$(".falling").delay(100).fadeIn().animate({opacity: 1, top:"300px"},'slow');}
slide();
CSS:
.falling {
width: 500px;
left: 600px;
top: 60px;
position: absolute;
display:none;
}
The problem is; 2 things. One, at the end of the 'slide down' I would like to have the .falling wrapper width to DECREASE so down to maybe 250px; because I want the illusion the images are grouping together at the end. Each img has a shared class called .imgfall I would like to use this to make the images smaller in width at the bottom as well. So, maybe max-width: 25px;
function slide(){
$(".falling").delay(100).fadeIn().animate({opacity: 1, top:"300px"},'slow');
$(".falling").css("width", "250px"); // tried this before and after slide but doesn't resize after slide but instead before, so not working!
}
slide();

By calling a function as the last parameter in jquery's animate function, you basically call an 'on complete'. See: http://api.jquery.com/animate/
var $fallingShell = $(".falling");
var animateSlides = function(){
function slide(){
$fallingShell.delay(100).fadeIn().animate({opacity: 1, top:"300px"},'slow', function(){
$fallingShell.animate({"width":"250px"}, 500);
});
}
}
And the replay needs the inline css create by the js reset. See: http://api.jquery.com/css/
I think this is everything you need to reset, but this is a best guess having not seen the code.
var resetSlides = function(){
$(".falling").css(
"width":"auto",
"opacity":"0",
"top":"0px"
);
}
So then you can tie it all together with a click or timer or something, or even call the reset at the start of animateSlides();
$('button').on('click', function(){
resetSlides();
animateSlides();
});

Related

How to slow down onclick events inside my function or make them happen gradually? Looking for smooth transition

I'm sure there is a simple fix for this and I just am unable to piece it together... In the event that the link with the id of "light_off" is clicked then I want all the little changes to take place, that part is working, but they're happening too abruptly. How do I slow them down or fade into the changes so the transition looks smoother? Do I fadeIn? Add "slow" duration? Animate? And if so, how would I implement that properly? Gee, I hope that makes sense. Any help would be appreciated! Thank you!!
<script>
$(document).ready(function(){
$("#lights_off").click(function(){
$("#lights_off").fadeOut(1000);
$("#main").addClass(" lights_on");
$('#flavoredesign_logo').attr('src','img/logofinal.png');
$("#nav").css("color","#000000");
$("#nav").css("border-bottom"," #333 solid 1px");
});
});
</script>
You can also use $.animate()
However using animate you can't set color values, but only numeric values or use 'toggle's. w3 has an excellent guide for using it.
$(function() {
var on = true;
$('#lights').on('click', function() {
if ( on ) {
$( "#lights" ).animate({
width: 100,
height: 100
}, 1000 );
} else {
$( "#lights" ).animate({
width: 200,
height: 200
}, 1000 );
}
on = !on;
});
})
I created a fiddle with sizing of an element
you can use setTimeout(function(){ /you code/ }, 200) or use css animations / transitions
As pointed out in the comments, couldn't you use the CSS transition attribute to achieve smooth class changes? You can use this to give a time frame for transitioning between different property values. For example, if you wanted to give an animation time frame for transitioning between colours:
.light {
border-radius: 50%;
width: 100px;
height: 100px;
transition: background-color 1s; //Most properties can be manipulated through the transition attribute, e.g. width 1s
Then toggling between different classes with different values for background-colour:
.lights_off {
background-color: grey;
}
.lights_on {
background-color: yellow;
}
I've created a Fiddle that shows how this could be utilised to create a smooth transition.

Trigger jQuery events one after another

Hi I am trying to create an animation where one class is added only after the one before it is finished triggered.
$('.flipper').click(function(){
$('#first').addClass('first-flip');
$('#second').addClass('second-flip');
$('#fourth').addClass('fourth-flip');
});
so
$('#second').addClass('second-flip');
would only trigger when
$('#first').addClass('first-flip');
has finished its process.
so another way of explaining this would be.
Block A has a rotate effect added to it, after Block A is rotated, only then will Block B move 20 px right.
I basically just want to know how to create Jquery effects that trigger in sequential order.
You want to tie into transitionend or animationend. Here is an example using transitionend. After the box has finished moving, a new class is added which begins the next transition to turn the box blue.
var mydiv = document.querySelector("#mydiv");
document.querySelector("button").addEventListener("click", buttonHandler);
mydiv.addEventListener("transitionend", onEndHandler)
function buttonHandler() {
mydiv.classList.add("move-left");
}
function onEndHandler() {
mydiv.classList.add("turn-blue");
}
#mydiv {
background: red;
width: 10em;
height: 10em;
transition: 1s;
}
#mydiv.move-left {
transform: translateX(100px);
}
#mydiv.turn-blue {
background: blue;
}
<div id="mydiv"></div>
<button>Move div</button>
If you need the jQuery version, it's here:
var mydiv = $("#mydiv");
$("button").on("click", buttonHandler);
mydiv.on("transitionend", onEndHandler)
function buttonHandler() {
mydiv.addClass("move-left");
}
function onEndHandler() {
mydiv.addClass("turn-blue");
}
Nice resource: https://davidwalsh.name/css-animation-callback

How to adjust a Greensock.js tween based on browser scroll y position rather than by the time?

How would I go about adjusting the time manually based on the scroll position? What might that look like? To basically 'scroll' the tween? So that the tween reacts to the scrolling mouse's Y position rather than just trigger and execute based on a preset time?
IMHO, here is what you'll need to do:
You will need TimelineMax for sequencing your animations. Place
your animations in TimelineMax as you like them to be.
You'll need to figure out the maximum scroll position your window can scroll up to, beforehand. (This can also be re-calculated on browser resize as well but I haven't taken this into account in my example below). You can figure out with the
help of this answer. Also read the comments on that answer.
Upon scroll, you'll need to convert the current scroll position of
your window object into percentage that is: var currentScrollProgress=window.scrollY/maxScroll; such that your currentScrollProgress should always be between 0 and 1.
TimelineMax has a progress() method which takes values ranging
from 0 and 1 where 0 being the initial state of the animations
and 1 being the final state. Feed this currentScrollProgress
into it and you're done.
OR, you can tween the timeline itself that is: TweenMax.to(timeline,scrollTweenDuration,{progress:currentScrollProgress,ease:ease});.
Code used in my example is as follows:
HTML:
<div> </div>
<div> </div>
...
CSS:
html, body { margin: 0; padding: 0; }
div { width: 100%; height: 60px; margin: 2px 0; }
div:nth-child(odd) { background: #cc0; }
div:nth-child(even) { background: #0cc; }
JavaScript:
/*global TweenMax, TimelineMax,Power2*/
var myDIVs=document.querySelectorAll('div'),numDIVs=myDIVs.length;
var timeline=new TimelineMax({paused:true}),duration=.4,ease=Power2.easeOut,staggerFactor=.1,scrollTweenDuration=.4;
var scrollTimeout=null,scrollTimeoutDelay=20,currentScrollProgress=0;
var maxScroll=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight)-window.innerHeight; //see [https://stackoverflow.com/a/17698713/3344111]
function init(){
initTimeline();
listenToScrollEvent();
onScroll();
}
function initTimeline(){
for(var i=0; i<numDIVs; i+=1){ timeline.fromTo(myDIVs[i],duration,{opacity:0},{opacity:1,ease:ease},i*staggerFactor); }
}
function listenToScrollEvent(){
(window.addEventListener)?window.addEventListener('scroll',debounceScroll,false):window.attachEvent('onscroll',debounceScroll);
}
function debounceScroll(){
clearTimeout(scrollTimeout);
scrollTimeout=setTimeout(onScroll,scrollTimeoutDelay);
}
function onScroll(){
currentScrollProgress=roundDecimal(window.scrollY/maxScroll,4);
//timeline.progress(currentScrollProgress); // either directly set the [progress] of the timeline which may produce a rather jumpy result
TweenMax.to(timeline,scrollTweenDuration,{progress:currentScrollProgress,ease:ease}); // or tween the [timeline] itself to produce a transition from one state to another i.e. it looks smooth
}
function roundDecimal(value,place){ return Math.round(value*Math.pow(10,place))/Math.pow(10,place); }
//
init();
Here is the resulting jsFiddle. Hope it helps.
T
While Tahir's answer is correct and sufficient, there's a lot of unnecessary code to show the example.
A more concise snippet is:
var max_scroll = document.body.offsetHeight - window.innerHeight;
win.addEventListener('scroll', function(){
var scroll_perc = parseFloat(Math.min(window.pageYOffset / max_scroll, 1).toFixed(2));
TweenMax.to(tl, 0, {
progress: scroll_perc
});
});
var tl = new TimelineMax({paused: true});
// the rest of your timeline....

How to implement jquery like slideDown() in zepto

I am using zepto library for my mobile web site. I have recently learnt that zepto does not have slideDown() plugin like jquery. I would like to implement the same for zepto.
I have tried one on jsfiddle (http://jsfiddle.net/goje87/keHMp/1/). Here it does not animate while showing the element. It just flashes down. How do I bring in the animation?
PS: I cannot provide a fixed height because I would be applying this plugin to the elements whose height property would not be known.
Thanks in advace!!
Demo: http://jsfiddle.net/6zkSX/5
JavaScript:
(function ($) {
$.fn.slideDown = function (duration) {
// get old position to restore it then
var position = this.css('position');
// show element if it is hidden (it is needed if display is none)
this.show();
// place it so it displays as usually but hidden
this.css({
position: 'absolute',
visibility: 'hidden'
});
// get naturally height
var height = this.height();
// set initial css for animation
this.css({
position: position,
visibility: 'visible',
overflow: 'hidden',
height: 0
});
// animate to gotten height
this.animate({
height: height
}, duration);
};
})(Zepto);
$(function () {
$('.slide-trigger').on('click', function () {
$('.slide').slideDown(2000);
});
});​
​
This worked for me:
https://github.com/Ilycite/zepto-slide-transition
The Zepto Slide Transition plugin add to Zepto.js the functions bellow :
slideDown();
slideUp();
slideToggle();
Speransky's answer was helpful, and I'm offering a simplified alternative for a common drop-down navigation list, and separated into slideUp and slideDown on jsfiddle: http://jsfiddle.net/kUG3U/1/
$.fn.slideDown = function (duration) {
// show element if it is hidden (it is needed if display is none)
this.show();
// get naturally height
var height = this.height();
// set initial css for animation
this.css({
height: 0
});
// animate to gotten height
this.animate({
height: height
}, duration);
};
This would work for what you need:
https://github.com/NinjaBCN/zepto-slide-transition

I can add an overlay, but I can't remove it (jQuery)

This function adds an overlay with the following properties to the entire browser screen,
$('a.cell').click(function() {
$('<div id = "overlay" />').appendTo('body').fadeIn("slow");
});
#overlay
{
background-color: black;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
display: none;
z-index: 100;
opacity: 0.5;
}
And this function is supposed to remove it.
$('#overlay').click(function() {
$(this).fadeOut("slow").remove();
});
But it seems to do absolutely nothing and now my page is stuck with a black overly over it. What's wrong with the removal?
The problem is that when you're adding the click handler, there isn't any overlay, so you're adding the handler to an empty set of elements.
To fix this, use the live method to bind your handler to all elements that match #overlay, whenever they are created.
Also, fadeOut is not a blocking call, so it returns before the element finishes fading out. Therefore, you're calling remove right after the element starts fading out.
To fix this, use fadeOut's callback parameter to call remove after the animation finishes.
For example:
$('#overlay').live(function() {
$(this).fadeOut("slow", function() { $(this).remove(); });
});
Here you go. This should fix the problem and let the overlay fade out before removing it.
$('#overlay').live("click", function() {
$(this).fadeOut("slow", function() { $(this).remove() });
});
Remove should be in the callback to fadeout, like so:
$('#overlay').live('click', function() {
$(this).fadeOut("slow", function() {
$(this).remove();
});
});
Try:
$('#overlay').live('click', function() {
$(this).fadeOut("slow").remove();
});
My recommendation is to use the jquery.tools overlay plugin. Your overlay will have a trigger (usually a button or link), but you can load or clear it with a javascript command, e.g.:
js:
var config = { closeOnClick:true, mask:{opacity:0.7, color:'#333', loadSpeed:1} }
$("#myTrigger").overlay(config); // add overlay functionality
$("#myTrigger").data("overlay").load(); // make overlay appear
$("#myTrigger").data("overlay").close(); // make overlay disappear
html:
<div id="myOverlay" style="display:none;">Be sure to set width and height css.</div>
<button id="myTrigger" rel="#myOverlay">show overlay</button>

Categories