Jump to content
GreenSock

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

JPG Sequence GSAP

Recommended Posts

Hello everyone,
I used a code that I found here: https://greensock.com/forums/topic/20404-flickering-png-sequence/
Thanks to @OSUblake.

My problem: I have a jpg sequence animation (240 frames) and I would like to navigate between the different frames. Go from 0 to 100 or from 150 to 20. I can go forwards but not backwards. On the first click the animation works but when I click again nothing happens
Here is my code:

HTML

<button class="btn btn1">BOUTON1</button>
<button class="btn btn2">BOUTON2</button>
<button class="btn btn3">BOUTON3</button>

<canvas id="canvas"></canvas>

JAVASCRIPT

var baseURL = "anim3/";
var canvas = document.querySelector("#canvas");
var context = canvas.getContext("2d");

var sprite = {
  frame: 1,
  lastFrame: 240,
  totalFrames: 240,
  textures: []
};

var animation = new TimelineMax({yoyo: true,paused: true,onUpdate: drawSprite})
  .to(sprite, 2, {
    frame: 100,
    roundProps: "frame",
    ease: Linear.easeNone
  });

var animation2 = new TimelineMax({yoyo: true,paused: true,onUpdate: drawSprite})
	.to(sprite, 2, {
		frame: 150,
	 	roundProps: "frame",
	  ease: Linear.easeNone
	});

var animation3 = new TimelineMax({yoyo: true,paused: true,onUpdate: drawSprite})
	.to(sprite, 2, {
		frame: 2,
		roundProps: "frame",
		ease: Linear.easeNone
	});

loadTextures(sprite.totalFrames)
  .then(resizeCanvas)
  .catch(function(reason) {
    console.log(reason)
  });

function drawSprite() {
  // No changes
  if (sprite.frame === sprite.lastFrame) {
		return;
  }
  context.drawImage(sprite.textures[sprite.frame], 0, 0);
  sprite.lastFrame = sprite.frame;
}

function resizeCanvas(textures) {
  var texture = textures[0];
  sprite.textures = textures;
  canvas.width = texture.naturalWidth || texture.width;
  canvas.height = texture.naturalHeight || texture.height;
  canvas.classList.add("is-loaded");
  var aspectRatio = canvas.height / canvas.width;

	// BASE
	base_image = new Image();
  base_image.src = 'anim3/animhead_01.jpg';
  base_image.onload = function(){
    context.drawImage(base_image, 0, 0);
  }
}

function loadTextures(numTextures) {
  var promises = [];
  for (var i = 1; i <= numTextures; i++) {
		var index = i < 100 ? "0" + i : i;
    promises.push(loadTexture(baseURL + "animhead_" + index + ".jpg"));
  }
  return Promise.all(promises);
}

function loadTexture(path) {
  return new Promise(function(resolve, reject) {
    var img = new Image();
    img.onload = function() {
      resolve(img);
    }
    img.onerror = function() {
      reject("Error loading " + path);
    };
    img.src = path;
  });
}


$( ".btn1" ).click(function() {
  animation.play();
});
$( ".btn2" ).click(function() {
  animation2.play();
});
$( ".btn3" ).click(function() {
  animation3.play();
});

Someone can help me ?

Thank you.

Link to post
Share on other sites

Hey oOLucOo and welcome to the GreenSock forums. 

 

A few things:

  • We highly recommend that you use the GSAP 3 formatting:
  • If you want to navigate between frames you can't just have three timelines like that. You need more logic involved. This thread should be able to help you more:
  • If you'd like our help debugging please make a minimal demo.
  • Like 1
Link to post
Share on other sites

Sorry for the format, this is my first post.
Thanks for your feedback. I'll try that.

 

Yet I had the impression of being close. 😀

Link to post
Share on other sites

@ZachSaucier

I tried with the link you gave me (360). The animation is less fluid than with my initial version

Link to post
Share on other sites
3 hours ago, oOLucOo said:

The animation is less fluid than with my initial version

That likely has to do with how many frames you're using per second.

 

To get your demo working you'll need to create a new animation to go to the target frame no matter the direction. It would likely make sense to make a single method that create a new tween animating to a frame that's passed in as an argument. Then all you have to do in click function is call that function with the target frame.

Link to post
Share on other sites

 

my animation is 30 fps

 

Is that right  ?

var animation = new TimelineMax({yoyo: true,paused: true,onUpdate: drawSprite})
  .to(sprite, 2, {
    frame: 60,
    roundProps: "frame",
    ease: Linear.easeNone
  });

 

thank you for your help.

 

 

Link to post
Share on other sites
var sprite = {frame: 1,lastFrame: -1,totalFrames: 239,textures: []};

var animation = gsap.timeline({yoyo: false,paused: true,onUpdate: drawSprite});
animation.to(sprite, 2, { frame: 60,roundProps: "frame",ease: Linear.easeNone });

var animation2 = gsap.timeline({yoyo: false,paused: true,onUpdate: drawSprite});
animation2.to(sprite, 2, { frame: 120,roundProps: "frame",ease: Linear.easeNone });

$(".btn1").click(function() {
  animation.play();
});
$(".btn2").click(function() {
  animation2.play();
});

 

How to do to be able to launch the animation several times?

When I click again on one of the buttons, the animation does not start and I have no error.

 

Thanks

Link to post
Share on other sites

@oOLucOo Please go through the Getting Started with GSAP post:

 

 

As I said before you need to create a new animation each time. You can't just use the same static animations like what you're trying to do.

 

36 minutes ago, oOLucOo said:

I have no error

That's because there isn't an error. Your timeline's playhead is at the end so when you click play again it attempts to go forward but there's nothing left to go forwards towards. Your error is logical (you always tell the same animations to go forward). 

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.

×