JSFiddle - React, Tailwind, and code Playground
by Sergei Sokolov
CSS
body{ background-color:#333;
margin:0; padding:0
}
canvas {cursor:pointer}
JavaScript
/**
* для вопроса https://toster.ru/q/456711
* Необычный hover эффект?
*/
"use strict";
// create canvas
var canvas = document.createElement('canvas')
, ctx = canvas.getContext('2d')
, i
, Point = function( x, y) {
this.x = x || 0
, this.y = y || 0
, this.v = 0 // current value
, this.t = 0 // target value
}
, points = []
, radius = 8
, x, y
, follower
, needUpdate = true
;
// mouse follower / smoother
function Follower(x,y) {
this.x = x || 0;
this.y = y || 0;
this.tx = x;
this.ty = y;
}
Follower.prototype.update = function(delta) {
var dx, dy;
delta = delta || 0.05;
dx = delta * (this.tx - this.x);
dy = delta * (this.ty - this.y);
this.x += dx;
this.y += dy;
//return true;
return dx * dx + dy * dy > 1;
}
// for debugging
Follower.prototype.render = function(ctx, isActive) {
ctx.fillStyle = isActive ? "#33F" : "#009";
ctx.fillRect( this.x-2, this.y-2, 4, 4);
ctx.fillStyle = isActive ? "#3F3" : "#090";
ctx.fillRect( this.tx-2, this.ty-2, 4, 4);
}
Follower.prototype.goto = function(tx, ty) {
this.tx = tx;
this.ty = ty;
return this.update();
}
function map( lo, hi, v) {
return lo + Math.floor( v * (hi - lo));
}
Point.prototype.render = function(ctx) {
var delta
, r = map( 240, 255, this.v)
, g = map( 240, 0, this.v)
, b = map( 240, 0, this.v)
, a = map( 10, 255, this.v)
;
ctx.fillStyle = "rgba(" +[r,g,b,a].join(',') + ")";
ctx.beginPath();
ctx.arc( this.x, this.y, radius, 0, Math.PI * 2);
ctx.fill();
delta = 0.06 * (this.t - this.v); // speed of fade
this.v += delta;
return delta * delta > 1e-5;
}
// setup canvas
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);
follower = new Follower( canvas.width/2, canvas.height/2);
// initialize points
for( x = 1.5 * radius; x...