Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/GIF #43 #44

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

Conversation

EmilienLeroy
Copy link
Contributor

@EmilienLeroy EmilienLeroy commented Apr 26, 2020

GIF Component

See #43

I have create the GIF component using gifken
But there are a trouble with compressed gif see this issue

GIF component state :

  • drawCurrentFrame
  • loop
  • currentFrameIndex
  • currentFrame
  • currentFrameCompletion
  • pause
  • resume
  • play
  • restart
  • goToFrame

Example

export default function MyComponent() {
  useType(MyComponent);

  const gif = useNewComponent(() => GIF({
    url: someGifFile, 
    width: 267, 
    height: 200, 
    fps: 25,
    loop: true
  }));

  gif.play()

  useDraw((context) => {
    gif.drawCurrentFrame(context);
  });
}

@suchipi
Copy link
Owner

suchipi commented May 19, 2020

Sorry I haven't reviewed this yet. I've been pretty overwhelmed with life stuff recently. I appreciate your work here though, and I hope to get to this soon.

@EmilienLeroy
Copy link
Contributor Author

EmilienLeroy commented May 20, 2020

@suchipi
No prob! The feature isn't finish yet. I will complete this when I will have some free time 😉

@EmilienLeroy EmilienLeroy marked this pull request as ready for review June 1, 2020 14:42
@EmilienLeroy
Copy link
Contributor Author

This is a first version of GIF component. The trouble with compressed gifs was fixed by a little trick (see this issue for more information).
Result into hex-engine:
hex-test2

@suchipi
Copy link
Owner

suchipi commented Jun 2, 2020

Thanks! :D I'll try to review this soon.

Copy link
Owner

@suchipi suchipi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for doing this! I know it took a lot of research and talking to people to get gifken to handle transparent GIF frames. I'm sorry it took me so long to review it. Life has been stressful lately.

I left some comments; there are a couple things we'll need to change before this can be merged. The main thing is that we should use the Animation component instead of setInterval.

If you'd like, I can finish this work on your behalf. Or, I can leave it to you. Whichever you prefer.

packages/2d/src/Components/GIF.ts Outdated Show resolved Hide resolved
packages/2d/src/Components/GIF.ts Outdated Show resolved Hide resolved
height: options.height,
})

setInterval(() => {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setInterval will keep playing forwards even if the game is paused from the developer inspector or the component is disabled. Could you instead use the Animation Component, which will only run when the game's frames advance?

* url: someGifFile,
* width: 200,
* height: 200,
* fps: 20,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible for GIFs to have frames with different lengths; one frame can be long and the other can be short. Does gifken support this?

If you change the code to use the Animation component, you can specify the duration of each frame, and it will handle advancing to the next frame at the right time for you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have find in the gifken documentation a property called delayCentiSeconds
I don't know if is exaclty what we want but i can test to set this property as duration when i will update the GIF component with the Animation component.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, sounds good! You can use https://ezgif.com/maker to make a GIF that has frames with differing durations.

@EmilienLeroy
Copy link
Contributor Author

@suchipi
I have update the component description and adds the Preloader.
Using the Animation component is a bit harder for me. Do you have some example with this component ?

@suchipi
Copy link
Owner

suchipi commented Jul 14, 2020

The Aseprite component uses Animation: https://github.com/suchipi/hex-engine/blob/43cd447c99611d7eb9e9a0305b60edf5b660de45/packages/2d/src/Components/Aseprite.ts

In your code you'll want to:

  • Draw each frame of the GIF on its own to fix the transparency problem
  • Create an AnimationFrame holding each frame image, with the duration set the appropriate duration for that frame
  • Put those frames into an Animation component like so:
    const animation = useNewComponent(() => Animation(frames, { loop: true /* unless the GIF doesn't loop */ }));
  • Call play on that animation once to start it:
    animation.play();
  • Expose the AnimationAPI from that animation in the return value of your GIF component:
    return {
      getGif() {
        return gif;
      },
      drawCurrentFrame(context: CanvasRenderingContext2D, x: number = 0, y: number = 0) {
        if (animation.currentFrame) {
          context.drawImage(animation.currentFrame.data, x, y);
        }
      },
      get frames() { return animation.frames; },
      get loop() { return animation.loop; },
      set loop(newValue) { animation.loop = newValue; },
      get currentFrameIndex() { return animation.currentFrameIndex; },
      get currentFrame() { return animation.currentFrame; },
      get currentFrameCompletion() { return animation.currentFrameCompletion; },
      pause() { animation.pause(); },
      resume() { animation.resume(); },
      play() { animation.play(); },
      restart() { animation.restart(); },
      goToFrame(frameNumber: number) { animation.goToFrame(frameNumber); },
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants