# Canvas 绘制点线相交

随机产生一些直线，当直线相交时产生交点，直线不断移动，交点的位置也随之改变。

```<!doctype html>
<html>
<meta charset="utf-8">
<title>Canvas绘制点线相交</title>
<style>
body {
background-color: #eee;
overflow: hidden;
}
canvas {
background-color: #eee;
display: block;
margin: 0 auto;
}
</style>
<body>
<canvas id="canvas"></canvas>
</body>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var cw = canvas.width = window.innerWidth,
cx = cw / 2;
var ch = canvas.height = window.innerHeight,
cy = ch / 2;

ctx.fillStyle = "#000";
var linesNum = 16;
var linesRy = [];
var requestId = null;

function Line(flag) {
this.flag = flag;
this.a = {};
this.b = {};
if (flag == "v") {
this.a.y = 0;
this.b.y = ch;
this.a.x = randomIntFromInterval(0, ch);
this.b.x = randomIntFromInterval(0, ch);
} else if (flag == "h") {
this.a.x = 0;
this.b.x = cw;
this.a.y = randomIntFromInterval(0, cw);
this.b.y = randomIntFromInterval(0, cw);
}
this.va = randomIntFromInterval(25, 100) / 100;
this.vb = randomIntFromInterval(25, 100) / 100;

this.draw = function() {
ctx.strokeStyle = "#ccc";
ctx.beginPath();
ctx.moveTo(this.a.x, this.a.y);
ctx.lineTo(this.b.x, this.b.y);
ctx.stroke();
}

this.update = function() {
if (this.flag == "v") {
this.a.x += this.va;
this.b.x += this.vb;
} else if (flag == "h") {
this.a.y += this.va;
this.b.y += this.vb;
}

this.edges();
}

this.edges = function() {
if (this.flag == "v") {
if (this.a.x < 0 || this.a.x > cw) {
this.va *= -1;
}
if (this.b.x < 0 || this.b.x > cw) {
this.vb *= -1;
}
} else if (flag == "h") {
if (this.a.y < 0 || this.a.y > ch) {
this.va *= -1;
}
if (this.b.y < 0 || this.b.y > ch) {
this.vb *= -1;
}
}
}

}

for (var i = 0; i < linesNum; i++) {
var flag = i % 2 == 0 ? "h" : "v";
var l = new Line(flag);
linesRy.push(l);
}

function Draw() {
requestId = window.requestAnimationFrame(Draw);
ctx.clearRect(0, 0, cw, ch);

for (var i = 0; i < linesRy.length; i++) {
var l = linesRy[i];
l.draw();
l.update();
}
for (var i = 0; i < linesRy.length; i++) {
var l = linesRy[i];
for (var j = i + 1; j < linesRy.length; j++) {
var l1 = linesRy[j]
Intersect2lines(l, l1);
}
}
}

function Init() {
linesRy.length = 0;
for (var i = 0; i < linesNum; i++) {
var flag = i % 2 == 0 ? "h" : "v";
var l = new Line(flag);
linesRy.push(l);
}

if (requestId) {
window.cancelAnimationFrame(requestId);
requestId = null;
}

cw = canvas.width = window.innerWidth,
cx = cw / 2;
ch = canvas.height = window.innerHeight,
cy = ch / 2;

Draw();
};

setTimeout(function() {
Init();

}, 15);

function Intersect2lines(l1, l2) {
var p1 = l1.a,
p2 = l1.b,
p3 = l2.a,
p4 = l2.b;
var denominator = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);
var ua = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denominator;
var ub = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denominator;
var x = p1.x + ua * (p2.x - p1.x);
var y = p1.y + ua * (p2.y - p1.y);
if (ua > 0 && ub > 0) {
markPoint({
x: x,
y: y
})
}
}

function markPoint(p) {
ctx.beginPath();
ctx.arc(p.x, p.y, 2, 0, 2 * Math.PI);
ctx.fill();
}

function randomIntFromInterval(mn, mx) {
return ~~(Math.random() * (mx - mn + 1) + mn);
}
</script>
</html>```

无论是Canvas 还是别的，前端的学习总是妙趣横生，只要思想在不断进步，技术就会一次次的突破。如果你学习过Canvas ，你会更加了解这段代码的神奇，送给你，远道而来的求学者。

0 条评论

• ### 情人节送给粉丝的礼物

代码不算多，特效也不是很花哨，情人节她更在意的是你口中的甜言蜜语，这个动画是你们交流的开端。 祝愿你们心心念念的人也在念着你们，愿你们web学习一帆风顺，无往...

• ### 寿司快卖：实现游戏主流程--制作寿司和客户显示动画特效

上一节我们搭建了游戏的基本框架。游戏界面被分为若干个板块，其中一个板块显示了各种制作寿司的材料，它的目的是用于玩家根据信息组装各种寿司，本节我们进入游戏的主流程...

• ### 分享HTML5-CANVAS相交线动画代码实例

今天全百科网分享的是HTML5-CANVAS相交线动画代码实例，史基于html、css、js三个方面制作而成，可用于网页背景，效果很是不错。

• ### .glb格式的模型怎么在three.js中展示

3D软件中导出的格式一般有.obj 和.glb ，下面是blender 2.8.2 生成模型并在three.js中展示的流程

• ### 云终端系列（一）—— 实时音视频Web端接入体验（Vue基础音视频通话篇）

这个系列呢，主要给各位观众老爷看看目前有较大趋势的SaaS应用的SDK在各种主流Web终端的使用姿势和异常分析，如果想要纯粹了解开发的或者云原生，云开发的可以去...

• ### threejs 场景切换 优化性能

是实现2个场景的定时切换，由于是用在大屏系统，需要浏览器一直能正常运行，不能运行一段时间卡死

• ### 撩妹技能 get，教你用 canvas 画一场流星雨

玩过 canvas 的同学，你画圆画方画线条这么 6，如果说叫你画下面这个玩意儿，你会不会觉得你用的是假 canvas？canvas 没有画一个带尾巴玩意儿的 ...