js实现光圈效果
实现光圈效果的方法
光圈效果可以通过多种方式实现,以下是几种常见的实现方法:
使用CSS和JavaScript结合
通过CSS定义光圈样式,JavaScript控制动画效果。以下是一个简单的实现:
<div class="aperture"></div>
.aperture {
width: 100px;
height: 100px;
border-radius: 50%;
background: radial-gradient(circle, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 70%);
box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.5);
position: absolute;
transform: scale(1);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.5); opacity: 0.5; }
100% { transform: scale(1); opacity: 1; }
}
const aperture = document.querySelector('.aperture');
document.addEventListener('mousemove', (e) => {
aperture.style.left = `${e.clientX - 50}px`;
aperture.style.top = `${e.clientY - 50}px`;
});
使用Canvas绘制光圈
Canvas提供了更灵活的控制方式,可以创建更复杂的光圈效果:
<canvas id="apertureCanvas"></canvas>
const canvas = document.getElementById('apertureCanvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
function drawAperture(x, y, radius) {
const gradient = ctx.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.8)');
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fillStyle = gradient;
ctx.fill();
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
const time = Date.now() * 0.001;
const radius = 50 + Math.sin(time * 2) * 20;
drawAperture(canvas.width / 2, canvas.height / 2, radius);
requestAnimationFrame(animate);
}
animate();
使用WebGL实现高级光圈效果
对于更复杂的光圈效果,可以使用WebGL:
<canvas id="webglCanvas"></canvas>
const canvas = document.getElementById('webglCanvas');
const gl = canvas.getContext('webgl');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 顶点着色器
const vsSource = `
attribute vec2 position;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
}
`;
// 片段着色器
const fsSource = `
precision highp float;
uniform vec2 resolution;
uniform float time;
void main() {
vec2 uv = (gl_FragCoord.xy - 0.5 * resolution.xy) / resolution.y;
float dist = length(uv);
float glow = 0.05 / dist;
float pulse = 0.5 + 0.5 * sin(time);
glow *= pulse;
gl_FragColor = vec4(vec3(glow), 1.0);
}
`;
// 初始化WebGL程序
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vsSource);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fsSource);
gl.compileShader(fragmentShader);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
// 设置顶点数据
const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
const position = gl.getAttribLocation(program, 'position');
gl.enableVertexAttribArray(position);
gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);
// 设置统一变量
const resolution = gl.getUniformLocation(program, 'resolution');
gl.uniform2f(resolution, canvas.width, canvas.height);
function animate() {
const time = gl.getUniformLocation(program, 'time');
gl.uniform1f(time, performance.now() * 0.001);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(animate);
}
animate();
实现光圈效果的关键点
-
视觉效果:光圈通常表现为从中心向外扩散的光晕效果,可以通过径向渐变或距离衰减函数实现。
-
动画控制:使用JavaScript控制光圈的大小、透明度和位置变化,创建脉动或跟随效果。
-
性能优化:对于复杂场景,使用Canvas或WebGL比DOM操作更高效,特别是需要大量光圈实例时。
-
交互性:将光圈与用户交互结合,如跟随鼠标移动或响应点击事件,增强用户体验。
-
参数调整:通过调整颜色、大小、透明度和动画速度等参数,可以创建不同风格的光圈效果。
不同应用场景的实现建议
-
简单的UI元素:CSS结合少量JavaScript即可满足需求,实现成本低且兼容性好。
-
游戏或复杂视觉效果:Canvas或WebGL提供更好的性能和更丰富的效果控制。
-
响应式设计:确保光圈效果在不同屏幕尺寸下表现一致,可能需要动态调整参数。
-
移动端优化:注意性能影响,可能需要简化效果或使用硬件加速。
以上方法可以根据具体需求进行组合和调整,实现各种风格的光圈效果。







