1.0.1 • Published 4 years ago

@stkterry/react-reanim v1.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
4 years ago

@stkterry/react-reanim

Simplify HTML5 canvas animations in React!

NPM JavaScript Style Guide

This project has two primary goals:

1) Prevent React from constantly re-rendering when drawing to the canvas. Essentially, turn the canvas into a mostly static component. 2) Separate the step / draw functionality from the associated boiler-plate common to virtually every canvas animation.

Install

npm install --save @stkterry/react-reanim

Usage

The following results in a simple, spinning cube as a basic example.

import React, { Component } from 'react'

import Reanim from '@stkterry/react-reanim'

export default function Simple() {

  const [angle, setAngle] = useState(0);

  const [style, setStyle] = useState();
  useEffect(() => {
    setStyle({ width: "250px", height: "250px",});
  }, [])

  const step = () => setAngle(angle + 1);

  const draw = ctx => {
    const width = ctx.canvas.width;
    const height = ctx.canvas.height;
    ctx.save();
    ctx.beginPath();
    ctx.clearRect(0, 0, width, height);
    ctx.translate(width / 2, height / 2);
    ctx.rotate(angle * Math.PI / 180);
    ctx.fillStyle = '#4397AC';
    ctx.fillRect(-width / 4, -height / 4, width / 2, height / 2);
    ctx.restore();
  };

  return (
    <Reanim
      step={step}
      draw={draw}
      width="250px"
      height="250px"
      style={style}
    />
  )
}

Reanim Options

Reanim will accept any other attributes that are common to React/canvas and pass them accordingly (className, onMouseOver, style, width, height, etc...).

Important!

If you pass functions or objects to Reanim (excluding step/draw/onClick) without wrapping them in a useCallback or otherwise effectively memoizing them, you will trigger re-renders of the component on every frame! While not necessarily a problem, this can/will affect performance! I'm working on a solution that will auto-memoize commonly passed variables.

Other

Common canvas weirdness still applies to Reanim. It's up to you to know how to wield HTML5 canvas effectively. This component is just a wrapper to separate the step/draw functions from the typical boiler-plate necessary to get a canvas up and running.

Canvas

If you so desire, you can make use of the inner canvas component directly.

import React, { useState } from 'react';

import { Canvas } from '@stkterry/react-reanim';

export default function Example(props) {

  // ... some code here
  // ...
  // ...
  const [ctx, setCtx] = useState();
  // do something with ctx

  return (
    <Canvas setCtx={setCtx} />
  )
};

Note that the only variable Canvas requires is a setCtx function which should assign a 2d context off the node when mounted, otherwise Canvas will accept anything your standard canvas will. Canvas is memoized by default but remember that the contents you pass it may constantly trigger re-renders anyway.

Canvas is just a memoized regular canvas element with a passback for setting context.

Bonus Hooks!

useWindowDims

This hook returns the inner width and height of the current window. It's lightweight and will automatically add/remove the event listener. Updates on resize.

import React from 'react';

import { useWindowDims } from '@stkterry/react-reanim';

export default function Example(props) {

  const windowDims = useWindowDims();

  return (
    <div>
      <h2>innerWidth: {windowDims.width}</h2>
      <h2>innerHeight: {windowDims.height}</h2>
    </div>
  )
}

You may find this useful if you need to dynamically style or control your canvas based on window size.

To Do

  • Add target frame-rate functionality
  • Add collection of convenient hooks for working with the canvas
  • Implement a context simplification library for drawing
  • Add real tests...

License

MIT © stkterry

1.0.1

4 years ago

1.0.0

4 years ago