Scale and move a text smoothly with javascript
I'm having a text scaled and moved via JavaScript / jQuery. I can't use jQuerys animate() because it has to fade in and out and has to be repeated and with more elements (end result: "flying" from the background, moving in different directions and fading out).
My problem: It's not running smoothly and causes quite the cpu-usage. Here's a stripped down version:
<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script type="text/javascript">
var steps = 300; // steps from start to finish
// the final css values
var endValueTop = 300;
var endValueLeft = 300;
var endValueFontSize = 100;
// the current css values (get encreased in doAnimation())
var currentValueTop = 100;
var currentValueLeft = 100;
var currentValueFontSize = 0;
// the added values in each step
var stepsTop = (endValueTop - currentValueTop) / steps;
var stepsLeft = (endValueLeft - currentValueLeft) / steps;
var stepsFontSize = (endValueFontSize - currentValueFontSize) / steps;
function doAnimation() {
// increase current values
currentValueTop += stepsTop;
currentValueLeft += stepsLeft;
currentValueFontSize += stepsFontSize;
// apply them
$("#hello").css({
top: currentValueTop,
left: currentValueLeft,
fontSize: currentValueFontSize
});
// restart if there are steps left
if (steps--) {
window.setTimeout(function(){
doAnimation();
}, 50);
}
}
// start the first time
doAnimation();
</script>
<style>
article, aside, figure, footer, header, hgroup,
menu, nav, section { display: block; }
body { position: relative; }
p#hello { position: absolute; top: 100px; left: 100px; font-size: 0px; }
</style>
</head>
<body>
<p id="hello">Hello World</p>
</body>
</html>
Running example on JS BIN.
Any suggestions? Bonus: How to reduce the cpu load? Thanks a lot!
S开发者_开发百科teffen
Well first off, absolutely do not use jQuery within a 50ms timer. If anything is causing high CPU usage it is that. Use something like this instead
var hello = $('#hello')[0].style;
function doAnimation() {
//code...
hello.top = curentValueTop + 'px';
hello.left = currentValueLeft + 'px';
hello.fontSize = currentValueFontSize + 'px';
//rest of code...
}
However, smoothly and consistently scaling of fonts is something most browsers do not handle well. Since 99% of the time the text on a web page is not flying into your face, we do not notice this. You might have more luck with an image of the text rendered at the maximum font size you need.
Also, 50ms ~= 20fps which is not a particularly smooth frame rate for animations that traverse half of the screen. If not using jQuery significantly reduces CPU usage you could try a smaller interval. Of course most browsers are not good at handling high frame rate animations either.
Yup, modern web browsers, struggling to do things that 20 year old video game consoles had no problem with, at a quarter of the frame rate.
EDIT Try this http://jsbin.com/oxode/4/edit
I used the em
unit for fontSize
as it accepts fractional numbers, and used a 15ms timer (about 60fps if the browser can keep up). As you can see it scales smoother, although you will have to adjust your animation settings a bit...
I've used this library some years ago quite successfully on cellphones, maybe it has little enough overhead to make it fast enough for you:
http://dev.opera.com/libraries/animation/
jQuery wasn't really designed for long animations (that's why "slow" is less than 1 second) so high CPU load isn't really going to go away.
One thing you could do is to use the animate function http://api.jquery.com/animate/
That already does a lot of what you had programmed there.
<!DOCTYPE html><html><body>
<style>
#txt{position:absolute; left:0px;}
</style>
<div id="txt">Salam</div> <br><br>
<button onclick="setTimeout(fn, 200)">GO ON</button>
<script>
function fn() {document.getElementById("txt").style.left="200px";
document.getElementById("txt").style.transition="2s";
}
</script></body></html>
Native JS and CSS can handle this. In the CSS, set your default text position. In JavaScript, 2 steps: 1 = Set the new position. 2 = Add "transition" value to you style attibute.
精彩评论