最初的想法是仿写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. 结合Pnotify插件--app-jquery-notify.js

    $.NOTIFY = { showSuccess : function (title, text, context) { var opt = { title : title, text : text, ...

  2. [iOS]C语言技术视频-11-指针变量练习一(交换值)

    下载地址: 链接: http://pan.baidu.com/s/1pJIcGm3 密码: s83p

  3. python之路: 基础篇

    )或>>> name = )    #按照占位符的顺序):]        #下标识从0开始的 wulaoer >>> print name[:]        # ...

  4. mybatis+spring事务

    http://www.mybatis.org/spring/zh/transactions.html 第四章 事务 一个使用 MyBatis-Spring 的主要原因是它允许 MyBatis 参与到 ...

  5. JAVA中传递参数乱码问题

    url传递中文如果jsp页面,myeclipse.web.xml中org.springframework.web.filter.CharacterEncodingFilter,都是UTF-8编码,直接 ...

  6. 文本去重-----awk或者uniq

    对于awk '!a[$3]++',需要了解3个知识点 1.awk数组知识,不说了 2.awk的基本命令格式 awk 'pattern{action}'     省略action时,默认action是{ ...

  7. salt自动化部署

    1. 到编译机器编译 /export/Deploy/vm-agent 执行脚本 ./vm-agent.sh develop -alpha 2.检查rpm包是否打包成功 http://172.18.13 ...

  8. 机器学习算法与实现 之 Logistic Regression---java实现

    Logistic Regression和Linear Regression实现起来几乎是一样的,有疑问的同学可以看一看Andrew N.g在coursera上的machine learning课程. ...

  9. 【转】50条大牛C++编程开发学习建议

    每个从事C++开发的朋友相信都能给后来者一些建议,但是真正为此进行大致总结的很少.本文就给出了网上流传的对C++编程开发学习的50条建议,总结的还是相当不错的,编程学习者(不仅限于C++学习者)如果真 ...

  10. [Angular Tutorial] 4 - Directory and File Organization

    在这一步中,我们将不会在我们的应用中添加任何新功能,相反,我们打算退回一步,重构我们的代码库,移动我们的代码和文件,以此来使我们的应用更具易扩展性和可维护性. 在先前的步骤中,我们已经见识到了如何将我 ...