JSFiddle - React, Tailwind, and code Playground

Paint API and keyframes experiments

by Travis Almand

HTML

<div class="container square"></div>

<div class="container rectangle"></div>

SCSS

.container {
  --color: red;
  --size: 20;
  border: 3px solid rebeccapurple;
  margin: 20px;
  
  &:hover {
    //animation: 1s linear 0s infinite alternate tick;
    animation: 1s linear 0s forwards around;
    background-image: paint(paint-test);
  }
  
  &.square {
    height: 200px;
    width: 200px;
  }
  &.rectangle {
    height: 200px;
    width: 400px;
  }
}

@keyframes around {
  0% {
    --x: 0%;
    --y: 0%;
    --opacity: 0%;
  }
  25% {
    --x: 100%;
    --y: 0%;
    --opacity: 100%;
  }
  50% {
    --x: 100%;
    --y: 100%;
    --opacity: 100%;
  }
  75% {
    --x: 0%;
    --y: 100%;
    --opacity: 100%;
  }
  100% {
    --x: 0%;
    --y: 0%;
    --opacity: 0%;
  }
}

JavaScript

CSS.registerProperty({
	name: '--x',
  syntax: '<percentage>',
  inherits: false,
  initialValue: '0%'
});
CSS.registerProperty({
	name: '--y',
  syntax: '<percentage>',
  inherits: false,
  initialValue: '0%'
});
CSS.registerProperty({
	name: '--color',
  syntax: '<color>',
  inherits: false,
  initialValue: 'transparent'
});
CSS.registerProperty({
	name: '--opacity',
  syntax: '<percentage>',
  inherits: false,
  initialValue: '100%'
});

CSS.paintWorklet.addModule(URL.createObjectURL(new Blob([`
class PaintTest {
  static get inputProperties() { return ['--x', '--y', '--size', '--color', '--opacity']; }

  paint(ctx, geom, properties) {
    const x = parseInt(properties.get('--x')) / 100;
    const y = parseInt(properties.get('--y')) / 100;
    const size = parseInt(properties.get('--size'));
    
    ctx.filter = 'opacity(' + properties.get('--opacity') + ')';
    ctx.fillStyle = 'red';
    ctx.beginPath();
    
    ctx.arc(geom.width * x, geom.height * y, size, 0, 360, false);
        
    ctx.fill();
  }
}

// Register our class under a specific name
registerPaint('paint-test', PaintTest);
`], {type: "application/javascript"})));