canvas製作小球碰撞效果(帶連線功能)
阿新 • • 發佈:2021-01-31
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
#myCanvas {
width: 100%;
height: 100vh;
display: block;
}
</style>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script>
const canvas = document.getElementById('myCanvas')
canvas.setAttribute('width', document.body.clientWidth)
canvas.setAttribute('height', document.body.clientHeight)
const ctx = canvas.getContext('2d');
let ballArr = []
// 建立一個小球類
class Ball {
constructor(x, y, r, color, maxWidth, maxHeight, minWidth, minHeight) {
this.x = x;
this.y = y;
this.color = color;
this.r = r;
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
this.minWidth = minWidth;
this.minHeight = minHeight;
this.dx = Math.random() * 10 - 5;
this.dy = Math.random() * 10 - 5;
this.index = ballArr.length
ballArr.push(this)
}
render() {
ctx.beginPath()
ctx.fillStyle = this.color
ctx.arc(this.x, this.y, this.r, 0, 2* Math.PI);
ctx.fill()
}
update() {
this.dx = this.x + this.dx <= minWidth || this.x + this.dx >= maxWidth ? -this.dx : this.dx;
this.dy = this.y + this.dy <= minHeight || this.y + this.dy >= maxHeight ? -this.dy : this.dy;
this.x += this.dx;
this.y += this.dy;
ctx.beginPath()
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI)
ctx.fill()
}
drawLine() {
let x = ballArr.findIndex( item => item == this)
ballArr.forEach((item, index) => {
if(Math.abs(item.x - this.x) < 150 && Math.abs(item.y - this.y) < 150 && index > this.index) {
let lineDistance = Math.sqrt(Math.pow(item.x - this.x, 2) + Math.pow(item.x - this.x, 2))
let alpha = parseInt(lineDistance) / 150;
ctx.strokeStyle = `rgba(0, 0, 0, ${alpha})`
console.log(alpha)
ctx.beginPath();
ctx.moveTo(this.x, this.y)
ctx.lineTo(item.x, item.y)
ctx.closePath();
ctx.stroke();
}
})
}
}
const maxWidth = document.body.clientWidth;
const maxHeight = document.body.clientHeight;
const minWidth = 0;
const minHeight = 0;
for(let i = 0; i < 30; i++) {
let x = parseInt(Math.random() * maxWidth);
let y = parseInt(Math.random() * maxHeight);
new Ball(x, y, 10, 'grey', maxWidth, maxHeight, minWidth, minHeight)
}
setInterval(() => {
ctx.clearRect(0, 0, maxWidth, maxHeight)
ballArr.forEach(item => {
item.render();
item.update();
item.drawLine();
});
}, 10)
</script>
</body>
</html>```