Toggle navigation
在线编辑器
在线代码
文本比较
jQuery下载
前端库
在线手册
登录/注册
下载代码
html
css
js
分享到微信朋友圈
X
html
css
body { background: #020203; } .canvas { position: absolute; width: 100vw; height: 100vh; } .codepen-link { position: absolute; bottom: 30px; right: 30px; height: 40px; width: 40px; z-index: 10; border-radius: 50%; box-sizing: border-box; background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/544318/logo.jpg"); background-position: center center; background-size: cover; opacity: 0.5; -webkit-transition: all 0.25s; transition: all 0.25s; } .codepen-link:hover { opacity: 0.8; box-shadow: 0 0 6px #efefef; }
JavaScript
const PI = Math.PI; const TAU = 2 * PI; const cos = n => Math.cos(n); const sin = n => Math.sin(n); const canvas = document.querySelector(".canvas"); const ctx = canvas.getContext("2d"); let worm, mouse; let tick = 0; let opts = { startHue: 270, blur: 0.1, armCount: 32, segmentLength: 20, segmentMin: 6, segmentMax: 18, segmentNum: () => Math.round( Math.random() * (opts.segmentMax - opts.segmentMin) + opts.segmentMin ), rigidity: 0.9, responsiveness: 0.3, animation: "idle", reset: () => worm = new Worm(opts.armCount) }; class Mouse { constructor() { this.hover = false; this.position = new Vector2( 0.5 * window.innerWidth, 0.5 * window.innerHeight ); this.animationTarget = new Vector2( this.position.x, this.position.y ); this.animate = { random: () => { if (tick % 180 === 0) { this.animationTarget.x = Math.random() * canvas.width; this.animationTarget.y = Math.random() * canvas.height; } this.position.lerp(this.animationTarget, 0.35); }, moebius: () => { this.animationTarget.lerp({ x: 0.5 * canvas.width + (0.35 * canvas.width) * cos(tick * 0.0125), y: 0.5 * canvas.height + (0.35 * canvas.height) * sin(tick * 0.025) }, 0.85); this.position.lerp(this.animationTarget, 0.65); }, idle: () => { this.animationTarget = new Vector2( 0.5 * canvas.width, 0.5 * canvas.height ); this.position.lerp(this.animationTarget, 1); } }; } } class Segment { constructor(x, y, len, angle, color, parent) { this.tick = Math.round(Math.random() * 60); this.jointSize = Math.random() * 3; this.parent = parent; this.color = color; this.len = len; this.angle = angle; this.position = new Vector2(x + this.len * cos(this.angle), y + this.len * sin(this.angle)); this.angle = Math.atan2( this.parent.position.y - this.position.y, this.parent.position.x - this.position.x ); this.head = new Vector2( this.position.x + this.len * cos(this.angle), this.position.y + this.len * sin(this.angle) ); } update() { this.tick++; this.angle = Math.atan2( this.parent.position.y - this.position.y, this.parent.position.x - this.position.x ); this.head.x = this.parent.position.x; this.head.y = this.parent.position.y; this.position.lerp( { x: this.head.x - this.len * cos(this.angle), y: this.head.y - this.len * sin(this.angle) }, opts.rigidity ); this.position.x += cos(this.tick * 0.05) * 0.35; this.position.y += sin(this.tick * 0.05) * 0.35; } draw() { ctx.save(); ctx.globalCompositeOperation = "lighter"; ctx.beginPath(); ctx.strokeStyle = this.color; ctx.lineWidth = 1; ctx.moveTo(this.position.x, this.position.y); ctx.lineTo(this.head.x, this.head.y); ctx.stroke(); ctx.closePath(); ctx.beginPath(); ctx.arc(this.head.x, this.head.y, this.jointSize, 0, TAU); ctx.stroke(); ctx.closePath(); ctx.restore(); } } class Arm { constructor(segmentCount, parent, radius, angle) { this.tick = 0; this.parent = parent; this.segmentCount = segmentCount; this.segments = []; this.radius = radius; this.angle = angle; for (let i = 0; i < this.segmentCount; i++) { let x = this.segments[i - 1] ? this.segments[i - 1].position.x : parent.position.x; let y = this.segments[i - 1] ? this.segments[i - 1].position.y : parent.position.y; this.segments.push( new Segment( x, y, opts.segmentLength, this.angle, `hsla(${-8 * i + opts.startHue},50%,50%,${1 / (i + 0.1)})`, this.segments[i - 1] || { position: new Vector2(parent.position.x, parent.position.y) } ) ); } } update() { this.tick++; this.radius = 40 + sin(this.tick * 0.05) * 20 + noise.simplex3(0, 0, this.tick * 0.0075) * 12; for (let i = 0; i < this.segmentCount; i++) { this.segments[0].parent.position.x = this.parent.position.x + (this.radius - i * 50) * cos(this.angle + this.tick * 0.0125); this.segments[0].parent.position.y = this.parent.position.y + (this.radius - i * 50) * sin(this.angle + this.tick * 0.0125); this.segments[i].update(); this.segments[this.segments.length - i - 1].draw(); } } } class Worm { constructor(armCount) { this.tick = 0; this.arms = []; this.armCount = armCount; this.velocity = new Vector2(0, 0); this.position = new Vector2( 0.5 * window.innerWidth, 0.5 * window.innerHeight ); for (var i = 0; i < this.armCount; i++) { this.arms.push( new Arm(opts.segmentNum(), this, 50, i / this.armCount * TAU) ); } } animate() { this.tick++; this.velocity.lerp( { x: cos( noise.simplex3( this.position.x * 0.0015, this.position.y * 0.0015, this.tick * 0.0015 ) * TAU ) * 4, y: sin( noise.simplex3( this.position.x * 0.0015, this.position.y * 0.0015, this.tick * 0.0015 ) * TAU ) * 4 }, 0.0175 ); this.position.add(this.velocity); this.position.lerp(mouse.position, 0.05 * opts.responsiveness); for (let i = 0; i < this.armCount; i++) { this.arms[i].update(); } } } function initGUI() { let gui = new dat.GUI(); gui.add(opts, "animation", ["random", "moebius", "idle"]); gui.add(opts, "rigidity").step(0.1).min(0.1).max(1); gui.add(opts, "responsiveness").step(0.1).min(0.1).max(2); gui.add(opts, "startHue").step(1).min(0).max(360).onFinishChange(() => { worm = new Worm(opts.armCount); }); gui.add(opts, "blur").step(0.1).min(0).max(0.9); gui.add(opts, "armCount").step(1).min(4).max(48).onFinishChange(() => { worm = new Worm(opts.armCount); }); gui.add(opts, "segmentLength").step(1).min(5).max(40).onFinishChange(() => { worm = new Worm(opts.armCount); }); gui.add(opts, "segmentMin").step(1).min(2).max(12).onFinishChange(() => { worm = new Worm(opts.armCount); }); gui.add(opts, "segmentMax").step(1).min(2).max(28).onFinishChange(() => { worm = new Worm(opts.armCount); }); gui.add(opts, "reset"); } function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } function draw() { ctx.fillStyle = `hsla(240,30%,1%,${1 - opts.blur})`; ctx.fillRect(0, 0, canvas.width, canvas.height); if (!mouse.hover) mouse.animate[opts.animation](); worm.animate(); } function loop() { tick++; draw(); window.requestAnimationFrame(loop); } window.onresize = () => resize(); window.onmousemove = e => { mouse.position.x = e.clientX; mouse.position.y = e.clientY; mouse.hover = true; }; window.onmouseout = () => { mouse.hover = false; }; window.onload = () => { mouse = new Mouse(); worm = new Worm(opts.armCount); initGUI(); resize(); draw(); setTimeout(loop, 1000); };
粒子
时间
文字
hover
canvas
3d
游戏
音乐
火焰
水波
轮播图
鼠标跟随
动画
css
加载动画
导航
菜单
按钮
滑块
tab
弹出层
统计图
svg
×
Close
在线代码下载提示
开通在线代码永久免费下载,需支付20jQ币
开通后,在线代码模块中所有代码可终身免费下!
您已开通在线代码永久免费下载,关闭提示框后,点下载代码可直接下载!
您已经开通过在线代码永久免费下载
对不起,您的jQ币不足!可通过发布资源 或
直接充值获取jQ币
取消
开通下载
<!doctype html> <html> <head> <meta charset="utf-8"> <title>来自深海的奇特生物-jq22.com</title> <script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script> <style>
</style> </head> <body>
<script>
</script>
</body> </html>
2012-2021 jQuery插件库版权所有
jquery插件
|
jq22工具库
|
网页技术
|
广告合作
|
在线反馈
|
版权声明
沪ICP备13043785号-1
浙公网安备 33041102000314号