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