How do I avoid repainting the dom whilst adjusting width? - javascript

So I'm trying to have these two divs push each-other, but FPS is taking a huge hit, and I know it's due to dom repainting... But can I avoid it?
http://codepen.io/Strongarm/pen/obXmmg
document.getElementById("left").addEventListener("click", function(){
TweenMax.to(".left", 0.5, {width:"100%"});
TweenMax.to(".right", 0.5, {width:"0%", opacity: 0});
fullScreen = true;
});
document.getElementById("right").addEventListener("click", function(){
TweenMax.to(".left", 0.5, {width:"0%", opacity: 0});
TweenMax.to(".right", 0.5, {width:"100%"});
fullScreen = true;
});

Depending on your situation, you may be able to animate the "transform" attribute instead. This link describes why transform is better when it comes to moving elements around - it's possible that it will help with resizing too.
For obvious reasons this won't work in all cases, but you could try:
TweenMax.to(".left", 1, {transform: scaleX(100%)});
TweenMax.to(".right", 1, {transform: scaleX(0%)});

Related

Css3 transition queue

I am trying to queue css transition with same properties. Basically I want to translate an element to certain position (so transition duration 0) before I make another translate.
This is a mockup, click on move (box should move 100px right, before translate 100px left)
this doesnt work because second transition overwrites first?
https://jsfiddle.net/aqwaypoh/3/
This works (I needed transition duration non zero (0.01) otherwise transitionend doesnt fire).
https://jsfiddle.net/dpv3xzth/5/
There is another problem that transition end fires 2 times on chrome, but I could fix that, I was just wondering is there a better way to write this?
I would prefer if I could write this without end event or timer if possible?
<div class="box"></div>
move</a>
Update:
You can use CSS3 animation property with #keyframes.
.box.animate {
animation: move 2s;
}
#keyframes move {
0% {
transform: translate(100px);
}
100% {
transform: translate(0px);
}
}
And to make the box move you can add class animate to your element. Or you can set animation property yourself in javascript, it's up to you.
box.addClass('animate')
jsfiddle: https://jsfiddle.net/aqwaypoh/7/
Adding a timeout on the second condition gives you what you want I believe.
var box = $('.box'),
move = $('.move').click(function() {
box.css({
"transform": "translate(100px)",
'transition-duration': '0s'
});
setTimeout(function(){
box.css({
"transform": "translate(0px)",
'transition-duration': '0.5s'
});
}, 1);
})

GSAP TweenMax: Need to make an HTML element jump in a semi circular path

I'm developing an interactive website which has a human character. I have implemented jump for the character but it happens in the triangular path (since not looking natural jump). So I need the jump to happen in a semi-circular path. Can someone help me making an HTML element jump naturally from its current position?
Current jump code:
TweenMax.to(app.humanCharacter.element, obstacleJumpSpeed, { bottom: app.humanCharacter.bottomOffset + obstacleHeight, left: app.humanCharacter.element.offset().left + obstacleWidth,
onComplete: function() {
TweenMax.to(app.humanCharacter.element, obstacleJumpSpeed, { bottom: app.humanCharacter.bottomOffset, left: app.humanCharacter.element.offset().left + obstacleWidth, delay: obstacleJumpDelay,
// humanCharacter's obstacle jump finished
onComplete: function() {
// starting walk cycle
app.humanCharacter.activity.startWalkCycle();
// restoring reference vars
app.humanCharacter.isObstacleJump = false;
app.humanCharacter.isJumping = false;
app.humanCharacter.obstacleNum = 0;
$('.tooltip-message').css({ 'opacity': 0 });
// callback for next reference
callback();
}
});
}
});
The easiest way would probably be to just do a bezier tween. GSAP can smoothly plot a curved path through the coordinates you provide using its "thru" mode (which is the default).
TweenMax.to(app.humanCharacter.element, obstacleJumpSpeed, {
bezier: [{bottom: app.humanCharacter.bottomOffset + obstacleHeight, left: app.humanCharacter.element.offset().left + obstacleWidth}, {bottom: app.humanCharacter.bottomOffset, left: app.humanCharacter.element.offset().left + obstacleWidth}],
onComplete:function() {
//do more stuff...
}
});
Read the docs at http://greensock.com/docs/#/HTML5/GSAP/Plugins/BezierPlugin/
A few pointers to keep in mind:
I'd strongly recommend using "x" and "y" instead of "left" and "top" (or "bottom") because it much cheaper to animate those performance-wise (transforms don't affect layout).
Try to avoid stringing animations together using callbacks - it's much cleaner to just sequence them in a TimelineLite or TimelineMax; it gives you far more control (you can then control the entire sequence as a whole). See http://greensock.com/sequence-video and http://greensock.com/position-parameter
If you don't want to do a bezier tween, you could do a combination of 3 tweens: one for the vertical movement up (with an easeOut), another for the vertical movement down (with an easeIn or maybe easeInOut), and a 3rd that is solely for the horizontal movement that'd span both of the others (run at the same time). But the bezier tween is probably best.
If you need more help, don't hesitate to ask in the GreenSock forums at http://greensock.com/forums/
Happy tweening!

JavaScript: An efficient way to handle events (Firefox-specific)

I'm running a scroll event that triggers TweenMax animations, and I'm noticing that, while it looks good on Chrome, there is a considerable amount of lag on Firefox. Does anyone have a suggestion about how to handle this scroll event as efficiently as possible? Also, is there something about Firefox's rendering that I'm not aware of that might be causing this? Any leads would be appreciated!
The gist is that I'm looking for containers on my page called "customers", which each contain three individual "customer" elements. When a div that matches "customers" scrolls into view, trigger a TweenMax animation, and add a class called "animated", which prevents the element from re-animating subsequently.
Here is a fiddle with the basic demonstration:
http://jsfiddle.net/epp37jsq/
EDIT
To clarify, the fiddle only demonstrates the behavior of my animation function. The lag does not occur there because the file size is quite small. On the actual site, I have 11 groups of 3 "customers." The image is the same, but pulled in 33 times. In the future, the images will be unique. In essence, the animation is being called for each of these 11 groups. I'm looking for suggestions on how to improve the speed of my page.
And my code:
var scrollTimer = null;
$(window).scroll(function () {
if (scrollTimer) {
clearTimeout(scrollTimer); // clear any previous pending timer
}
scrollTimer = setTimeout(handleScroll, 500); // set new timer
console.log("fired!");
});
function handleScroll() {
scrollTimer = null;
$('.customers').each(function() {
if (!$(this).hasClass('animated')) {
if ($(this).isOnScreen(0.45, 0.45)) {
TweenMax.staggerFromTo($(this).find('.customer'), 0.3, {
y: 50,
opacity: 0
}, {
y: 0,
opacity: 1,
ease: Power2.easeOut
}, 0.15);
$(this).addClass('animated');
}
}
});
}
Usually with Firefox, translating on the x or y axis can cause some jank. Sometimes adding a slight rotation:0.001 to your tween can help make your tween more smooth in Firefox.
http://jsfiddle.net/pwkja058/
Also using the GSAP special property autoAlpha instead of opacity can help increase performance
TweenMax.staggerFromTo($(this).find('.customer'), 0.3, {
y: 200,
rotation:0.01, /* add a slight rotation */
autoAlpha: 0 /* use instead of opacity */
}, {
y: 0,
rotation:0.01, /* add a slight rotation */
autoAlpha: 1, /* use instead of opacity */
ease: Power2.easeOut
}, 0.15);
autoAlpha is part of the GSAP CSSPlugin:
http://greensock.com/docs/#/HTML5/GSAP/Plugins/CSSPlugin/
autoAlpha - Identical to opacity except that when the value hits 0 the visibility property will be set to "hidden" in order to improve browser rendering performance and prevent clicks/interactivity on the target. When the value is anything other than 0, visibility will be set to "inherit". It is not set to "visible" in order to honor inheritance (imagine the parent element is hidden - setting the child to visible explicitly would cause it to appear when that's probably not what was intended). And for convenience, if the element's visibility is initially set to "hidden" and opacity is 1, it will assume opacity should also start at 0. This makes it simple to start things out on your page as invisible (set your css visibility:hidden) and then fade them in whenever you want.

Velocity JS Lag

I have been using parallax for some time and I have been using CSS animations , transforms and etc in order to get the results that I want. But after reading some stuff about Velocity , thought giving it a try.
The problem is the animations are having some kind of delay. Probably because I'm not applying velocity correctly, but I have researched and it seems that I'm doing is correct.
$ability.velocity({
translateX: '-50px',
opacity: '0'
});
$(document).on('scroll', function(){
var wScroll = $(this).scrollTop();
if(wScroll > $('.ability-self').offset().top - $(window).height()/1.2){
$ability.velocity({
translateX: "0",
opacity: '1'
});
} else{
$ability.velocity({
translateX: '-70px',
opacity: 0
});
}
The problem with that is that the animation only happens 1 or 2 seconds after I scroll after the element. I have checked if any CSS attribute might be interfering, but I didn't find a relevant one.
Is my JS bad?
Assuming your use of Velocity is correct, your code is causing a lot of stress for the browser.
What you should do is first cache the layout values that don't change:
var window_h = $(window).height()/1.2
and:
var ability_top = $('.ability-self').offset().top
And second, debounce the scroll event handler, since scroll is triggered a lot and you only need to respond once every frame, or possibly even less. For debouncing you could use lodash's or Underscore's _.debounce() or just copy paste the implementation, so your code would look like:
$(document).on('scroll', _.debounce(function(){
// code here...
}, 50))

Smooth translation on mouse move

I'm trying to make 3D layer effect like on this page:
Example Page:
http://cloudraiders.com/
I did almost everything, but have one big problem that can't handle:
$("#mainView").mousemove(function( event ) {
//getting mouse dimentions
var pageX = event.pageX;
var pageY = event.pageY;
var mainWidth = $(this).width();
var mainHeight = $(this).height();
//
//console.log(pageX);
("#mainView").find("li").each(function( index ) {
var depth = $(this).attr("dataDepth");
var scalable = $(this).attr("scalable");
var x = pageX*depth;
var y = pageY*depth;
var z = 0;
var thisScale = mainWidth / mainHeight * 1;
//setting accelerated webkit transform
$(this).css("-webkit-transform", "translate3d("+x+"%,"+y+"%,"+z+"px"+")");
});
});
The problem is, that translate3d is not smooth like in example page. It is jumping.
When I'm moving mouse out of the window, and then enter in different place it is just jumping.
I'v found some solution in forum already, but didn't work to good with mouse move.
Any help will be a lot appreciated.
Regards!
EDIT:
I'v used Jquery animate function:
$(this).animate({ whyNotToUseANonExistingProperty: 100 }, {
step: function(now,fx) {
$(this).css('-webkit-transform',"translate3d("+x+"%,"+y+"%,"+z+"px"+")");
},
duration:100
},'linear');
It works almost good, but the problem is, that Jquery is stacking queries. And if I will move mouse alot, animations goes on like for minute.
When dealing with css animation/transformation, there is some performance trickt bear in mind. one of them is to set a default transform value (set to 0) in order to enable the rendering those element by default.
Try addind those rule as default in your css to your animated element ("li" in your case):
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
Also, note that the website linked in your answer use the jquery parallax plugin, which take care of those accelerations issues for you.
And here some ressource about css transform/animation acceleration:
Increase Your Site’s Performance with Hardware-Accelerated CSS
DOM, HTML5, & CSS3 Performance
Related stackoverflow question
If you expect soft transition you should tell it somewhere to the browser. Just add this style and customize it. Do it in the style-sheet not inside your evented JavaScript. Handle all the prefixes.
#mainView{
transition:all 0.5s ease-in;
}

Categories

Resources