JavaScript
语言:
JaveScriptBabelCoffeeScript
确定
var canvas;
var context;
var screenWidth;
var screenHeight;
var doublePI = Math.PI * 2;
var lerpValue;
var lineStep;
var pointA;
var pointB;
var controlA;
var controlB;
var mousePos;
var manual = false;
window.onload = function() {
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
window.onresize = function() {
screenWidth = window.innerWidth;
screenHeight = window.innerHeight;
canvas.width = screenWidth;
canvas.height = screenHeight;
pointA.x = screenWidth >> 1;
pointA.y = screenHeight >> 1;
};
lerpValue = 0;
lineStep = 0;
pointA = Point.create(300, 300);
pointB = Point.create(600, 300);
window.onresize();
controlA = Point.create(screenWidth >> 1, screenHeight >> 1);
controlB = Point.create(screenWidth >> 1, screenHeight >> 1);
mousePos = Point.create(0, 0);
canvas.addEventListener('mousemove', function(e) {
if (lineStep > 1) manual = true;
mousePos.x = e.clientX;
mousePos.y = e.clientY;
});
loop();
};
window.getAnimationFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 16.6);
};
function loop() {
render();
updatePoints();
lerpValue += 0.02;
lineStep += 0.03;
getAnimationFrame(loop);
}
function updatePoints() {
//pointA.y += Math.sin(lineStep + Math.PI * 0.5) * 2;
if (manual) {
pointB.x += (mousePos.x - pointB.x) * 0.1;
pointB.y += (mousePos.y - pointB.y) * 0.1;
} else {
pointB.x = Math.cos(lerpValue) * (screenWidth >> 1) + (screenWidth >> 1);
pointB.y = Math.sin(lerpValue) * (screenHeight >> 1) + (screenHeight >> 1);
}
controlA.x = Math.cos(lineStep) * (screenWidth >> 2) + (screenWidth >> 1);
controlA.y = Math.sin(lerpValue) * (screenHeight >> 2) + (screenHeight >> 1);
controlB.x = Math.cos(lerpValue) * (screenWidth >> 2) + (screenWidth >> 1);
controlB.y = Math.sin(lineStep) * (screenHeight >> 2) + (screenHeight >> 1);
//pointB.y += (mousePos.y - pointB.y) * 0.1;
//controlA.y += Math.sin(lineStep + Math.PI * 0.5) * 8;
//controlB.y += Math.sin(lineStep + Math.PI * 1) * 8;
//pointA.x += Math.sin(lineStep - 1) * 6;
//pointB.x += (mousePos.x - pointB.x) * 0.1;
}
function render() {
context.globalAlpha = 1;
context.fillStyle = '#000';
context.fillRect(0, 0, screenWidth, screenHeight);
context.globalAlpha = 1;
renderPoints();
drawBezierCurve(Math.sin(lerpValue) * 0.5 + 0.5, pointA, pointB, controlA, controlB);
//drawBezierCurve(1, pointA, pointB, controlA, controlB);
}
function renderPoints() {
drawPoint(pointA, 4, '#F00');
drawPoint(pointB, 4, '#F00');
drawPoint(controlA, 4, '#F00');
drawPoint(controlB, 4, '#F00');
}
function drawPoint(point, radius, color) {
context.beginPath();
context.fillStyle = color;
context.arc(point.x >> 0, point.y >> 0, radius, 0, doublePI);
context.fill();
context.closePath();
}
function drawBezierCurve(t, p1, p2, c1, c2) {
var r1 = Point.create(lerp(t, p1.x, c1.x), lerp(t, p1.y, c1.y));
var r2 = Point.create(lerp(t, c1.x, c2.x), lerp(t, c1.y, c2.y));
var r3 = Point.create(lerp(t, c2.x, p2.x), lerp(t, c2.y, p2.y));
var r4 = Point.create(lerp(t, r1.x, r2.x), lerp(t, r1.y, r2.y));
var r5 = Point.create(lerp(t, r2.x, r3.x), lerp(t, r2.y, r3.y));
var fp = Point.create(lerp(t, r4.x, r5.x), lerp(t, r4.y, r5.y));
drawPoint(r1, 2, '#FF0');
drawPoint(r2, 2, '#FF0');
drawPoint(r3, 2, '#FF0');
drawPoint(r4, 1, '#FFF');
drawPoint(r5, 2, '#FFF');
drawPoint(fp, 2, '#0F0');
drawLine(pointA, controlA, 2);
drawLine(controlA, controlB, 2);
drawLine(controlB, pointB, 2);
drawLine(r1, r2, 2);
drawLine(r2, r3, 2);
drawLine(r4, r5, 2);
context.beginPath();
context.strokeStyle = '#AAA';
context.lineWidth = 1;
var j = 1;
for (j; j > 0; j -= 0.01) {
var t1 = Point.create(lerp(j, p1.x, c1.x), lerp(j, p1.y, c1.y));
var t2 = Point.create(lerp(j, c1.x, c2.x), lerp(j, c1.y, c2.y));
var t3 = Point.create(lerp(j, c2.x, p2.x), lerp(j, c2.y, p2.y));
var t4 = Point.create(lerp(j, t1.x, t2.x), lerp(j, t1.y, t2.y));
var t5 = Point.create(lerp(j, t2.x, t3.x), lerp(j, t2.y, t3.y));
var tp = Point.create(lerp(j, t4.x, t5.x), lerp(j, t4.y, t5.y));
if (j == t) context.moveTo(tp.x, tp.y);
else context.lineTo(tp.x, tp.y);
}
context.stroke();
context.closePath();
context.beginPath();
context.strokeStyle = '#FFF';
var i = t;
for (i; i > 0; i -= 0.02) {
var t1 = Point.create(lerp(i, p1.x, c1.x), lerp(i, p1.y, c1.y));
var t2 = Point.create(lerp(i, c1.x, c2.x), lerp(i, c1.y, c2.y));
var t3 = Point.create(lerp(i, c2.x, p2.x), lerp(i, c2.y, p2.y));
var t4 = Point.create(lerp(i, t1.x, t2.x), lerp(i, t1.y, t2.y));
var t5 = Point.create(lerp(i, t2.x, t3.x), lerp(i, t2.y, t3.y));
var tp = Point.create(lerp(i, t4.x, t5.x), lerp(i, t4.y, t5.y));
context.lineWidth = ((i * 30) >> 0) + 4;
if (i == t) context.moveTo(tp.x, tp.y);
else context.lineTo(tp.x, tp.y);
context.stroke();
}
context.closePath();
}
function drawLine(p1, p2, width) {
context.strokeStyle = '#222';
context.lineWidth = 1;
context.moveTo(p1.x, p1.y);
context.lineTo(p2.x, p2.y);
context.stroke();
context.closePath();
}
function lerp(value, min, max) {
return (max - min) * value + min;
}
//VPoint
var Point = (function() {
//exposed methods:
var create = function(x, y) {
var obj = Object.create(def);
obj.x = x || 0;
obj.y = y || 0;
return obj;
};
//Vec2D definition:
var def = {
x: null,
y: null
};
return {
create: create
};
}());