hex-engine icon indicating copy to clipboard operation
hex-engine copied to clipboard

Feature/GIF #43

Open EmilienLeroy opened this issue 4 years ago • 6 comments

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 :

  • [X] drawCurrentFrame
  • [X] loop
  • [x] currentFrameIndex
  • [x] currentFrame
  • [x] currentFrameCompletion
  • [X] pause
  • [X] resume
  • [X] play
  • [X] restart
  • [x] 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);
  });
}

EmilienLeroy avatar Apr 26 '20 16:04 EmilienLeroy

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.

suchipi avatar May 19 '20 23:05 suchipi

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

EmilienLeroy avatar May 20 '20 07:05 EmilienLeroy

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

EmilienLeroy avatar Jun 01 '20 14:06 EmilienLeroy

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

suchipi avatar Jun 02 '20 05:06 suchipi

@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 ?

EmilienLeroy avatar Jul 13 '20 14:07 EmilienLeroy

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); },
    }
    

suchipi avatar Jul 14 '20 07:07 suchipi