Javascript 有没有办法让这成为一个互动的背景?
基本上,我试图制作一个交互式背景,无论鼠标悬停或移动到哪里,背景中的线条都会沿着鼠标的特定方向流动或跟随。我是否可以通过使用HTML/CSS/JavaScript来实现这一点?这是代码。CSS在顶部,JS在底部 //CSSJavascript 有没有办法让这成为一个互动的背景?,javascript,Javascript,基本上,我试图制作一个交互式背景,无论鼠标悬停或移动到哪里,背景中的线条都会沿着鼠标的特定方向流动或跟随。我是否可以通过使用HTML/CSS/JavaScript来实现这一点?这是代码。CSS在顶部,JS在底部 //CSS canvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } // Init Context let c = document.createElement(
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
// Init Context
let c = document.createElement('canvas').getContext('2d')
let postctx = document.body.appendChild(document.createElement('canvas')).getContext('2d')
let canvas = c.canvas
let vertices = []
// Effect Properties
let vertexCount = 7000
let vertexSize = 2
let oceanWidth = 204
let oceanHeight = -80
let gridSize = 32;
let waveSize = 16;
let perspective = 500;
// Common variables
let depth = (vertexCount / oceanWidth * gridSize)
let frame = 0
let { sin, cos, tan, PI } = Math
// Render loop
let loop = () => {
let rad = sin(frame / 100) * PI / 20
let rad2 = sin(frame / 50) * PI / 10
frame++
if (postctx.canvas.width !== postctx.canvas.offsetWidth || postctx.canvas.height !== postctx.canvas.offsetHeight) {
postctx.canvas.width = canvas.width = postctx.canvas.offsetWidth
postctx.canvas.height = canvas.height = postctx.canvas.offsetHeight
}
c.fillStyle = `hsl(200deg, 100%, 2%)`
c.fillRect(0, 0, canvas.width, canvas.height)
c.save()
c.translate(canvas.width / 2, canvas.height / 2)
c.beginPath()
vertices.forEach((vertex, i) => {
let ni = i + oceanWidth
let x = vertex[0] - frame % (gridSize * 2)
let z = vertex[2] - frame * 2 % gridSize + (i % 2 === 0 ? gridSize / 2 : 0)
let wave = (cos(frame / 45 + x / 50) - sin(frame / 20 + z / 50) + sin(frame / 30 + z*x / 10000))
let y = vertex[1] + wave * waveSize
let a = Math.max(0, 1 - (Math.sqrt(x ** 2 + z ** 2)) / depth)
let tx, ty, tz
y -= oceanHeight
// Transformation variables
tx = x
ty = y
tz = z
// Rotation Y
tx = x * cos(rad) + z * sin(rad)
tz = -x * sin(rad) + z * cos(rad)
x = tx
y = ty
z = tz
// Rotation Z
tx = x * cos(rad) - y * sin(rad)
ty = x * sin(rad) + y * cos(rad)
x = tx;
y = ty;
z = tz;
// Rotation X
ty = y * cos(rad2) - z * sin(rad2)
tz = y * sin(rad2) + z * cos(rad2)
x = tx;
y = ty;
z = tz;
x /= z / perspective
y /= z / perspective
if (a < 0.01) return
if (z < 0) return
c.globalAlpha = a
c.fillStyle = `hsl(${180 + wave * 20}deg, 100%, 50%)`
c.fillRect(x - a * vertexSize / 2, y - a * vertexSize / 2, a * vertexSize, a * vertexSize)
c.globalAlpha = 1
})
c.restore()
// Post-processing
postctx.drawImage(canvas, 0, 0)
postctx.globalCompositeOperation = "screen"
postctx.filter = 'blur(16px)'
postctx.drawImage(canvas, 0, 0)
postctx.filter = 'blur(0)'
postctx.globalCompositeOperation = "source-over"
requestAnimationFrame(loop)
}
// Generating dots
for (let i = 0; i < vertexCount; i++) {
let x = i % oceanWidth
let y = 0
let z = i / oceanWidth >> 0
let offset = oceanWidth / 2
vertices.push([(-offset + x) * gridSize, y * gridSize, z * gridSize])
}
loop()
//JS
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
// Init Context
let c = document.createElement('canvas').getContext('2d')
let postctx = document.body.appendChild(document.createElement('canvas')).getContext('2d')
let canvas = c.canvas
let vertices = []
// Effect Properties
let vertexCount = 7000
let vertexSize = 2
let oceanWidth = 204
let oceanHeight = -80
let gridSize = 32;
let waveSize = 16;
let perspective = 500;
// Common variables
let depth = (vertexCount / oceanWidth * gridSize)
let frame = 0
let { sin, cos, tan, PI } = Math
// Render loop
let loop = () => {
let rad = sin(frame / 100) * PI / 20
let rad2 = sin(frame / 50) * PI / 10
frame++
if (postctx.canvas.width !== postctx.canvas.offsetWidth || postctx.canvas.height !== postctx.canvas.offsetHeight) {
postctx.canvas.width = canvas.width = postctx.canvas.offsetWidth
postctx.canvas.height = canvas.height = postctx.canvas.offsetHeight
}
c.fillStyle = `hsl(200deg, 100%, 2%)`
c.fillRect(0, 0, canvas.width, canvas.height)
c.save()
c.translate(canvas.width / 2, canvas.height / 2)
c.beginPath()
vertices.forEach((vertex, i) => {
let ni = i + oceanWidth
let x = vertex[0] - frame % (gridSize * 2)
let z = vertex[2] - frame * 2 % gridSize + (i % 2 === 0 ? gridSize / 2 : 0)
let wave = (cos(frame / 45 + x / 50) - sin(frame / 20 + z / 50) + sin(frame / 30 + z*x / 10000))
let y = vertex[1] + wave * waveSize
let a = Math.max(0, 1 - (Math.sqrt(x ** 2 + z ** 2)) / depth)
let tx, ty, tz
y -= oceanHeight
// Transformation variables
tx = x
ty = y
tz = z
// Rotation Y
tx = x * cos(rad) + z * sin(rad)
tz = -x * sin(rad) + z * cos(rad)
x = tx
y = ty
z = tz
// Rotation Z
tx = x * cos(rad) - y * sin(rad)
ty = x * sin(rad) + y * cos(rad)
x = tx;
y = ty;
z = tz;
// Rotation X
ty = y * cos(rad2) - z * sin(rad2)
tz = y * sin(rad2) + z * cos(rad2)
x = tx;
y = ty;
z = tz;
x /= z / perspective
y /= z / perspective
if (a < 0.01) return
if (z < 0) return
c.globalAlpha = a
c.fillStyle = `hsl(${180 + wave * 20}deg, 100%, 50%)`
c.fillRect(x - a * vertexSize / 2, y - a * vertexSize / 2, a * vertexSize, a * vertexSize)
c.globalAlpha = 1
})
c.restore()
// Post-processing
postctx.drawImage(canvas, 0, 0)
postctx.globalCompositeOperation = "screen"
postctx.filter = 'blur(16px)'
postctx.drawImage(canvas, 0, 0)
postctx.filter = 'blur(0)'
postctx.globalCompositeOperation = "source-over"
requestAnimationFrame(loop)
}
// Generating dots
for (let i = 0; i < vertexCount; i++) {
let x = i % oceanWidth
let y = 0
let z = i / oceanWidth >> 0
let offset = oceanWidth / 2
vertices.push([(-offset + x) * gridSize, y * gridSize, z * gridSize])
}
loop()
//初始化上下文
设c=document.createElement('canvas').getContext('2d'))
让postcx=document.body.appendChild(document.createElement('canvas')).getContext('2d'))
让canvas=c.canvas
设顶点=[]
//效应特性
让vertexCount=7000
设vertexSize=2
让oceanWidth=204
假设海洋高度=-80
设gridSize=32;
设波长=16;
让透视图=500;
//公共变量
let depth=(顶点计数/海洋宽度*网格大小)
设帧=0
设{sin,cos,tan,PI}=Math
//渲染循环
让循环=()=>{
设rad=sin(帧/100)*PI/20
设rad2=sin(帧/50)*PI/10
框架++
如果(postcx.canvas.width!==postcx.canvas.offsetWidth | | postcx.canvas.height!==postcx.canvas.offsetHeight){
postcx.canvas.width=canvas.width=postcx.canvas.offsetWidth
postcx.canvas.height=canvas.height=postcx.canvas.offsetHeight
}
c、 填充样式=`hsl(200度,100%,2%)`
c、 fillRect(0,0,canvas.width,canvas.height)
c、 保存()
c、 平移(canvas.width/2、canvas.height/2)
c、 beginPath()
顶点。forEach((顶点,i)=>{
设ni=i+i
设x=顶点[0]-帧%(网格大小*2)
设z=顶点[2]-帧*2%gridSize+(i%2===0?gridSize/2:0)
让波=(cos(帧/45+x/50)-sin(帧/20+z/50)+sin(帧/30+z*x/10000))
设y=顶点[1]+波*波大小
设a=Math.max(0,1-(Math.sqrt(x**2+z**2))/depth)
让tx,ty,tz
y-=海平面高度
//变换变量
tx=x
ty=y
tz=z
//旋转Y
tx=x*cos(rad)+z*sin(rad)
tz=-x*sin(rad)+z*cos(rad)
x=tx
y=ty
z=tz
//旋转Z
tx=x*cos(rad)-y*sin(rad)
ty=x*sin(rad)+y*cos(rad)
x=tx;
y=ty;
z=tz;
//旋转X
ty=y*cos(rad2)-z*sin(rad2)
tz=y*sin(rad2)+z*cos(rad2)
x=tx;
y=ty;
z=tz;
x/=z/透视图
y/=z/透视图
如果(a<0.01)返回
如果(z<0)返回
c、 globalAlpha=a
c、 fillStyle=`hsl(${180+波浪*20}度,100%,50%)`
c、 fillRect(x-a*vertexSize/2,y-a*vertexSize/2,a*vertexSize,a*vertexSize)
c、 globalAlpha=1
})
c、 还原()
//后处理
PostTx.drawImage(画布,0,0)
postcx.globalCompositeOperation=“屏幕”
PostCx.filter='模糊(16px)'
PostTx.drawImage(画布,0,0)
PostCx.filter='模糊(0)'
postcx.globalCompositeOperation=“源代码结束”
requestAnimationFrame(循环)
}
//生成点
for(设i=0;i>0
让偏移量=宽度/2
顶点.推送([(-offset+x)*gridSize,y*gridSize,z*gridSize])
}
循环()
你能用这个例子做一个JSFIDLE吗?这对你的代码有帮助吗?是的。这就是我正在使用的代码。你能用这个例子做一个JSFIDLE吗?这对你的代码有帮助吗?是的。这就是我正在使用的代码