Accessing updated CSS values from previously animated elements in a Greensock timeline - javascript

I have a TimelineLite() which performs a series of .to() tweens in sequential order. I'd like to be able to use the value that results from one of the early tweens in the construction of one of the later tweens.
Is there anyway to access the values of elements that have previously completed their animation in a timeline?
UPDATED:
The example that I provided originally was quite crude. I've updated it to more accurately reflect what I'm running into.
The size of the colored div are dependent on the viewport, and the content within them flows based on that size. Clicking on one of them begins an animation which expands the clicked div to fill the viewport and removes the non-clicked divs. This resizing causes the text to reflow to adjust for the new space.
Then div.status (that was previously absolutely positioned off the bottom of the page) animates up to be below the selected colored div. Unfortunately, the height that is used to calculate its new top value is what the selected colored div's height was prior to the animation and subsequent reflow of it's content.
var timeline = new TimelineLite();
$('.clickable').click(function(){
var $selected = $(this);
var $notSelected = $('.clickable').not($(this));
$selected.addClass('selected');
$notSelected.addClass('not-selected');
timeline
.add("optionSelected")
.to(
$selected,
0.5,
{ "width":"96%" },
"optionSelected"
)
.to(
$notSelected,
0.5,
{
"width":"0%",
"padding":"0"
},
"optionSelected"
)
.to(
$(".status"),
0.5,
{
"top":$('.selected').height()
}
)
})
body{
position:relative;
height:100vh;
overflow:hidden;
background-color:cornsilk;
}
section{
background-color:#ddd;
display:flex;
align-items: flex-start;
}
div{
width: 30%;
padding:2%;
color: #FFF;
display:inline-block;
}
.clickable{cursor:pointer;}
.status{
width:96%;
position:absolute;
top:100%;
left:0;
background-color:#FFF;
color:black;
border:1px solid black;
}
.blue{background-color:blue;}
.green{background-color:green;}
.purple{background-color:purple;}
.not-selected{
white-space: nowrap;
overflow:hidden;
}
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<section>
<div class="blue clickable"><strong>Clickable</strong> - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Dignissim tortor, sit amet vulputate augue lectus vel felis. Cras ac ex vel ligula porta laoreet.
</div>
<div class="green clickable"><strong>Clickable</strong> - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ultrices, est ut sollicitudin gravida, velit erat dignissim tortor, sit amet vulputate augue lectus vel felis. Cras ac ex vel ligula porta laoreet. Mauris lorem tellus, convallis ac tincidunt eu, efficitur consequat turpis.</div>
<div class="purple clickable"><strong>Clickable</strong> - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ultrices, est ut sollicitudin gravida, velit erat dignissim tortor, sit amet vulputate augue lectus vel felis. Cras ac ex vel ligula porta laoreet.</div>
<div class="status">Status</div>
</section>
</body>

Try returning the desired height from a function as a callback. I think then it won't be executed until after the animation of the .selected element has reached that to() in the chain.
Also height() does not include padding or margins, so you end up with the .status overlapping, try .outerHeight() instead.
Working example:
http://codepen.io/jonwheeler/pen/jAvRZZ?editors=0110

Related

jQuery change css on a specified element

I need something that will change the style of a div when you scroll to a specific element
Example:
In my header i have the texts:
1) Home
2) Text2
3) Text3
4) Text4
When on top i want the "Home" to be white and all the others blue
When on paragraph 1 i want the "Text2" white and all the other blue
When on paragraph 2 i want the "Text3" white and all the other blue
When on paragraph 3 i want the "Text4" white and all the other blue
When below "Text4" i want the "Home" to be white and all the others blue
PS: "Text2","Text3" and "Text4" will have nothing else in betwheen
I'd go with waypoints or with skrollr. There are plenty of tutorials about skrollr so dont worry.
You can do something like this
Use scroll() to listen scroll event
Get the scroll top value by using scrollTop()
DEMO :
$(window).scroll(function() {
$('#div2').css('color', $(this).scrollTop() > 390 ? 'red' : 'blue');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id=main style="height:1000px">
<div id=div2 style="margin-top:500px">element</div>
</div>
This toggles the color of any header text at the point a matching element comes into view (or leaves) :
Demo
$(function() {
var gate = $(window),
bar = $('header'),
title = bar.find('span'),
element = $('.element'),
viewin, viewout;
gate.on('load resize', function() {
viewin = []; viewout = [];
element.each(function() {
var placement = $(this).offset().top-gate.height(),
dimension = $(this).outerHeight();
viewin.push(placement);
viewout.push(placement+dimension);
});
})
.scroll(function() {
var location = gate.scrollTop();
element.each(function(i) {
var option = title.eq(i), white = option.hasClass('white');
if (location > viewin[i] && location <= viewout[i]) {
if (!white) option.addClass('white');
}
else if (white) option.removeClass('white');
});
});
});
Comments below are no longer very relevant because they are discussing an earlier stage.
Animating colors does not work unless you include a library for animating colors.
jQuery does not animate colors by default.
So for color-animation you must include library like JQuery UI, but it is large for just using color-animation.
Instead i would suggest you to use Bitstorm:ColorLibrary, it's just 2.7kb in size.
JSFiddle : DEMO
$(document).ready(function(){
var top = document.getElementById("css_text").scrollHeight; // top position of '#css_text'
alert("Top position of #CSS_TEXT : " + top);
var calcu = top - 20;
$(window).scroll( function(){
var pos = $(window).scrollTop();
if(pos >= calcu)
{
$("#css_text").animate({"color":"red","opacity":"1"},2000);
}
});
});
#css_text
{
opacity:0;
color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors-min.js"></script>
<h1>HTML Ipsum Presents</h1>
<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.</p>
<h2>Header Level 2</h2>
<ol>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
</ol>
<blockquote><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.</p></blockquote>
<h3>Header Level 3</h3>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
</ul>
<pre id="css_text"><code>
#header h1 a {
display: block;
width: 300px;
height: 80px;
}
</code></pre>
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li>Vestibulum auctor dapibus neque.</li>
</ul>
Check the following jquery functions
scroll
scrollTop
offset
each
attr
Your code could look something like that:
( function( $ ) {
$(window).scroll(function(e){
var home = $('#home');
var switchPosition = $(window).scrollTop() + parseInt(home.css("top"))+30;
$('.text').each(function(){
if ( switchPosition > $(this).offset().top &&
$(this).attr('data-color') !== home.attr('data-color') ) {
home.css({color: $(this).attr('data-color')});
home.attr('data-color', $(this).attr('data-color') );
}
});
});
} )( jQuery );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="home" style="font-weight: bold; color: blue; position: fixed; top: 20px; left: 20px;">HOME</div>
<div style="color: white; position: fixed; top: 170px; left: 20px;">scroll down...</div>
<div class="text" data-color="blue" style="background: #999; height: 500px"> </div>
<div class="text" data-color="red" style="background: #666; height: 500px"> </div>
<div class="text" data-color="white" style="background: #333; height: 1000px"> </div>

Force text in the child div fit into parent

I have two div tags in my HTML code like this
<div id="parent">
<div id="child">
<p class="child-text"> ..... </p>
<a class="child-link"> ..... </a>
<p class="child-text"> ..... </p>
</div>
</div>
#parent{ height: 400px; width:100px}
How can force the content of #child div vertically fit into the parent div ?
I am looking for some thing that can take child div ID and resize its content dynamically. I have worked with jQuery.fittext. However, it get the child-text class id instead of child div id. In other words, it is not intelligent enough to identify what is in the child div and then rescale them.
Is there any other alternative for this ?
You could do something like:
var fontsize = 10;
while($('#child').height() <= $('#parent').height()){
fontsize = fontsize +1;
$('#child').css('font-size',fontsize+'px');
}
#parent{ height: 400px; width:100px;background:red;}
#child{padding-bottom:5px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="parent">
<div id="child">
<p class="child-text"> Once upon a time </p>
<a class="child-link"> there lived a monkey</a>
<p class="child-text"> who loved to eat oranges </p>
</div>
</div>
While #child height is less then #parent then it adds 1px until it is not. In the css, I gave #child a padding bottom of 5px, so it would not overflow
JSFiddle
Add a display property value of table to #parent and display property value of table-cell to the elements you want to measure the height of #parent
#parent, #child {
width: 100%;
height: 100%;
position: relative;
display: table;
}
.child-link, .child-text { /* ID/Class of whatever element you want to measure the #parent */
display: inline-block;
height: 100%;
width: 150px;
vertical-align: top;
background-color: green;
bottom: 0;
display: table-cell;
border-left: solid 5px white; /* Just for Division sake */
}
<div id="parent">
<div id="child"><p class="child-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sagittis felis nec est iaculis, id rhoncus eros efficitur. Aliquam justo felis, semper in placerat non, facilisis sed elit. </p>
<a class="child-link"> Lorem </a>
<p class="child-text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sagittis felis nec est iaculis, id rhoncus eros efficitur. Aliquam justo felis, semper in placerat non, facilisis sed elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sagittis felis nec est iaculis, id rhoncus eros efficitur. Aliquam justo felis, semper in placerat non, facilisis sed elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sagittis felis nec est iaculis, id rhoncus eros efficitur. Aliquam justo felis, semper in placerat non, facilisis sed elit.</p>
</div>
</div>
To make it dependent on the screen size, do something like below:
#media screen and (max-width: 768px) { /* Adjust as needed */
enter code here
}

How can I get these paragraphs to vertically align?

I'm using jquery cycle to fade between a few slides. These slides are of a fixed height but they contain p tags that contain text of varying lengths. I've created this jsfiddle to show you what I mean.
The problem I'm having is that I want the p tags within these slides to be vertically aligned - I want the copy to sit nicely in the center of the div. Usually when working with dynamic content like this, I'd put the p tags in a wrapper, then calculate the height of the wrapper on page load using js and position accordingly (which is why I've tagged this as javascript - I may need to use it for the solution if I can't use css).
Anyway the reason I can't seem to use js is because the p tags are within hidden panels. I can only access the size of the elements once the parent becomes visible which means I'd no doubt have to set up a callback just after a slide is made visible to do the positioning then. The downside of that is the content will jump while the js calculates the position.
One solution would be to use a table with vertical-align in the table cell, but I'm not sure it'd be semantically correct to put p tags within a td? (someone correct me if I'm wrong). Is there a purely css solution I can use here, that'll also work in ie7?
Here is the html I have:
<script src="http://ajax.aspnetcdn.com/ajax/jquery.cycle/2.99/jquery.cycle.all.js"></script>
<div id="cycle-wrapper">
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ut placerat dolor. Maecenas tempor nunc eu justo venenatis ullamcorper. Vestibulum ac turpis id quam dapibus adipiscing. Donec semper turpis at tortor tincidunt viverra.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ut placerat dolor. Maecenas tempor nunc eu justo venenatis ullamcorper.</p>
</div>
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ut placerat dolor. Maecenas tempor nunc eu justo venenatis ullamcorper. Vestibulum ac turpis id quam dapibus adipiscing. Donec semper turpis at tortor tincidunt viverra. Praesent iaculis sem vitae arcu dictum, quis dictum arcu cursus.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ut placerat dolor. Maecenas tempor nunc eu justo venenatis ullamcorper. Vestibulum ac turpis id quam dapibus adipiscing. Donec semper turpis at tortor tincidunt viverra. Praesent iaculis sem vitae arcu dictum, quis dictum arcu cursus.</p>
</div>
</div>
The css:
#cycle-wrapper { width: 340px; height: 300px; border: 2px solid red; }
#cycle-wrapper div { width: 340px; height: 300px; text-align: center; }
The script:
$(function() {
$('#cycle-wrapper').cycle();
});
Thanks
EDIT: I have got it working with tables here but I'd love to find a purely css solution if possible!
You can make your <p> visible only after the alignment has been calculated, so there is no "jumping" paragraph.
If you don't mind use the css display property and add separating elements,
Check my perfect version on http://jsfiddle.net/m29uu/3/
#cycle-wrapper {
width: 340px;
height: 300px;
border: 2px solid red;
display:table;
}
#cycle-wrapper p {
width: 340px;
height: 150px;
display:table-row;
}
#cycle-wrapper span {
text-align: center;
display:table-cell;
vertical-align:middle;
}
PURE CSS WAY
Not sure i understand your req. but i think this achieves what you want, one way of doing it would be to push the upper-most div using margin-top to the middle of parent div, which will automatically push the other div below it!
DEMO : http://jsfiddle.net/logintomyk/YTZYQ/
HTML
<div class="divCent">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ut placerat dolor. Maecenas tempor nunc eu justo venenatis ullamcorper. Vestibulum ac turpis id quam dapibus adipiscing. Donec semper turpis at tortor tincidunt viverra.</p>
</div>
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ut placerat dolor. Maecenas tempor nunc eu justo venenatis ullamcorper. Vestibulum ac turpis id quam dapibus adipiscing. Donec semper turpis at tortor tincidunt viverra. Praesent iaculis sem vitae arcu dictum, quis dictum arcu cursus.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ut placerat dolor. Maecenas tempor nunc eu justo venenatis ullamcorper. Vestibulum ac turpis id quam dapibus adipiscing. Donec semper turpis at tortor tincidunt viverra. Praesent iaculis sem
CSS
#cycle-wrapper .divCent { width: 340px; height: 300px; text-align: center;
margin-top:25% /* this is what i added **/
}
EDIT
After comments from Onimusha, here is another fiddle, implemented on his link http://jsfiddle.net/logintomyk/7AJy5/1/
Quick CSS Solution
Add the following css
#cycle-wrapper div > div {
display: table-cell;
vertical-align: middle;
}
and add a second div wrapper around the paragraph tags for the new css to apply to. It worked on the fiddle.
See this link http://www.jakpsatweb.cz/css/css-vertical-center-solution.html
It is possible to vertically center without the jQuery cycle element.
But when the plugin is added the alignment was not proper.
I am not very much aware of this plugin but try changing the default options as mentioned in jQuery Cycle Plugin's option reference.
your Div have id "cycle-wrapper". and all the paragraph within this Div..
use
$("#cycle-wrapper").css("vertical-align:middle");
you can apply any css like the following way
$("element").css("propertyname","value");
Set multiple properties and values:
$(selector).css({property:value, property:value, ...})

Indent a block of text from the second row

I want make format my text:
title - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et turpis urna. Phasellus magna elit, tempus ut accumsan posuere, suscipit vel ligula. Vestibulum mauris massa, venenatis non dignissim vestibulum,
to look like:
title - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et turpis urna.
Phasellus magna elit, tempus ut accumsan posuere, suscipit vel ligula. Vestibulum
mauris massa, venenatis non dignissim vestibulum,
I'm interesting in any solution without add change text manually.
Any help would be appreciated.
A fast and dirty solution:
<pre>
<!-- your text stuff -->
</pre>
HTML
<div class="title">title</div>
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et turpis urna. Phasellus magna elit, tempus ut accumsan posuere, suscipit vel ligula. Vestibulum mauris massa, venenatis non dignissim vestibulum,
</div>​
CSS
​.title { float: left; }
.title:after { content: '-'; display: inline-block; margin: 0 5px; }
.text { overflow: hidden; }​
jsFiddle Demo
The title is floated left, and overflow: hidden; is used to establish a new block formatting context. You can do this with any overflow value other than the default visible.
The only thing in this that is not absolutely cross-browser is the :after pseudo-element (which works from IE8), but you can simply use a static - in your HTML instead. I have chosen to do it this way because it is cleaner and there is no unnecessary styling in the markup.
For the title you could use something more semantic like an appropriate header (h1, h2, etc.).
Playing with margin and text-indent along with the :first-line pseudoclass you could achieve the desired effect: here's the relevant CSS
p { text-indent: -2.35em ; margin-left: 2.35em }
p:first-line { margin-left: -2.35em }
Example fiddle: http://jsfiddle.net/nb88K/
Be aware that the chosen value is strictly dependent on the width of "title" word.
As a sidenote, If you could change the markup itself I would instead suggest to move that word from your text to a content property of a :before pseudoclass — the fact that your text is a title, from a semantic point of view, should be conveyed through the choice of the element (so I would chose a <hn> tag)

use css for alignment and filling

I want to have a div that contains two other divs, a top div and a bottom div. The top div should be aligned to the top and have a auto-height, which depends on the content of the top div. The bottom div should fill out the empty area of the parent div.
I would like to make the alignment only with the use of CSS. I don't want to calc any positions or sizes by myself.
I tried the following:
1) http://jsfiddle.net/2dUxa/
Problem: If the parent is resized the bottom-div should move some pixels downwards.
2) http://jsfiddle.net/Th4Mn/
Problem: If the parent is resized the bottom-div should become smaller.
A solution with the use of javascript might look like this: http://jsfiddle.net/2dUxa/7/
Is theire a solution without the use of javascript?
Well, how about this: http://jsfiddle.net/2dUxa/3/
I change both div to position: relative, and give the bottom a height: 100%.
Then, set the #main overflow: hidden;
Use this below markup and css..
This is with your code check this and below is my code
​<div id="main">
<header>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mattis congue auctor. Proin iaculis blandit erat, nec vestibulum orci ultricies eget. Suspendisse viverra posuere urna, eu eleifend leo imperdiet at. Nulla lobortis, erat elementum placerat sagittis, est tellus hendrerit quam, quis iaculis leo est et mi.</p>
</header>
<footer>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mattis congue auctor. Proin iaculis blandit erat, nec vestibulum orci ultricies eget. Suspendisse viverra posuere urna, eu eleifend leo imperdiet at. Nulla lobortis, erat elementum placerat sagittis, est tellus hendrerit quam, quis iaculis leo est et mi.</p>
</footer>
</div>
​
​#main{
width:80%;
height:300px;
position:relative;
background:#ddd;
}
header{
width:100%;
height:auto;
position:absolute;
top:0;
left:0;
background:#aaa;
}
​footer{
width:100%;
height:auto;
position:absolute;
bottom:0;
left:0;
background:#777;
}
Check here running code... ​

Categories

Resources