Toggle navigation
在线编辑器
在线代码
文本比较
jQuery下载
前端库
在线手册
登录/注册
下载代码
html
css
js
分享到微信朋友圈
X
html
css
* { margin:0; padding:0; background:#E8E8E8; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; } canvas { width:100vw; height:100vh; }
JavaScript
"use strict"; var l = l || {}; l.water = l.water || {}; l.water.fish = (userInput, renderer, config) => { let fish = {}; fish.init = (position) => { fish.position = position; fish.getTarget(); fish.lastDistance = l.helper.getCartesianDistance(fish.position, fish.target); fish.prevDistance = fish.lastDistance; fish.tail = []; fish.step = 0; }; fish.render = (shadow = true) => { // draw fish using renderer if (shadow) { fish.drawShape(fish.position, config.fish.color); fish.drawTail(fish.tail, fish.position, config.fish.color); //fish.render(false); return; } fish.drawShape(config.shadows.offset(fish.position, userInput.mouse.position), config.shadows.color); fish.drawTail(fish.tail.map((a) => config.shadows.offset(a, userInput.mouse.position)), config.shadows.offset(fish.position, userInput.mouse.position), config.shadows.color); }; fish.drawShape = (position, color) => { let ctx = renderer.ctx; ctx.fillStyle = color; ctx.beginPath(); ctx.arc(position.x, position.y, 5, 0, Math.PI * 2); ctx.fill(); }; fish.drawTail = (points, position, color) => { let ctx = renderer.ctx; ctx.beginPath(); ctx.strokeStyle = color; ctx.lineWidth = 2; ctx.lineJoin = 'round'; points.map((point, index) => { if (index === 0) { ctx.moveTo(point.x, point.y); } else { if (l.helper.getCartesianDistance(point, position) >= 5) { ctx.lineTo(point.x, point.y) } } }); ctx.stroke(); }; fish.updatePosition = (allFish) => { let nearTarget = l.helper.getCartesianDistance(fish.position, fish.target) < 10; let nearLight = l.helper.getCartesianDistance(fish.position, userInput.getMousePosition()) < l.config.fish.stopDistance; if (nearTarget && nearLight) { return; } else if (nearTarget || fish.lastDistance > fish.prevDistance) { fish.getTarget(); } fish.tail.push({x: fish.position.x, y: fish.position.y}); if (fish.tail.length > 50) { fish.tail.shift(); } let step = l.helper.getRadialVector(Math.min(config.fish.maxVeloctity, fish.distanceToTarget), fish.theta); let x = 0; let y = 0; x += Math.min(config.fish.maxVeloctity, step.x); y += Math.min(config.fish.maxVeloctity, step.y); if (l.helper.getCartesianDistance(fish.position, userInput.mouse.position) >= config.fish.stopDistance) { fish.position.x += x; fish.position.y += y; } }; fish.getTarget = () => { let distance = l.helper.getRandom(10, l.config.fish.segmentLength); let m = userInput.getMousePosition(); fish.distanceToTarget = l.helper.getCartesianDistance(fish.position, m); fish.theta = l.helper.getTheta(fish.position, m) + l.helper.getRandom(-(l.config.fish.randomAngleRange / 2), l.config.fish.randomAngleRange / 2) * Math.PI / 180; fish.target = l.helper.getRadialVector(distance, fish.theta); fish.target.x += fish.position.x; fish.target.y += fish.position.y; fish.prevDistance = fish.lastDistance; fish.lastDistance = distance; }; return fish; }; var l = l || {}; /** * @param type {string} * @param position {x, y} * @param userInput {userInput} * @param renderer {renderer} * @param config {config} * @returns {waterParent} */ l.waterParent = (type, position, userInput, renderer, config) => { if (l.water[type] === undefined) { throw new Error('Undefined Constructor: ' + type); } let object = l.water[type](userInput, renderer, config); object.draw = (shadow = true) => { object.render(shadow); }; object.progress = (allFish) => { object.updatePosition(allFish); }; object.init(position); return object; }; var l = l || {}; l.config = { canvas: { id: 'canvas', width: window.innerWidth, height: window.innerHeight }, light: { radius: 500 }, plants: { lily: { color: "#006633" } }, fish: { color: "#FF9933", maxVeloctity: 1, stopDistance: 40, randomAngleRange: 30, flockSpacing: 10, count: 50, segmentLength: 100 }, shadows: { color: "#000", offset: (position, cursorPosition) => { let unit = l.helper.getUnitVectorBetweenTwoPoints(position, cursorPosition); return { x: position.x - 100 * unit.x, y: position.y - 100 * unit.y } } } }; var l = l || {}; l.helper = { getRadialVector: (distance, theta) => { return { x: distance * Math.cos(theta), y: distance * Math.sin(theta) } }, getCartesianDistance: (p1, p2) => { return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)); }, getTheta: (p1, p2) => { return Math.atan2( p2.y - p1.y, p2.x - p1.x ); }, log: function() { for (let i in arguments) { let a = arguments[i]; console.log(JSON.parse(JSON.stringify(a))); } }, getUnitVectorBetweenTwoPoints: (p1, p2) => { let v = {x: p2.x - p1.x, y: p2.y - p1.y}; let mag = Math.sqrt(v.x * v.x + v.y * v.y); return { x: v.x / mag, y: v.y / mag }; }, getRandom: (min, max) => { let diff = max - min; return Math.floor(Math.random() * diff + min); } }; var l = l || {}; l.init = () => { let userInput = l.userInput(l.config); let renderer = l.renderer(userInput, l.config); let fish = []; for (let i = 0; i < l.config.fish.count; i++) { fish.push(l.waterParent('fish', {x: Math.floor(Math.random() * l.config.canvas.width), y: Math.floor(Math.random() * l.config.canvas.height)}, userInput, renderer, l.config)); } let loop = () => { renderer.wipe(); fish.map((f) => { f.progress(fish); f.draw(false); }); fish.map((f) => { f.draw(); }); // this method of restarting the animation isn't perfect, and there's a memory leak tied to this and maybe also to long running animations. if (l.stop === undefined) { requestAnimationFrame(loop); } }; requestAnimationFrame(loop); }; window.onload = () => { l.init(); }; var l = l || {}; l.renderer = (userInput, config) => { let renderer = {}; renderer.canvas = document.getElementById(config.canvas.id); renderer.canvas.width = config.canvas.width; renderer.canvas.height = config.canvas.height; renderer.ctx = renderer.canvas.getContext('2d'); renderer.wipe = () => { renderer.ctx.clearRect(0, 0, renderer.canvas.width, renderer.canvas.height); let ctx = renderer.ctx; //ctx.globalCompositeOperation = 'source-over'; // Paint the canvas black. ctx.fillStyle = '#000'; ctx.clearRect(0, 0, renderer.canvas.width, renderer.canvas.height); ctx.fillRect(0, 0, renderer.canvas.width, renderer.canvas.height); ctx.beginPath(); let radialGradient = ctx.createRadialGradient(userInput.mouse.position.x, userInput.mouse.position.y, 1, userInput.mouse.position.x, userInput.mouse.position.y, config.light.radius); radialGradient.addColorStop(0, 'rgba(255,255,255,1)'); radialGradient.addColorStop(1, 'rgba(0,0,0,0)'); //ctx.globalCompositeOperation = "source-in"; //ctx.globalCompositeOperation = 'source-out'; ctx.fillStyle = radialGradient; ctx.arc(userInput.mouse.position.x, userInput.mouse.position.y, config.light.radius, 0, Math.PI*2, false); ctx.fill(); ctx.closePath(); }; return renderer; }; var l = l || {}; l.userInput = (config) => { let ui = {}; ui.init = () => { let canvas = document.getElementById(config.canvas.id); canvas.addEventListener('mousemove', ui.mouseMoved); canvas.addEventListener('click', ui.mouseClicked); ui.mouse = { position: {x: config.canvas.width / 2, y: config.canvas.height / 2} }; }; ui.mouseMoved = (event) => { ui.mouse.position = {x: event.offsetX, y: event.offsetY}; }; ui.mouseClicked = (event) => { l.stop = true; setTimeout(() => { delete l.stop; l.init(); }, 20); }; ui.getMousePosition = () => { return ui.mouse.position; }; ui.init(); return ui; };
粒子
时间
文字
hover
canvas
3d
游戏
音乐
火焰
水波
轮播图
鼠标跟随
动画
css
加载动画
导航
菜单
按钮
滑块
tab
弹出层
统计图
svg
×
Close
在线代码下载提示
开通在线代码永久免费下载,需支付20jQ币
开通后,在线代码模块中所有代码可终身免费下!
您已开通在线代码永久免费下载,关闭提示框后,点下载代码可直接下载!
您已经开通过在线代码永久免费下载
对不起,您的jQ币不足!可通过发布资源 或
直接充值获取jQ币
取消
开通下载
<!doctype html> <html> <head> <meta charset="utf-8"> <title>canvas粒子超光源位置游动-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号