Toggle navigation
在线编辑器
在线代码
文本比较
jQuery下载
前端库
在线手册
登录/注册
下载代码
html
css
js
分享到微信朋友圈
X
html
css
body { font-family: 'Roboto', sans-serif; font-size: 14px; overflow: hidden; } .container, canvas { display: block; width: 100%; margin: 0 auto; } .canvas { background: #ccc; border-radius: 4px; display: block; }
JavaScript
'use strict'; (function() { var canvas = document.getElementById('canvas'), ctx = canvas.getContext('2d'), mouseX = 0, mouseY = -100, width = window.innerWidth, height = window.innerHeight, isMouseMove = false; var TAU = 2 * Math.PI; var generates = 0; var attempts = 300; var mainCirlce = { x: width / 2, y: height / 2, rds: 220 }; var maxCirlcesCount = 700; var circles = []; var maxCircleSize = mainCirlce.rds / 7; var colors = [ ['#0F4155', '#F5C03E'], ['#D63826', '#0F4155'], ['#0F4155', '#D63826'], ['#152A3B', '#158ca7'], ['#e4a50a', '#D63826'], ['#D63826', '#e4a50a'], ['#3a7b30', '#F5C03E'], ['#0F4155', '#7ec873'] ]; var mouseCircle = { currX: width / 2, currY: -100, targX: width / 2, targY: -100, rds: maxCircleSize * .85, easingCircle: .15, easingRect: .13, angle: random(360), rectCurrX: width / 2, rectCurrY: -100, }; var activeDistanceRadius = maxCircleSize * 2; var isRectPosOfsset = false; var isRectWidthOfsset = false; var isDrawBubbles = true; var isDrawRects = true; var rndWidthFactor = 1; var rndXOffsetFactor = .5; var rndYOffsetFactor = .5; var sintId; function start() { setup(); } function setup() { canvas.width = width; canvas.height = height; ctx.lineWidth = 1; sintId = setInterval(function () { generateNewWorld(); }, 500); setEventListeners(); draw(); } function generateNewWorld() { if (generates === 3) { clearInterval(sintId); } isRectPosOfsset = false; isRectWidthOfsset = false; isDrawBubbles = true; isDrawRects = true; rndWidthFactor = 1; rndXOffsetFactor = .5; rndYOffsetFactor = .5; mouseCircle.angle = random(360); var clrSetIdx = ~~random(colors.length); ctx.strokeStyle = colors[clrSetIdx][0]; ctx.fillStyle = colors[clrSetIdx][1]; if (generates === 0) { isDrawRects = false; } if (generates === 1) { isRectPosOfsset = true; rndXOffsetFactor = random(-.5, 1); rndYOffsetFactor = random(-.5, 1); } if (generates === 2) { isRectWidthOfsset = true; rndWidthFactor = random(4, 5); } if (generates > 3) { if (Math.random() >= .8) { isRectWidthOfsset = true; rndWidthFactor = random(3, 5); } if (Math.random() >= .7) { isRectPosOfsset = true; rndXOffsetFactor = random(-.5, 1); rndYOffsetFactor = random(-.5, 1); } if (Math.random() >= .85) { isDrawBubbles = false; } if (isDrawBubbles) { if (Math.random() >= .85) { isDrawRects = false; } } } generateCirclesInCircle(); ++generates; } function draw() { background('#fff'); drawFoamBubbles(); drawMouseCircle(); window.requestAnimationFrame(draw); } function drawFoamBubbles() { updateCirclesPos(circles); circles.forEach(function (p) { p.updateAnimationValues(); }); if (isDrawRects) { circles.forEach(function (p) { p.drawRect(); }); } if (isDrawBubbles) { circles.forEach(function (p) { p.drawCircle(); }); } } function drawMouseCircle() { mouseCircle.currX += (mouseX - mouseCircle.currX) * mouseCircle.easingCircle; mouseCircle.currY += (mouseY - mouseCircle.currY) * mouseCircle.easingCircle; mouseCircle.rectCurrX += (mouseX - mouseCircle.rectCurrX) * mouseCircle.easingRect; mouseCircle.rectCurrY += (mouseY - mouseCircle.rectCurrY) * mouseCircle.easingRect; ctx.beginPath(); ctx.arc(mouseCircle.currX, mouseCircle.currY, mouseCircle.rds, 0, Math.PI * 2, false); ctx.arc(mouseCircle.currX, mouseCircle.currY, mouseCircle.rds + .3, 0, Math.PI * 2, false); ctx.stroke(); ctx.save(); ctx.translate(mouseCircle.rectCurrX, mouseCircle.rectCurrY); ctx.rotate(mouseCircle.angle); ctx.fillRect(-mouseCircle.rds * rndXOffsetFactor, -mouseCircle.rds * rndYOffsetFactor, mouseCircle.rds / rndWidthFactor, mouseCircle.rds); ctx.restore(); } function generateCirclesInCircle() { circles = []; var newCircleCenter, tmpDistance, cDist, idx, itr, i; for (idx = 0; idx < maxCirlcesCount; idx++) { for (i = 0; i < attempts; ++i) { newCircleCenter = genNewPosition(mainCirlce); if (isPointInsideCircle(newCircleCenter, mainCirlce) && !isIntersectWithCircles(newCircleCenter, circles)) { break; } } // distance to main circle border; var newCircleSize = (mainCirlce.rds - dist(newCircleCenter.x, newCircleCenter.y, mainCirlce.x, mainCirlce.y)) * 2; newCircleSize = newCircleSize > maxCircleSize ? maxCircleSize : newCircleSize; for (itr = 0; itr < circles.length; itr++) { cDist = dist(circles[itr].x, circles[itr].y, newCircleCenter.x, newCircleCenter.y); tmpDistance = Math.abs(circles[itr].rds - cDist); if (tmpDistance < newCircleSize) { newCircleSize = tmpDistance + 3; } } if (newCircleSize >= 3) { circles.push(new Circle(newCircleCenter.x, newCircleCenter.y, newCircleSize, idx)); } } if (isRectWidthOfsset) { circles.forEach(function (circleItem) { circleItem.rectWidthDivideFactor = rndWidthFactor; }); } if (isRectPosOfsset) { circles.forEach(function (circleItem) { circleItem.rectXOffsetFactor = rndXOffsetFactor; circleItem.rectYOffsetFactor = rndYOffsetFactor; }); } } function updateCirclesPos() { var i, circleItem, theta, distance; for (i = 0; i < circles.length; i++) { circleItem = circles[i]; theta = Math.atan2(circleItem.y - mouseY, circleItem.x - mouseX); distance = activeDistanceRadius / dist(mouseX, mouseY, circleItem.x, circleItem.y); circleItem.x += Math.cos(theta) * distance + (circleItem.origX - circleItem.x) * 0.075; circleItem.y += Math.sin(theta) * distance + (circleItem.origY - circleItem.y) * 0.075; } } // Circle class function Circle (x, y, r, idx) { this.x = x; this.y = y; this.origX = x; this.origY = y; this.rds = r; this.currRds = 0; this.idx = idx; this.durAnimation = random(1.7, 2.7); this.durProgress = 0; this.currAngle = random(1, 7); this.targetAngle = this.currAngle + random(1, 7) * (Math.random() > .5 ? 1 : -1); this.rectWidth = 0; this.rectX = 0; this.rectY = 0; this.rectXOffsetFactor = .5; this.rectYOffsetFactor = .5; this.rectWidthDivideFactor = 1; this.drawCircle = function () { ctx.beginPath(); ctx.arc(this.x, this.y, this.currRds, 0, Math.PI * 2, false); ctx.arc(this.x, this.y, this.currRds + .3, 0, Math.PI * 2, false); ctx.stroke(); }; this.drawRect = function () { ctx.save(); ctx.translate(this.x, this.y); ctx.rotate(this.currAngle); ctx.fillRect(this.rectX, this.rectY, this.rectWidth, this.currRds); ctx.restore(); }; this.updateAnimationValues = function () { if (this.durProgress < this.durAnimation) { if (this.currRds !== this.rds) { this.currRds = easeOutElastic(this.durProgress, this.currRds, this.rds, this.durAnimation); this.rectWidth = this.currRds / this.rectWidthDivideFactor; this.rectX = -this.currRds * this.rectXOffsetFactor; this.rectY = -this.currRds * this.rectYOffsetFactor; } if (this.currAngle !== this.targetAngle) { this.currAngle = easeOutElastic(this.durProgress, this.currAngle, this.targetAngle, this.durAnimation); } this.durProgress += .008; } }; this.drawWithAnimate = function () { this.updateAnimationValues(); this.drawCircle(); }; } function genNewPosition(mainCirlce) { return { x: random(10, width - 20), y: random(10, height - 10) }; // // different way: perfect for creating point inside circle but having some slight differences in result // var angle = random(TAU); // var scalar = random(1, mainCirlce.rds); // return { // x: Math.cos(angle) * scalar + mainCirlce.x, // y: Math.sin(angle) * scalar + mainCirlce.y // }; } function isPointInsideCircle(pos, circle) { return dist (pos.x, pos.y, circle.x, circle.y) < circle.rds; } function isIntersectWithCircles(pos, circles) { if (circles.length > 0) { for (var i = 0; i < circles.length; i++) { if (isPointInsideCircle(pos, circles[i])) { return true; } // return isPointInsideCircle(pos, circles[i]); } } return false; } function setEventListeners() { document.addEventListener('mousedown', mouseDown); document.addEventListener('mouseout', mouseOut ); document.addEventListener('mousemove', mouseMove); document.addEventListener('keypress', keyTyped ); window.addEventListener('resize', function() { width = window.innerWidth; height = window.innerHeight; } ); } function keyTyped(evt) { var eventKey = evt.key.toLowerCase(); switch (eventKey){ case 'g': generateNewWorld(); break; } } function mouseDown(evt) { if (evt.button === 0) { generateNewWorld(); } } function mouseOut (evt) { isMouseMove = false; } function mouseMove(evt) { var mousePos = getMousePos(canvas, evt); mouseX = mousePos.x; mouseY = mousePos.y; isMouseMove = true; } function getMousePos(block, evt) { block = block || document.getElementsByTagName('body')[0]; var rect = block.getBoundingClientRect(); return { x: evt.clientX - rect.left, y: evt.clientY - rect.top }; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Helper Functions ////////////////////////////////////////////////////////////////////////////////////////// function random (min, max){ if (!min && min !== 0) { return Math.random(); } else if (!max) { return Math.random() * min; } return Math.random() * (max - min) + min; } function dist (x1, y1, x2, y2) { var a = x1 - x2; var b = y1 - y2; return Math.sqrt(a * a + b * b); } function background(clr) { ctx.save(); ctx.fillStyle = clr || "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.restore(); } // t: curr time, b: start val, c: change In value, d: duration function easeOutElastic(t, b, c, d) { var s = 1.70158; var a = c; if (t === 0) { return 0; } t /= d; if (t === 1) { return c; } var p = d * 0.3; if (a < Math.abs(c)) { a = c; s = p / 4; } else { s = p / (2 * Math.PI) * Math.asin(c / a); } return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c; } start(); })();
粒子
时间
文字
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号