最初的想法是仿写win7的泡泡屏保效果,但是对于小球的斜碰问题一直没搞明白(如果你会这个,欢迎留言或者做个demo),所以只是简单处理了碰撞后的速度,有时候会看起来很搞笑~~~funny guy

话不多说,先上demo

https://win7killer.github.io/demo_set/html_demo/canvas/can_ps/ball.html

效果如下:

code:

 <!DOCTYPE html>
<html lang="zh"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
} html {
height: 100%;
} body {
width: 100%;
height: 100%;
background: #333;
background: url(./img/6.jpg) no-repeat 0 0;
background-size: cover;
} canvas {
display: block;
}
</style>
</head> <body>
<canvas id="can" width=0 height=0></canvas>
<script>
var ballsNum = 20;
window.onload = function() { var can = document.getElementById('can');
can.width = document.body.offsetWidth;
can.height = document.body.offsetHeight;
var ctx = can.getContext('2d');
var ballR = Math.floor(can.height / 15);
ctx.shadowColor = 'rgba(0,0,0,.3)';
ctx.shadowOffsetX = ballR / 5;
ctx.shadowOffsetY = ballR / 5;
// ctx.shadowBlur = ballR / 10 > 5 ? ballR / 10 : 5;
ctx.shadowBlur = 16; var aObj = randomBall(ballsNum);
var raf = window.requestAnimationFrame(loop); function loop() {
ctx.clearRect(0, 0, can.width, can.height);
for (var i = 0, l = aObj.length; i < l; i++) {
fnChange(aObj[i]);
checkPeng(aObj, i);
}
if (raf) {
raf = window.requestAnimationFrame(loop);
}
} // 改变圆心坐标
function fnChange(obj) {
drawArc(obj);
obj.x += obj.sx * 10 / 4;
obj.y += obj.sy * 5 / 4; if (obj.x >= can.width - ballR) {
obj.x = can.width - ballR;
obj.sx = -1 * obj.sx;
} else if (obj.x <= ballR) {
obj.x = ballR;
obj.sx = -1 * obj.sx;
}
if (obj.y >= can.height - ballR) {
obj.y = can.height - ballR;
obj.sy = -1 * obj.sy;
} else if (obj.y <= ballR) {
obj.y = ballR;
obj.sy = -1 * obj.sy;
}
}
//画圆
function drawArc(obj) {
ctx.save();
ctx.beginPath();
ctx.arc(obj.x % can.width, obj.y % can.height, ballR, 0, 2 * Math.PI);
ctx.closePath(); var grd = ctx.createRadialGradient(obj.x - ballR * 3 / 10, obj.y - ballR * 4 / 10, ballR / 8, obj.x - ballR * 4 / 10, obj.y - ballR * 4 / 10, ballR * 16 / 10);
grd.addColorStop(0, "rgba(255,255,255,1)");
grd.addColorStop(1, obj.scolor);
ctx.fillStyle = grd;
ctx.fill();
ctx.restore();
} function randomBall(num) {
var barr = [];
var ball;
for (var i = 0; i < num || 0; i++) {
ball = {};
ball.x = Math.random() * (can.width - ballR * 2) + ballR;
ball.y = Math.random() * (can.height - ballR * 2) + ballR;
ball.sx = Math.random() * 6 - 6 / 2;
ball.sy = Math.random() * 6 - 6 / 2;
var scr = Math.round(Math.random() * 200 + 50);
var scg;
var scb;
if (scr > 200) {
if (Math.random() > 1) {
scg = Math.round(Math.random() * 150 + 50);
scb = Math.round(Math.random() * 200 + 50);
} else {
scb = Math.round(Math.random() * 150 + 50);
scg = Math.round(Math.random() * 200 + 50);
}
} else {
scg = Math.round(Math.random() * 200 + 50);
scb = Math.round(Math.random() * 200 + 50);
}
ball.scolor = 'rgba(' + [scr, scg, scb, 1].join(',') + ')';
barr.push(ball);
}
return barr;
} //碰撞检测
function checkPeng(arr, i) {
var j, len; for (j = 0, len = arr.length; j < len; j++) {
if (i === j) {
continue;
}
var ca = {
x: arr[i].x - arr[j].x,
y: arr[i].y - arr[j].y
}
var z = Math.sqrt(Math.pow(ca.x, 2) + Math.pow(ca.y, 2));
var cha = z - ballR * 2;
if (cha <= 0) {
if (arr[i].x < arr[j].x) {
arr[i].x += cha;
} else {
arr[i].x += -cha;
}
if (arr[i].y < arr[j].y) {
arr[i].y += cha;
} else {
arr[i].y += -cha;
}
//arr[i].sy = -1*arr[i].sy;
var iTY = arr[i].sy;
arr[i].sy = 1 * arr[j].sy;
arr[j].sy = iTY;
//arr[i].sx = -1*arr[i].sx;
var iTX = arr[i].sx;
arr[i].sx = 1 * arr[j].sx;
arr[j].sx = iTX;
}
}
}
}
</script>
</body> </html>

然后是加强版的透明泡泡

https://win7killer.github.io/demo_set/html_demo/canvas/can_ps/ball_1.html

效果如下:

code:

 <!DOCTYPE html>
<html lang="zh"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
} html {
height: 100%;
} body {
width: 100%;
height: 100%;
background: #333;
background: url(./img/6.jpg) no-repeat 0 0;
background-size: cover;
} canvas {
display: block;
}
</style>
</head> <body>
<canvas id="can" width=0 height=0></canvas>
<script>
var ballsNum = 20;
window.onload = function() { var can = document.getElementById('can');
can.width = document.body.offsetWidth;
can.height = document.body.offsetHeight;
var ctx = can.getContext('2d');
var ballR = Math.floor(can.height / 15);
ctx.shadowColor = 'rgba(0,0,0,.3)';
ctx.shadowOffsetX = ballR / 5;
ctx.shadowOffsetY = ballR / 5;
// ctx.shadowBlur = ballR / 10 > 5 ? ballR / 10 : 5;
ctx.shadowBlur = 16; var aObj = randomBall(ballsNum);
var raf = window.requestAnimationFrame(loop);
function loop() {
ctx.clearRect(0, 0, can.width, can.height);
for (var i = 0, l = aObj.length; i < l; i++) {
fnChange(aObj[i]);
checkPeng(aObj, i);
}
if (raf) {
raf = window.requestAnimationFrame(loop);
}
} // 改变圆心坐标
function fnChange(obj) {
drawArc(obj);
obj.x += obj.sx * 10 / 4;
obj.y += obj.sy * 5 / 4; if (obj.x >= can.width - ballR) {
obj.x = can.width - ballR;
obj.sx = -1 * obj.sx;
} else if (obj.x <= ballR) {
obj.x = ballR;
obj.sx = -1 * obj.sx;
}
if (obj.y >= can.height - ballR) {
obj.y = can.height - ballR;
obj.sy = -1 * obj.sy;
} else if (obj.y <= ballR) {
obj.y = ballR;
obj.sy = -1 * obj.sy;
}
}
//画圆
function drawArc(obj) {
ctx.save();
ctx.beginPath();
ctx.arc(obj.x % can.width, obj.y % can.height, ballR, 0, 2 * Math.PI);
ctx.closePath(); var grd1 = ctx.createRadialGradient(
obj.x,
obj.y,
ballR / 2,
obj.x,
obj.y,
ballR * 13 / 10
);
// grd1.addColorStop(0, "rgba(255,255,255,1)");
grd1.addColorStop(0, "rgba(255,255,255,0)");
grd1.addColorStop(1, obj.scolor);
ctx.fillStyle = grd1;
ctx.fill();
ctx.restore(); var grd = ctx.createRadialGradient(obj.x - ballR * 3 / 10, obj.y - ballR * 4 / 10, ballR / 8, obj.x - ballR * 4 / 10, obj.y - ballR * 4 / 10, ballR * 16 / 10);
grd.addColorStop(0, "rgba(255,255,255,1)");
grd.addColorStop(0.2, "rgba(255,255,255,0)");
grd.addColorStop(1, "rgba(255,255,255,0)");
// grd.addColorStop(1, obj.scolor);
ctx.fillStyle = grd;
ctx.save();
ctx.shadowColor = 'rgba(0,0,0,.0)';
ctx.fill();
ctx.restore();
} function randomBall(num) {
var barr = [];
var ball;
for (var i = 0; i < num || 0; i++) {
ball = {};
ball.x = Math.random() * (can.width - ballR * 2) + ballR;
ball.y = Math.random() * (can.height - ballR * 2) + ballR;
ball.sx = Math.random() * 6 - 6 / 2;
ball.sy = Math.random() * 6 - 6 / 2;
var scr = Math.round(Math.random() * 200 + 50);
var scg;
var scb;
if (scr > 200) {
if (Math.random() > 1) {
scg = Math.round(Math.random() * 150 + 50);
scb = Math.round(Math.random() * 200 + 50);
} else {
scb = Math.round(Math.random() * 150 + 50);
scg = Math.round(Math.random() * 200 + 50);
}
} else {
scg = Math.round(Math.random() * 200 + 50);
scb = Math.round(Math.random() * 200 + 50);
}
ball.scolor = 'rgba(' + [scr, scg, scb, 1].join(',') + ')';
barr.push(ball);
}
return barr;
} //碰撞检测
function checkPeng(arr, i) {
var j, len; for (j = 0, len = arr.length; j < len; j++) {
if (i === j) {
continue;
}
var ca = {
x: arr[i].x - arr[j].x,
y: arr[i].y - arr[j].y
}
var z = Math.sqrt(Math.pow(ca.x, 2) + Math.pow(ca.y, 2));
var cha = z - ballR * 2;
if (cha <= 0) {
if (arr[i].x < arr[j].x) {
arr[i].x += cha;
} else {
arr[i].x += -cha;
}
if (arr[i].y < arr[j].y) {
arr[i].y += cha;
} else {
arr[i].y += -cha;
}
//arr[i].sy = -1*arr[i].sy;
var iTY = arr[i].sy;
arr[i].sy = 1 * arr[j].sy;
arr[j].sy = iTY;
//arr[i].sx = -1*arr[i].sx;
var iTX = arr[i].sx;
arr[i].sx = 1 * arr[j].sx;
arr[j].sx = iTX;
}
}
}
}
</script>
</body> </html>

就这样吧,canvas写了一些有意思的demo,但是没有系统的可以写成博客的东西,之后会慢慢整理一下介绍给大家~

最后,祝大家鸡年大吉吧,升职涨薪。

【鸡年大吉】,不知道写点啥,放个demo(小球碰撞)吧,有兴趣的看看的更多相关文章

  1. 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(五)——实现注册功能

    使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...

  2. 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(四)——对 run.py 的调整

    使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...

  3. 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用

    使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...

  4. 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化

    使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...

  5. 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(三)——使用Flask-Login库实现登录功能

    使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...

  6. 记写 android 微信登录的demo历程

    前言 首先看一条链接: https://github.com/Tencent/WeDemo 腾讯给了一个wedemo,微信第三方登录的例子.里面是php和ios,ios是object写的,php还是原 ...

  7. canvas写的一个小时钟demo

    <!DOCTYPE html> <html> <head> <title>HTML5 Canvas Demo of clock</title> ...

  8. webpack学习(二):先写几个webpack基础demo

    一.先写一个简单demo1 1-1安装好webpack后创建这样一个目录: 1-2:向src各文件和dist/index.html文件写入内容: <!DOCTYPE html> <h ...

  9. js 模仿jquery 写个简单的小demo

    <div id="div" style="background:red;width:100px;height:300px"> 123123123 & ...

随机推荐

  1. (简单) POJ 2240 Arbitrage,SPFA。

    Description Arbitrage is the use of discrepancies in currency exchange rates to transform one unit o ...

  2. Spring--注入类型--setter

    setter注入: package com.bjsxt.service; import com.bjsxt.dao.UserDAO; import com.bjsxt.model.User; publ ...

  3. POJ3169差分约束系统

    题意:有n头牛,编号为1到n,对于关系好的ml头牛,al和bl之间的距离不大于dl,关系差的md头牛,ad和bd之间的距离不大于dd,求第1头牛和第n头牛之间的距离 分析:这是一道差分约束系统的题目, ...

  4. UVA 10518 How Many Calls?

    题意:一个递推式第n项%b是多少. 递推式: 构造矩阵: #include<cstdio> #include<cstring> #include<cmath> #i ...

  5. 浅谈一个网页打开的全过程(涉及DNS、CDN、Nginx负载均衡等)

    1.概要 从用户在浏览器输入域名开始,到web页面加载完毕,这是一个说复杂不复杂,说简单不简单的过程,下文暂且把这个过程称作网页加载过程.下面我将依靠自己的经验,总结一下整个过程.如有错漏,欢迎指正. ...

  6. session cookie用法

    1.session(1)session存储在服务器的(2)session每个人存一份(3)session有默认的过期时间(4)session里面可以存储任意类型的数据安全,对服务造成压力用法:1.当一 ...

  7. Outlook 2013 电子邮件账户设置备份与恢复

    与之前版本不同,Outlook 2013需要备份以下注册表内容:HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Profiles恢复时 ...

  8. PHP 合并数组 追加数组例子

    PHP合并数组我们可以使用array_merge()函数,array_merge()函数返回一个联合的数组.所得到的数组以第一个输入数组参数开始,按后面数组参数出现的顺序依次追加.其形式为: arra ...

  9. 【转】 如何提高自己的acm个人能力

    2011-05-17 21:26 1429人阅读 评论(0) 收藏 举报 算法网络blog八卦游戏读书 转载自 简单de数字 最终编辑 fading_code by   zfy0701 本来以为HNU ...

  10. C语言的位运算的优势

    位运算加速技巧1. 如果乘上一个2的倍数数值,可以改用左移运算(Left Shift) 加速 300% x = x * 2;x = x * 64;//改为:x = x << 1; // 2 ...