Jump to content
Search Community

Animation in canvas

Guest newdevide
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Guest newdevide

Hi, just a few quick question.

 

I've been trying to learn html5 canvas. It's hard, especially when i don't have any javascript basic programming.

 

How do i animate all the stuff in canvas using greensock js animation tool?

 

There's a script like this:

var canvas = document.getElementById("myCanvas");

var context = canvas.getContext("2d");

 

Now from the documentation i know you get the element id and animate it (NOT IN CANVAS). But in canvas do i have to make a lot of context (like the script above, so i make context1 context2 etc), then animate it by its context name?

 

Another thing. How do i animate an object where its starting alpha = 0, then turn it to 100? Sorry, i still confused on how to animte things in html

 

Thx 4 all the help

Link to comment
Share on other sites

Don't fret, some canvas demos and tips are on the way.

For now, check out Lee Brimelow's intro to TweenLite JS here:

http://gotoandlearn.com/play.php?id=161

 

He uses the canvas at the end.

 

If you are a flash developer, EaselJS can make the canvas much more approachable:

http://createjs.com/#!/EaselJS

 

I would recommend investigating some pure canvas tutorials just to get some of the concepts down. Lee's video does a great job of showing enough to get you started.

  • Like 1
Link to comment
Share on other sites

Guest newdevide

Thx for the reply.

Can i have one simple question.

So i have a div with the id="img1", how do set the initial alpha state = 0?

If i'm not mistaken i could use tweenMax to animate its alpha, but how do i make the initial alpha state = 0?

 

Thx

Link to comment
Share on other sites

The easiest way would probably be to set the div's css "visibility" property to "hidden" and then use TweenLite or TweenMax to tween autoAlpha to 1. The latest version will automatically assume that the initial value of "visibility:hidden" means alpha should start at 0 too, and it will fade it in.

  • Like 1
Link to comment
Share on other sites

Guest newdevide

OK, one more thing. Ic ould use somea advice.

 

I'm trying (real hard) to study both the TweenLite JS here and the easelJS, in your opinion, which one will better in the future, for me to use?

Link to comment
Share on other sites

please understand that in these forums you are undoubtedly going to get an answer that favors TweenLite:)

 

To be fair though, the tools serve different purposes. TweenLite JS ( and other tools in the GreenSock Platform) are focused on creating rich animations. EaselJS is simply a tool that makes working with the canvas more 'flash-like'.

 

Canvas is a great technology with a lot of promise but many devs will say that it's implementation is not consistent and its performance really suffers on mobile devices.

 

TweenLite has benefits that go beyond the canvas. You can create amazing animations that run super fast in the DOM, you can plug it into raphael.js (for animating vectors), and it also works with canvas + more.

 

In short the GreenSock Animation Platform does "more cool stuff in more places".

 

So that's my official marketing stance.

---

 

As a Flash developer that absolutely trembled at the thought of using javascript or working "directly in the browser" I found the new GreenSock JS tools to be an absolutely amazing way to have fun and learn of all the power that is available outside of Flash.

 

I would suggest that instead of going with canvas/easelJS that you learn a little bit about how jQuery selectors work http://net.tutsplus.com/articles/news/learn-jquery-in-30-days/ this will help you get up to speed with how to easily select elements that you want to tween. Just watch the first 4 videos to get a decent grasp.

 

Read the GSAP javascript getting started page: http://www.greensock.com/get-started-js/

And in addition to reading actually try typing the code on that page AND experiment with tweening different properties.

 

I totally understand that it can be a lot to digest. I think you will find that after you get over a few bumps in the road that it won't take long before it all starts coming together.

 

The absolute best thing you can do in addition to reading the GreenSock documentation and trying things on your own is to visit these forums regularly and just read. You will see a ton of great solutions to real-world problems.

 

Stay tuned for more js-related tutorials and getting started tips. There is a lot of new training material in the works.

  • Like 1
Link to comment
Share on other sites

Guest newdevide

To Carl Schoof, 100 bows to you man. If you were here (Indonesia) i'll buy a glass of beer and tons of pizza. Your explanation is very straight forward and easy to grasp. Thx for the link 2.

 

And please, please don't get bore of me man. Coz i'm new and i really2 need a lot of guidance (which meand a lot of asking silly and stupid questions here). :-P

 

Thx

Link to comment
Share on other sites

  • 3 weeks later...

Has anyone else had trouble with Lee's Canvas tutorial?

 

I can't get even his provided download file ("canvas.html") to work! (The other two "photo" and "css" work just fine).

I was trying to troubleshoot my own work (getting a blank page) and realized that I get a blank page with Lee's files as well?

Link to comment
Share on other sites

Yeah, it seems that the current files that Lee provides are just starter files.

When his video first launched I plugged in the canvas code from the video.

In canvas.html use this script in the head

 

 

<script>

var ctx, img;

function init() {
ctx = document.getElementById("canvas").getContext("2d");
console.log('s');
img = new Image();
img.xpos = 50;
img.ypos = 50;
img.src = "enemy.png";
img.onload = function() {
animate();
}

TweenMax.to(img, 4, {xpos:500, ypos:500 });
TweenLite.ticker.addEventListener("tick", animate);
}

function animate() {
ctx.clearRect(0,0,800,600);
ctx.drawImage(img, img.xpos, img.ypos);
}

</script>

Link to comment
Share on other sites

  • 8 months later...

looking at your code above, I can see that its working but the bug is not following its path. so I put an autoRotate:true property but it didn't work.

 

Also, when I delete the autoCSS:false property to replace a css property before the bezier property, its also not working.

 

In the modified code below, I put the last working code from the previous bug demo including the delayedCall function and its all screwed up.

 

Can you please check again why its not working?

 

http://jsfiddle.net/anagnam/eDt6E/3/

Link to comment
Share on other sites

First, sorry I didn't explain the fiddle more, I was short on time.

 

A few things to help deal with your problems

 

1) When dealing with canvas elements you aren't tweening css properties any more. You don't need the css{} object in your tweens. But since CSSPlugin is loaded with TweenMax and BezierPlugin is compatible with CSSPlugin, assumptions are made that you are tweening CSS properties especially since img is a DOM element. In this rare case canvas + bezierplugin + dom target, its necessary to go the extra step of setting autoCSS:false so that they engine skips the step of creating the css{} object.

 

2) When working with canvas, the developer has a lot of responsibility in making sure that objects are positioned, rotated and scaled properly. TweenLite only changes numbers, its up to the developer to use those numbers in a way that translates to objects moving across the screen.

 

In the Lee example. The drawImage() method was responsible for taking the properties that were tweened: img.x and img.y and using them to reposition the img on the next screen re-draw.

 

In order for autoRotate to work, the object that is being rotated needs to have a rotation property (or one that you specify, see BezierPlugin docs) Your img object only has xpos and ypos. The BezierPlugin doesn't know where to apply the rotation unless you tell it.

 

In short you would need to:

 

1) create img.rotation property

2) use a method in addition to drawImage() that will modify the display of the img and make it appear rotated.

 

#2 is no small task. See: http://creativejs.com/2012/01/day-10-drawing-rotated-images-into-canvas/

 

Since something as simple as rotation is such a hassle, many 3rd-party canvas libraries have come around like KineticJS to make it much easier. KineticJS objects have built-in methods like

setRotationDeg(), setX() and setY() that make object manipulation MUCH easier. TweenLite works great with KineticJS and you can animate KineticJS methods directly in most cases.

 

KineticJS: http://kineticjs.com/ read the docs and tutorials

 

Here is a demo I created awhile ago using KineticJS with TweenLite: http://www.snorkl.tv/2012/06/exploring-generative-canvas-art-with-tweenmax-js-and-kineticjs/

 

But really, before getting into all that, I would recommend starting with some basic canvas tutorials so that you can better understand the benefits and challenges: http://www.html5canvastutorials.com/tutorials/html5-canvas-element/

 

Unfortunately I can't take your entire dom animation and convert it canvas, but take a look here: http://jsfiddle.net/Xg95u/2/

 

It has 1 bug following a random path that gets reset repeatedly. Yes, autoRotate won't work unless you come up with a custom implementation. Again, TweenLite can only tween the rotation values, you would have to calculate how those values affect the display of the img.

 

Hopefully this helps you on your way.

Link to comment
Share on other sites

Yep, Carl hit pretty much all the points I was going to make. I'll offer a few things (some of which reiterate what Carl said):

 

Since you're not trying to animate css-related properties (in your case, xpos and ypos), you should NOT be tucking your values into a css:{} object. 

 

As far as autoRotate not working, that's because when you set autoRotate to "true", it assumes that it's supposed to use "x" and "y" properties of the target and figure out the rotation according to those, but your object doesn't use "x" or "y" (it doesn't even have those properties) - you're using xpos and ypos. But don't worry - BezierPlugin can accommodate just about any values. If you read the docs about autoRotate, you'll see that you can pass in an array of 4 values that tell it how to apply autoRotate. In your case, you should add a "rotation" property to your img, set it to zero, and then your autoRotate should look like this:

 

autoRotate:["xpos","ypos","rotation",0]

Docs are here: http://api.greensock.com/js/com/greensock/plugins/BezierPlugin.html

 

And to actually cause the rotated value to affect the canvas, you must draw it differently - this has nothing to do with GSAP; it's just how drawing to the canvas works. Your animate() method could look like this:

 

function animate() {
    ctx.clearRect(0,0,600,600);
    var x = img.xpos,
        y = img.ypos,
        angle = img.rotation * Math.PI / 180,
        width = img.width,
        height = img.height;
    ctx.translate(x, y);
    ctx.rotate(angle);
    ctx.drawImage(img, -width / 2, -height / 2, width, height);
    ctx.rotate(-angle);
    ctx.translate(-x, -y);
}

Here's a revised jsfiddle: 

http://jsfiddle.net/84YTk/

 

I hope that helps.

  • Like 1
Link to comment
Share on other sites

And to get things complicated (for me), I managed to convert the bug png file to an actual canvas bezier curves. please view the source in the link below:

 

http://relumastudio.com/download/green-bug.html

 

I understand that tweenmax can animate numbers. but with tons of bezier points to animate on just the 1 bug as shown on the link above... its imposible for me to animate say hundreds of thousands of bugs.

 

I already tried wrapping it into a function that I can call in tweenmax but no luck.

 

So any hint on how I can animate those canvas bezier points in tweenmax???

Link to comment
Share on other sites

Oh, I think you'd get much better performance by just using a bitmap and drawing that. Just a guess. You could probably also draw the bug to a canvas the way you did and then draw that canvas to another canvas, thus just repositioning the position/rotation/scale of the canvas instead of worrying about every little Bezier point inside the bug. 

Link to comment
Share on other sites

  • 1 year later...

Does anybody know/example with animating an image sequence (not a sprite image) into a canvas element.

I would like to use the power of TimeLine in order to control the Tween (pause, stat, stop)

 

It exists an example with image elements: 

See the Pen dkugc by anon (@anon) on CodePen

The main idea is here http://stackoverflow.com/questions/22411994/preloading-image-sequence-on-html5-canvas

 

But I would like in a canvas element

 

Thanks for your ideas.

Link to comment
Share on other sites

Hi,

 

Lately I've been looking a little into Pixi and it has quite some features into it.

 

What I've been using is the Movie Clip class, which allows you to build an animation from a sprite sheet and performs quite good, even in middle-end devices. What I haven't use is the Spine class, which also use a sprite sheet, but in a completely different way. Check out the samples of the spine class.

 

Besides Pixi I don't know of any other framework that could do the same, perhaps a framework used for game development, maybe other users could give more tips in this matter.

 

Rodrigo.

Link to comment
Share on other sites

Thank for your answers. It's useful ressources.

I try to achieve the complete animation like this : http://forums.greensock.com/topic/6338-animating-and-controlling-image-sequence/#entry22958

 

BUT, into one single Tween: which I can play(), pause() exactly like this: 

See the Pen aJcGl by jamiejefferson (@jamiejefferson) on CodePen

 

But for performance (DOM manipulations) into my game, I can't insert 60-80 images elements per animations (example:2).

So the example 1 is interesting but I need to rewrite at 30 fps into one single Tween. Here I need your help.

Link to comment
Share on other sites

Hi Maxime  :)

 

try this :

preload your images , change your src attr with one Tween and easily control that  :



var anim = {frame:0} ;
TweenMax.to(anim , 1, {frame:"+=25", roundProps:"frame", onUpdate:updateHandler });

function updateHandler() {
image.attr("src", "images/character"+anim.frame+".png");
}


with this method you don't need extra DOM objects .

 

hope this helps :)

 

 Edit : u can find easy way to preload images  by  Rodrigo  here :


  • Like 2
Link to comment
Share on other sites

Yes roundProps is the solution. Thank you very much. This helps!

 

I have a small problem: the update Handler is too fast.

I need to run a 30fps animation.

 

I run it as follow:

var fps          = 30,
		currentFrame = 0,
		totalFrames  = 25,
		$img          = $("#myImage");

	
	var anim = {frame:0};
	TweenMax.to(anim , totalFrames/fps, {frame:"+="+totalFrames, roundProps:"frame", onUpdate:updateHandler, repeat: 1 });

	function updateHandler() {
		var frameNum = anim.frame;
		console.log('set ',anim.frame);
		$img[0].src = "./img/test/ace_0" + (frameNum < 10 ? "0" : "") + frameNum + ".png";
	}

It try to set too many times the same image:

Output this:

set  0 - repeat 1
set  1 - repeat 1
set  2 - repeat 2
set  3 - repeat 2
set  4 - repeat 1
set  5 - repeat 3
set  6 - repeat 1
set  7 - repeat 1
set  8 - repeat 3
set  9 - repeat 3
set  10 - repeat 1
set  11 - repeat 1
2set  12 - repeat 1
set  13 - repeat 1
set  14 - repeat 1
set  15 - repeat 1
set  16 - repeat 11x
2set  17 - repeat 11x
set  18 - repeat 11x
set  19 - repeat 11x
set  20 - repeat 11x
2set  21 - repeat 11x
set  22 - repeat 11x
set  23 - repeat 11x
2set  24 - repeat 11x
set  25 - repeat 11x
 
 
I think my timing is not right : totalTime =  totalFrames/fps
Or some delays somewhere?
Link to comment
Share on other sites

Hi Maxime,

 

You can set the frequency GSAP updates with this:

TweenLite.ticker.fps(30);

But be aware that this is a general settting, so it'll affect everything you do with GSAP.

 

If you need other part of your app running at the common 60 fps, please check the following post:

 

http://forums.greensock.com/topic/9881-avoid-multiple-loaded-tweenmax-and-tweenlite/

 

Rodrigo.

Link to comment
Share on other sites

Hi everyone,

 

Changing the src attribute of image works well when the image element have the exact same size as the new image.

 

I have the following problem:

(After an initial preload)

 

When I set a retina image src (60x/second) twice bigger but resized by the CSS, the animation make a new HTTP request for this image. In other words, every frames creates new HTTP request.

 

My server + browser are overloaded...

 

Why setting an url of an image of 332x312 into the following tag create extra HTTP request?

<img style="width:166px; height:156px;" width="332" height="312" src="/images/ipad_2x/symbols/id_009@2x.png">
No extra http request when:
<img style="width:166px; height:156px;" width="166" height="156" src="/images/ipad_1x/symbols/id_009.png">
I already set a maxAge of 1 year for the assets server side

express.static('/images',{ maxAge: oneYear}));
Should I consider, deleting the DOM image and replacing with a new element ? :(
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...