Skip to main content

How to apply canvas filters with React and Konva?

To apply filters to a Konva node, you need to:

  1. Cache the node using node.cache()
  2. Apply filters using the filters prop
  3. Re-cache the node when its properties change
import React from 'react';
import Konva from 'konva';
import { Stage, Layer, Rect, Image } from 'react-konva';
import useImage from 'use-image';

// Example of functional component with image filter
const FilterImage = () => {
  const [image] = useImage('https://konvajs.org/assets/lion.png', 'anonymous');
  const imageRef = React.useRef();

  // when image is loaded we need to cache the shape
  React.useEffect(() => {
    if (image) {
      // you many need to reapply cache on some props changes like shadow, stroke, etc.
      imageRef.current.cache();
    }
  }, [image]);

  return (
    <Image
      ref={imageRef}
      x={10}
      y={10}
      image={image}
      filters={[Konva.Filters.Blur]}
      blurRadius={10}
    />
  );
};

// Example of class component with noise filter
// Try to click on rect to see color updates
const FilterRect = () => {
  const [color, setColor] = React.useState('green');
  const rectRef = React.useRef();

  React.useEffect(() => {
    if (rectRef.current) {
      rectRef.current.cache();
    }
  }, []);

  const handleClick = () => {
    setColor(Konva.Util.getRandomColor());
    // recache shape when we updated it
    rectRef.current.cache();
  };

  return (
    <Rect
      filters={[Konva.Filters.Noise]}
      noise={1}
      x={200}
      y={10}
      width={50}
      height={50}
      fill={color}
      shadowBlur={10}
      ref={rectRef}
      onClick={handleClick}
    />
  );
};

const App = () => {
  return (
    <Stage width={window.innerWidth} height={window.innerHeight}>
      <Layer>
        <FilterImage />
        <FilterRect />
      </Layer>
    </Stage>
  );
};

export default App;