Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
fripi

Animate CC - AS2 smoke effect

Recommended Posts

Hi everyone,

 

most of the time I create banners with simple DOM elements and GSAP, but a clients wants to use an old 2014 banner I did in AS2,

so I could do it from scratch in DOM but I tought it would be a nice exercice to try out Animate CC.

 

I already followed this great guide from Cory and learned some things regarding global vars, functions... it's impressive what comes out of Animate.

 

But I'm stuck on a smoke effect function:

import flash.display.BitmapData;

var currentBitmap:String = "smoke_black.png";
function doTrail(container:MovieClip, targetX:Number, targetY:Number, type:String):Void{

	//attach bitmap from the library with the linked name "adobe_flash"
	var myBmp:BitmapData = BitmapData.loadBitmap(currentBitmap);
	
	//create the "main_holder" movieclip that will hold our bitmap
	var _particle = container.createEmptyMovieClip("main_holder"+container.getNextHighestDepth(), container.getNextHighestDepth());
	
	//create an "internal_holder" movieclip inside "main_holder" that we'll use to center the bitmap data
	var internal_holder:MovieClip = _particle.createEmptyMovieClip("internal_holder", _particle.getNextHighestDepth());
	
	//set "internal_holder" x and y position based on bitmap size
	internal_holder._x = -myBmp.width/2;
	internal_holder._y = -myBmp.height/2;	
	
	//finally, attach the bitmapData "myBmp" to the movieclip "internal_holder"
	internal_holder.attachBitmap(myBmp, internal_holder.getNextHighestDepth()); 
		
	//set the particle's x & y position based on the target x & y. Offset the particle by a few pixels
	_particle._x = targetX + random(4)-8;
	_particle._y = targetY + random(4)-8;

	//randomly rotate the particle 360 degrees
	_particle._rotation = random(360);

	//give the particle a random scale, between 50% and 100%
	var randomScale = random(20);
	_particle._xscale = randomScale;
	_particle._yscale = randomScale;

	//give each particle its own speed
	_particle.speed = random(3)+1;

	//make it move
	_particle.onEnterFrame = function (){
		this._xscale += 2+this.speed;
		this._yscale += 2+this.speed;
		this._y -= this.speed;
		this._alpha -= this.speed;

		//check if particle is invisible, and remove it
		if(this._alpha <= 0){
			delete this.onEnterFrame;
			removeMovieClip(this);			
		}
	}
}

This function is called from another point in the timeline by this:

_root.onEnterFrame = function():Void{
	doTrail(container, 0, 0, currentBitmap);
}

So I think the onEnterFrame could be replaced by an interval or something like

createjs.Ticker.addEventListener("tick", doTrail);

And some elementys like _x can easely be replaced by removing the underscore but it's more the logic of attaching a bitmap that I can't find how to do.

 

It was a very basic code in AS2 so I hope that some of the genius present in this community can help me out with it.

 

Thank you

Link to post
Share on other sites

I'll try to understand this code, but canvas is so hard :-D

Link to post
Share on other sites

You can have two canvas elements, with different IDs. So you export your banner like always from Animate and then use the codepen above for the second canvas object, and layer the second canvas element using CSS to position it where you want it.

 

http://stackoverflow.com/questions/6787899/combining-two-or-more-canvas-elements-with-some-sort-of-blending

 

.

Link to post
Share on other sites

Hi,

 

Thank you, I finally used this code:

See the Pen iBKyC by MIML (@MIML) on CodePen

 

but as I don't really understand the JS code used for the canvas I'm stuck on the loop, how can I stop it after 15s?

Link to post
Share on other sites

ok I found how, I stop it in 2 steps, first I stop emitting particles after 13s but the loop continues to run so that the existing particles can vannish

then I stop the loop after 15s:

var start = null;
function renderSmoke(timestamp) {
      if (!start) start = timestamp;
      var progress = timestamp - start;
      //console.log(progress);
      var len = parts.length;
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      while (len--) {
          if (parts[len].y < 0 || parts[len].lifeTime > maxLifeTime) {
              parts.splice(len, 1);
          } else {
              parts[len].update();

              ctx.save();
              var offsetX = -parts[len].size/2,
                  offsetY = -parts[len].size/2;
           
              ctx.translate(parts[len].x-offsetX, parts[len].y-offsetY);
              ctx.rotate(parts[len].angle / 180 * Math.PI);
              ctx.globalAlpha  = parts[len].alpha;
              ctx.drawImage(smokeImage, offsetX,offsetY, parts[len].size, parts[len].size);
              ctx.restore();
          }
      }
      if (progress < 13000 || !progress ) {
        spawn();
      }
      if (progress < 15000 || !progress ) {
        requestAnimationFrame(renderSmoke);
      } else{
        TweenMax.to(canvas,1,{autoAlpha:0})
      }
  }

So in the code I added/changed this :

var start = null;
  
if (!start) start = timestamp;
var progress = timestamp - start;
      
if (progress < 13000 || !progress ) {
  spawn();
}
if (progress < 15000 || !progress ) {
  requestAnimationFrame(renderSmoke);
} else {
  TweenMax.to(canvas,1,{autoAlpha:0})
}

Is there a better way?

Link to post
Share on other sites

Using TweenLite.delayedCall() is the best way to schedule something animation related. It's actually a tween, so you can call normal tween methods on it like play, pause, and restart.

 

To create a interval timer using delayedCall, you can do something like this...

var spawnFreq = 0.04;

var interval = TweenLite.delayedCall(spawnFreq, function() {
  // Spawn particle
  interval.restart(true);
});

To schedule something to happen once, you can use delayedCall like this...

var spawnTime = 13;
var emitter = new Emitter();

TweenLite.delayedCall(spawnTime, function() {
  emitter.stop();
});

I made a couple versions of the example you linked to using modern JavaScript (ES6). If you don't use ES6, it's real easy to convert. It looks like most of the particle properties can be tweened. I also added in a random function if you wanted to add more randomness to the smoke.

 

Toggle smoke - 

See the Pen 6e7cd7f75fb657f16a97b78f5be172aa?editors=0010 by osublake (@osublake) on CodePen

Timed smoke - 

See the Pen b8f12be21f06889e3e8c985925abc821?editors=0010 by osublake (@osublake) on CodePen

  • Like 3
Link to post
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.

×