Toggle navigation
在线编辑器
在线代码
文本比较
jQuery下载
前端库
在线手册
登录/注册
下载代码
html
css
js
分享到微信朋友圈
X
html
Run
Fast
Slow
css
body { font-family: Arial; padding: 0; margin: 0; overflow: hidden; } canvas { background: linear-gradient( to bottom, rgb(6,9,43) 0%, rgb(30,45,75) 100% ); } canvas, menu { position: absolute; top: 0; color: white; } input, button { color: gray; font-size: 30px; background: transparent; border: 3px solid gray; padding: 5px; margin-top: 5px; transition: all 500ms; } button.active { color: aqua; border-color: aqua; box-shadow: 0 0 4px aqua; text-shadow: 0 0 14px aqua; transition: all 500ms; } label { display: inline-block; color: gray; padding: 10px; }
JavaScript
const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d'); const layers = 4; let size = 0; let particles = []; let targets = []; const lerp = (t, v0, v1) => (1 - t) * v0 + t * v1; const fov = 2000; const viewDistance = 200; let targetRotationY = 0.5; let rotationY = 0.5; let speed = 40; let animFrame; const texts = [ 'hello.', '(?°□°)?? ┻━┻', 'CodePen <3', '{ JavaScript }', 'We are the robots', 'C:\\>', 'Get creative!', 'I live in a giant bucket', 'sudo rm -rf /*', 'Eat your vegetables']; let textIndex = 0; canvas.width = window.innerWidth; canvas.height = window.innerHeight; class Vector3 { constructor(x, y, z) { this.x = x; this.y = y; this.z = z; } static fromScreenCoords(_x, _y, _z) { const factor = fov / viewDistance; const x = (_x - canvas.width / 2) / factor; const y = (_y - canvas.height / 2) / factor; const z = _z !== undefined ? _z : 0; return new Vector3(x, y, z); } rotateX(angle) { const z = this.z * Math.cos(angle) - this.x * Math.sin(angle); const x = this.z * Math.sin(angle) + this.x * Math.cos(angle); return new Vector3(x, this.y, z); } rotateY(angle) { const y = this.y * Math.cos(angle) - this.z * Math.sin(angle); const z = this.y * Math.sin(angle) + this.z * Math.cos(angle); return new Vector3(this.x, y, z); } pp() { const factor = fov / (viewDistance + this.z); const x = this.x * factor + canvas.width / 2; const y = this.y * factor + canvas.height / 2; return new Vector3(x, y, this.z); }} function init(e) { if (e) e.preventDefault(); cancelAnimationFrame(animFrame); const text = document.getElementById('textInput').value || texts[textIndex++ % texts.length]; let fontSize = 150; let startX = window.innerWidth / 2; let startY = window.innerHeight / 2; particles = []; targets = []; // Create temp canvas for the text, draw it and get the image data. const c = document.createElement('canvas'); const cx = c.getContext('2d'); cx.font = `900 ${fontSize}px Arial`; let w = cx.measureText(text).width; const h = fontSize * 1.5; let gap = 7; // Adjust font and particle size to fit text on screen while (w > window.innerWidth * .8) { fontSize -= 1; cx.font = `900 ${fontSize}px Arial`; w = cx.measureText(text).width; } if (fontSize < 100) gap = 6; if (fontSize < 70) gap = 4; if (fontSize < 40) gap = 2; size = Math.max(gap / 2, 1); c.width = w; c.height = h; startX = Math.floor(startX - w / 2); startY = Math.floor(startY - h / 2); cx.fillStyle = '#000'; // For reasons unknown to me, font needs to be set here again, otherwise font size will be wrong. cx.font = `900 ${fontSize}px Arial`; cx.fillText(text, 0, fontSize); const data = cx.getImageData(0, 0, w, h); // Iterate the image data and determine target coordinates for the flying particles for (let i = 0; i < data.data.length; i += 4) { const rw = data.width * 4; const rh = data.height * 4; const x = startX + Math.floor(i % rw / 4); const y = startY + Math.floor(i / rw); if (data.data[i + 3] > 0 && x % gap === 0 && y % gap === 0) { for (let j = 0; j < layers; j++) { targets.push(Vector3.fromScreenCoords(x, y, j * 1)); } } } targets = targets.sort((a, b) => a.x - b.x); loop(); return false; } function loop() { ctx.clearRect(0, 0, canvas.width, canvas.height); // As long as there are targets, keep creating new particles. // Remove target from the targets array when it's been assigned to a particle. for (let i = 0; i < speed; i++) { if (targets.length > 0) { target = targets[0]; x = canvas.width / 2 + target.x * 10; y = canvas.height / 2; z = -10; const position = Vector3.fromScreenCoords(x, y, z); const interpolant = 0; particles.push({ position, target, interpolant }); targets.splice(0, 1); } } particles. sort((pa, pb) => pb.target.z - pa.target.z). forEach((p, i) => { if (p.interpolant < 1) { p.interpolant = Math.min(p.interpolant + .01, 1); p.position.x = lerp(p.interpolant, p.position.x, p.target.x); p.position.y = lerp(p.interpolant, p.position.y, p.target.y); p.position.z = lerp(p.interpolant, p.position.z, p.target.z); } const rotationX = Math.sin(Date.now() / 2000) * .8; rotationY = lerp(0.00001, rotationY, targetRotationY); const particle = p.position. rotateX(rotationX). rotateY(rotationY). pp(); const s = 1 - p.position.z / layers; ctx.fillStyle = p.target.z === 0 ? 'rgb(114, 204, 255)' : `rgba(242, 101, 49, ${s})`; ctx.fillRect(particle.x, particle.y, s * size, s * size); }); animFrame = requestAnimationFrame(loop); } init(); window.addEventListener('mousemove', e => { const halfHeight = window.innerHeight / 2; targetRotationY = (e.clientY - halfHeight) / window.innerHeight; }); function setSpeed(e, val) { document.querySelectorAll('button').forEach(el => { el.classList.remove('active'); }); e.target.classList.add('active'); speed = val; }
粒子
时间
文字
hover
canvas
3d
游戏
音乐
火焰
水波
轮播图
鼠标跟随
动画
css
加载动画
导航
菜单
按钮
滑块
tab
弹出层
统计图
svg
×
Close
在线代码下载提示
开通在线代码永久免费下载,需支付20jQ币
开通后,在线代码模块中所有代码可终身免费下!
您已开通在线代码永久免费下载,关闭提示框后,点下载代码可直接下载!
您已经开通过在线代码永久免费下载
对不起,您的jQ币不足!可通过发布资源 或
直接充值获取jQ币
取消
开通下载
<!doctype html> <html> <head> <meta charset="utf-8"> <title>伪3D文本-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号