<h2>Static elements</h2>
<img style="--n:20;--t:0;--b:20;--na:0;" src="https://picsum.photos/id/1069/150/150">
<img style="--n:12;--t:0;--b:10;--na:0;" src="https://picsum.photos/id/1069/150/150">
<img style="--n:18;--t:1;--b:20;--na:0;--seed:33" src="https://picsum.photos/id/1069/150/150">
<img style="--n:44;--t:0;--b:30;--na:1;" src="https://picsum.photos/id/1069/150/150">
<img style="--n:24;--t:1;--b:78;--na:2;--seed:34" src="https://picsum.photos/id/1069/150/150">
<h2>Hover animations</h2>
<img class="h" style="--n:26;--t:0;--b:20;--v:0;--na:0;" src="https://picsum.photos/id/1074/150/150">
<img class="h" style="--n:20;--t:1;--b:0;--v:50;--na:0;--seed:208" src="https://picsum.photos/id/1074/150/150">
<img class="h" style="--n:30;--t:1;--b:20;--v:-10;--na:0;--seed:566" src="https://picsum.photos/id/1074/150/150">
<img class="h s" style="--n:40;--t:0;--b:0;--v:10;--na:3;" src="https://picsum.photos/id/1074/150/150">
<img class="h s" style="--n:50;--t:1;--b:0;--v:20;--na:4;--seed:115" src="https://picsum.photos/id/1074/150/150">
<h2>keyframes animations</h2>
<img class="a1" style="--n:50;--t:1;--na:0;--seed:123" src="https://picsum.photos/id/1016/150/150">
<img class="a1" style="--n:60;--t:0;--na:2;" src="https://picsum.photos/id/1016/150/150">
<img class="a1" style="--n:12;--t:0;--na:0;" src="https://picsum.photos/id/1016/150/150">
<img class="a2" style="--n:15;--na:5;--seed:50" src="https://picsum.photos/id/1016/150/150">
<img class="a2" style="--n:60;--na:5;--seed:50" src="https://picsum.photos/id/1016/150/150">
<h2>Hover + keyframes animations</h2>
<img class="a2 bo" style="--n:10;--na:6;--seed:385;--v:20" src="https://picsum.photos/id/1022/150/150">
<img class="a2 bo" style="--n:8;--na:6;--seed:966;--v:-100" src="https://picsum.photos/id/1022/150/150">
<img class="a2 bo" style="--n:30;--na:6;--seed:580;--v:50" src="https://picsum.photos/id/1022/150/150">
<img class="a2 bo" style="--n:40;--na:6;--seed:666;--v:-30" src="https://picsum.photos/id/1022/150/150">
<script>
if (CSS.paintWorklet) { CSS.paintWorklet.addModule('/t_afif/pen/f79d9dc54946caa5a416cb7fde5dabaa.js');
} else {
alert("Your browser cannot run this demo. Consider Chrome or Edge instead")
}
</script>
@property --b{
syntax: '<number>';
inherits: false;
initial-value: 0;
}
@property --bo{
syntax: '<number>';
inherits: false;
initial-value: 0;
}
img {
cursor:pointer;
border-radius:50%;
-webkit-mask:paint(blob);
transition:--b .5s,--bo .5s;
}
.h:hover {
--b:var(--v)!important
}
.s:hover {
--b:0.1!important;
transition:--b .5s cubic-bezier(.5,calc(var(--v)/(-.289*.1)),.5,calc(var(--v)/(.289*.1)));
}
.a1 {
animation:b1 2s infinite alternate;
}
@keyframes b1{
20% { --b:25 }
50%,90% {--b:50}
60% {--b:40}
}
.a2 {
animation:b2 2s infinite linear;
}
@keyframes b2{
0% { --b:0 }
100% {--b:1}
}
.bo:hover {
--bo:var(--v);
}
body {
background:pink;
}
registerPaint('blob', class {
static get inputProperties() {
return [
'--n',
'--na',
'--v',
'--b',
'--bo',
'--t',
'--seed'
]
}
paint(ctx, size, properties) {
var point = [];
const cx = size.width/2;
const cy = size.height/2;
const N = parseInt(properties.get('--n'));
const Na = parseInt(properties.get('--na'));
const T = parseInt(properties.get('--t'));
const B = parseFloat(properties.get('--b'));
const Bo = parseFloat(properties.get('--bo'));
const V = parseFloat(properties.get('--v'));
var RADIUS;
switch (Na) {
case 0:
case 1:
case 2:
if(V < 0)
RADIUS = size.width/2 + V;
else
RADIUS = size.width/2;
break;
case 3:
case 4:
RADIUS = size.width/2 - Math.abs(V);
break;
case 5:
case 6:
var r = (size.width)*Math.sin(Math.PI/(N*2));
RADIUS = size.width/2 - r;
break;
default:
RADIUS = size.width/2
}
const mask = 0xffffffff;
const seed = parseInt(properties.get('--seed'));
let m_w = (123456789 + seed) & mask;
let m_z = (987654321 - seed) & mask;
let random = function() {
m_z = (36969 * (m_z & 65535) + (m_z >>> 16)) & mask;
m_w = (18000 * (m_w & 65535) + (m_w >>> 16)) & mask;
var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
result /= 4294967296;
return result;
}
for(var i = 0; i < N; i++) {
var x,y;
switch (Na) {
case 0: /* default movement*/
var r = RADIUS - B*(i%2);
if(T == 1)
r = RADIUS - B*random();
x = Math.cos((i / N) * (2 * Math.PI)) * r + cx;
y = Math.sin((i / N) * (2 * Math.PI)) * r + cy;
break;
case 1: /* x-axis to the center */
var r = RADIUS - B*(i%2);
if(T == 1)
r = RADIUS - B*random();
x = Math.cos((i / N) * (2 * Math.PI)) * r + cx;
y = Math.sin((i / N) * (2 * Math.PI)) * RADIUS + cy;
break;
case 2: /* y-axis to the center */
var r = RADIUS - B*(i%2);
if(T == 1)
r = RADIUS - B*random();
x = Math.cos((i / N) * (2 * Math.PI)) * RADIUS + cx;
y = Math.sin((i / N) * (2 * Math.PI)) * r + cy;
break;
case 3: /* x-axis same direction */
var sign = 1;
if(i<0.75*N && i>0.25*N)
sign = -1;
var r = RADIUS - B*sign*(i%2);
if(T == 1)
r = RADIUS - B*sign*random();
x = Math.cos((i / N) * (2 * Math.PI)) * r + cx;
y = Math.sin((i / N) * (2 * Math.PI)) * RADIUS + cy;
break;
case 4: /* y-axis same direction */
var sign = 1;
if(i<0.5*N && i>0*N)
sign = -1;
var r = RADIUS - B*sign*(i%2);
if(T == 1)
r = RADIUS - B*sign*random();
x = Math.cos((i / N) * (2 * Math.PI)) * RADIUS + cx;
y = Math.sin((i / N) * (2 * Math.PI)) * r + cy;
break;
case 5: /* circular movement */
var r = (size.width)*Math.sin(Math.PI/(N*2));
var rr = r*random();
var xx = rr*Math.cos(B * (2 * Math.PI));
var yy = rr*Math.sin(B * (2 * Math.PI));
x = Math.cos((i / N) * (2 * Math.PI)) * RADIUS + xx + cx;
y = Math.sin((i / N) * (2 * Math.PI)) * RADIUS + yy + cy;
break;
case 6: /* spiral movement */
var r = (size.width)*Math.sin(Math.PI/(N*2));
var rr = r*random();
var xx = rr*Math.cos(B * (2 * Math.PI));
var yy = rr*Math.sin(B * (2 * Math.PI));
var ro = RADIUS - Bo*random();
x = Math.cos((i / N) * (2 * Math.PI)) * ro + xx + cx;
y = Math.sin((i / N) * (2 * Math.PI)) * ro + yy + cy;
break;
default: /* draw a circle by default */
var x = Math.cos((i / N) * (2 * Math.PI)) * RADIUS + cx;
var y = Math.sin((i / N) * (2 * Math.PI)) * RADIUS + cy;
}
point[i] = [x,y];
}
ctx.beginPath();
var xc1 = (point[0][0] + point[N - 1][0]) / 2;
var yc1 = (point[0][1] + point[N - 1][1]) / 2;
ctx.moveTo(xc1, yc1);
for(var i = 0; i < N - 1; i++) {
var xc = (point[i][0] + point[i + 1][0]) / 2;
var yc = (point[i][1] + point[i + 1][1]) / 2;
ctx.quadraticCurveTo(point[i][0], point[i][1], xc, yc)
}
ctx.quadraticCurveTo(point[N - 1][0], point[N - 1][1], xc1, yc1);
ctx.fillStyle = '#000';
ctx.closePath();
ctx.fill();
}
})
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.