我正在研究如何创建一个具有动态/移动背景的 div,基于具有三种颜色的径向渐变:
我们的想法是有一个像这样的中心点:
拖动动画并以或多或少随机的方式混合颜色。
我尝试搜索如何使用 CSS 实现此目的,但我能找到的只是简单的静态径向示例。解决这个问题的最佳方法是什么?
第一步是弄清楚如何制作其中一个。然后你可以旋转它或其他什么。我发现它看起来像一个色轮。我改编了代码https://stackoverflow.com/a/39399649/3807365
var mx = 0
var my = 0
var diameter = 200
var wheel
var can
var ctx
main()
function newEl(tag) {
return document.createElement(tag)
}
function main() {
wheel = makeWheel(diameter);
wheel.addEventListener('mousemove', moveCenter);
document.body.appendChild(wheel);
}
function hsv2rgb(hsv) {
var h = hsv.hue,
s = hsv.sat,
v = hsv.val;
var rgb, i, data = [];
if (s === 0) {
rgb = [v, v, v];
} else {
h = h / 60;
i = Math.floor(h);
data = [v * (1 - s), v * (1 - s * (h - i)), v * (1 - s * (1 - (h - i)))];
switch (i) {
case 0:
rgb = [v, data[2], data[0]];
break;
case 1:
rgb = [data[1], v, data[0]];
break;
case 2:
rgb = [data[0], v, data[2]];
break;
case 3:
rgb = [data[0], data[1], v];
break;
case 4:
rgb = [data[2], data[0], v];
break;
default:
rgb = [v, data[0], data[1]];
break;
}
}
return rgb;
};
function clamp(min, max, val) {
if (val < min) return min;
if (val > max) return max;
return val;
}
function drawWheel(ctx) {
ctx.clearRect(0, 0, can.width, can.height);
var imgData = ctx.getImageData(0, 0, diameter, diameter);
var maxRange = diameter / 2;
for (var y = 0; y < diameter; y++) {
for (var x = 0; x < diameter; x++) {
var xPos = x - (diameter / 2) - mx;
var yPos = (diameter - y) - (diameter / 2) - my;
var polar = pos2polar({
x: xPos,
y: yPos
});
var hueOffset = 50 * (polar.len / maxRange);
var hue = polar.ang + hueOffset;
hue = hue % 360;
while (hue < 0) {
hue += 360;
}
var sat = clamp(0, 1, polar.len / (maxRange / 2));
var val = clamp(0, 1, (maxRange - polar.len) / (maxRange / 2));
var rgb = hsv2rgb({
hue: hue,
sat: sat,
val: val
});
var index = 4 * (x + y * diameter);
imgData.data[index + 0] = rgb[0] * 255;
imgData.data[index + 1] = rgb[1] * 255;
imgData.data[index + 2] = rgb[2] * 255;
imgData.data[index + 3] = 255;
}
}
ctx.putImageData(imgData, 0, 0);
}
function makeWheel(diameter) {
can = newEl('canvas');
ctx = can.getContext('2d');
can.width = diameter;
can.height = diameter;
drawWheel(ctx)
return can;
}
function deg2rad(deg) {
return (deg / 360) * (2 * Math.PI);
}
function rad2deg(rad) {
return (rad / (Math.PI * 2)) * 360;
}
function pos2polar(inPos) {
var vecLen = Math.sqrt((inPos.x + mx) * (inPos.x + mx) + (inPos.y + my) * (inPos.y + my));
var something = Math.atan2(inPos.y, inPos.x);
while (something < 0)
something += 2 * Math.PI;
return {
ang: rad2deg(something),
len: vecLen
};
}
function moveCenter(event) {
var color = document.getElementById('color');
mx = -diameter / 2 + event.offsetX;
my = -1 * (-diameter / 2 + event.offsetY);
color.innerText = "" + mx + ", " + my
}
function loop() {
drawWheel(ctx)
requestAnimationFrame(loop)
}
loop()
canvas {
border: solid 1px red;
}
<div id="color" style="width: 200px; height: 50px; float: left;">Move mouse</div>