canvas泰森多边形动画效果

代码语言:html

所属分类:背景

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">

<style>
html,
body {
	width: 100%;
	height: 100%;
	overflow: hidden;
}

body {
	margin: 0;
	padding: 0;
	color: #fff;
	background-color: #000;
}

canvas {
	-webkit-tap-highlight-color: transparent;
	tap-highlight-color: transparent;
	-webkit-user-select: none;
	user-select: none;
	cursor: pointer;
}
</style>

</head>
<body translate="no">
<canvas></canvas>

<script >
// Voronoi by @neave

window.requestAnimationFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
  setTimeout(callback, 1000 / 60);
};

Array.prototype.each = function (f) {
  var i = this.length;
  while (i--) {
    f(this[i]);
  }
};

function Edge() {
  this.data = undefined;
  this.next = undefined;
  this.rot = undefined;
}

Edge.prototype.splice = function (e) {
  var e1 = this.next.rot,
  e2 = e.next.rot,
  e3 = this.next;

  this.next = e.next;
  e.next = e3;

  e3 = e1.next;
  e1.next = e2.next;
  e2.next = e3;
};

Edge.prototype.swap = function () {
  var e0 = this.oPrev(),
  e1 = this.sym().oPrev();

  this.splice(e0);
  this.sym().splice(e1);
  this.splice(e0.lNext());
  this.sym().splice(e1.lNext());
  this.setOrg(e0.dest());
  this.setDest(e1.dest());
};

Edge.prototype.sym = function () {
  return this.rot.rot;
};

Edge.prototype.iRot = function () {
  return this.rot.rot.rot;
};

Edge.prototype.org = function (v) {
  return this.data;
};

Edge.prototype.setOrg = function (v) {
  this.data = v;
};

Edge.prototype.dest = function () {
  return this.rot.rot.data;
};

Edge.prototype.setDest = function (v) {
  this.rot.rot.data = v;
};

Edge.prototype.setOrgDest = function (o, d) {
  this.setOrg(o);
  this.setDest(d);
};

Edge.prototype.left = function () {
  return this.rot.rot.rot.data;
};

Edge.prototype.setLeft = function (v) {
  this.rot.rot.rot.data = v;
};

Edge.prototype.right = function () {
  return this.rot.data;
};

Edge.prototype.setRight = function (v) {
  this.rot.data = v;
};

Edge.prototype.oNext = function () {
  return this.next;
};

Edge.prototype.rNext = function () {
  return this.rot.next.rot.rot.rot;
};

Edge.prototype.dNext = function () {
  return this.rot.rot.next.rot.rot;
};

Edge.prototype.lNext = function () {
  return this.rot.rot.rot.next.rot;
};

Edge.prototype.oPrev = function () {
  return this.rot.next.rot;
};

Edge.prototype.rPrev = function () {
  return this.rot.rot.next;
};

Edge.prototype.dPrev = function () {
  return this.rot.rot.rot.next.rot.rot.rot;
};

Edge.prototype.lPrev = function () {
  return this.next.rot.rot;
};

Edge.prototype.leftVertex = function (v) {
  return isLeftOf(v, this.org(), this.dest());
};

Edge.prototype.rightVertex = function (v) {
  return isRightOf(v, this.org(), this.dest());
};

Edge.prototype.colinearVertex = function (v) {
  return colinear(v, this.org(), this.dest());
};


function Vertex(x, y) {
  this.x = x;
  this.y = y;
  this.vx = 0;
  this.vy = 0;
  this.cell = 0;
  this.isInfinity = false;
}

Vertex.prototype.equals = function (v) {
  return this.x === v.x && this.y === v.y;
};


var get = document.querySelector.bind(document),
on = document.addEventListener.bind(document),
canvas,
context,
scale,
boundary = 25,
totalVertices = 80,
maxSpeed = 3,
vertices = [],
r,
g,
b,
ri,
gi,
bi,
rotMap = [1, 2, 3, 0],
nextMap = [0, 3, 2, 1],
edge,
edges = [],
circumcenters = [],
edgeVertices = [new Vertex(0, -5000), new Vertex(-10000, 5000), new Vertex(10000, 5000)],
maxIterations = 200,
followDist = 300,
stirDist = 100,
mouseX,
mouseY,
oldMouseX = 0,
oldMouseY = 0;

function inCircle(v0, v1, v2, v3) {
  var test = (v2.x - v1.x) * (v3.y - v1.y) * (v0.x * v0.x + v0.y * v0.y - v1.x * v1.x - v1.y * v1.y) +
  (v3.x - v1.x) * (v0.y - v1.y) * (v2.x * v2.x + v2.y * v2.y - v1.x * v1.x - v1.y * v1.y) +
  (v0.x - v1.x) * (v2.y - v1.y) * (v3.x * v3.x + v3.y * v3.y - v1.x * v1.x - v1.y * v1.y) -
  (v2.x - v1.x) * (v0.y - v1.y) * (v3.x * v3.x + v3.y * v3.y - v1.x * v1.x - v1.y * v1.y) -
  (v3.x - v1.x) * (v2.y - v1.y) * (v0.x * v0.x + v0.y * v0.y - v1.x * v1.x - v1.y * v1.y) -
  (v0.x - v1.x) * (v3.y - v1.y) * (v2.x * v2.x + v2.y * v2.y - v1.x * v1.x - v1.y * v1.y);

  return test >= 0;
}

function area(v0, v1, v2) {
  return (v1.x - v0.x) * (v2.y - v0.y) - (v2.x - v0.x) * (v1.y - v0.y);
}

function distSq(v0, v1) {
  return (v1.x - v0.x) * (v1.x - v0.x) + (v1.y - v0.y) * (v1.y - v0.y);
}

function colinear(v0, v1, v2) {
  return area(v1, v0, v2) === 0;
}

function isRightOf(v0, v1, v2) {
  return area(v0, v1, v2) > 0;
}

function isLeftOf(v0, v1, v2) {
  return area(v0, v1, v2) < 0;
}

function getQuadEdge() {
  var e = [new Edge(), new Edge(), new Edge(), new Edge()],
  i;

  for (i = 0; i < 4; i++) {
    e[i].rot = e[rotMap[i]];
    e[i].next = e[nextMap[i]];
  }

  return e[0];
}

function deleteQuadEdge(e) {
  disconnect(e);
  [e, e.rot, e.sym(), e.iRot()].each(function (q) {
    delete q;
  });
}

function initDelaunay() {
  edges.each(function (e) {
    deleteQuadEdge(e);
  });
  edges = [];
  circumcenters = [];

  edgeVertices.each(function (v) {
    v.isInfinity = true;
  });

  edges[0] = getQuadEdge();
  edges[2] = getQuadEdge();
  edges[0].setOrgDest(edgeVertices[1], edgeVertices[2]);
  edges[2].setOrgDest(edgeVertices[1], edgeVertices[0]);
  edges[0].splice(edges[2]);
  edges[2] = edges[2].sym();
  edges[1] = connect(edges[0], edges[2]);
  edge = edges[0];
}

function inCosmic(v) {
  var cosmic = true;
  [edges[0], edges[1], edges[2]].each(function (e) {
    cosmic &= e.leftVertex(v);
  });
  return cosmic;
}

function locate(v) {
  if (edge.rightVertex(v)) {
    edge = edge.sym();
  }

  var i = 0;
  while (i++ < maxIterations && !v.equals(edge.org()) && !v.equals(edge.dest())) {
    if (!edge.oNext().rightVertex(v)) {
      edge = edge.oNext();
    } else if (!edge.dPrev().rightVertex(v)) {
      edge = edge.dPrev();
    } else {
      return edge;
    }
  }
}

function connect(e0, e1) {
  var e2 = getQuadEdge();
  e2.setOrgDest(e0.dest(), e1.org());
  e2.splice(e0.lNext());
  e2.sym().splice(e1);
  return e2;
}

function disconnect(e) {
  e.splice(e.oPrev());
  e.sym().splice(e.sym().oPrev());
}

function circumcenter(v0, v1, v2) {
  var denominator = (v1.y - v2.y) * (v1.x - v0.x) - (v1.y - v0.y) * (v1.x - v2.x),
  num0 = (v0.x + v1.x) * (v1.x - v0.x) / 2 + (v1.y - v0.y) * (v0.y + v1.y) / 2,
  num1 = (v1.x + v2.x) * (v1.x - v2..........完整代码请登录后点击上方下载按钮下载查看

网友评论0