// Bezier Demo
// i - номер вершины, n - количество вершин, t - положение кривой (от 0 до 1)
function getBezierBasis(i, n, t) {
// Факториал
function f(n) {
return (n <= 1) ? 1 : n * f(n - 1);
}
// считаем i-й элемент полинома Берштейна
return (f(n)/(f(i)*f(n - i)))* Math.pow(t, i)*Math.pow(1 - t, n - i);
}
// arr - массив опорных точек. Точка - двухэлементный массив, (x = arr[0], y = arr[1])
// step - шаг при расчете кривой (0 < step < 1), по умолчанию 0.01. Чем больше шаг - тем грубее кривая
function getBezierCurve(arr, step) {
if (step === undefined) {
step = 0.01;
}
var res = [];
step = step / arr.length;
for (var t = 0.0; t < 1 + step; t += step) {
if (t > 1) {
t = 1;
}
var ind = res.length;
res[ind] = new Array(0, 0);
for (var i = 0; i < arr.length; i++) {
var b = getBezierBasis(i, arr.length - 1, t);
res[ind][0] += arr[i][0] * b;
res[ind][1] += arr[i][1] * b;
}
}
return res;
}
// Рисуем непрерывную кривую безье
// ctx - rendering context холста
// arr - массив точек по которым строим кривую
// delay - задержка перед отрисовкой следующей точки, pause - пауза перед началом рисования,
function drawLines(ctx, arr, delay, pause) {
if (delay === undefined) {
delay = 20;
}
if (pause === undefined) {
pause = delay;
}
var i = 0;
function delayDraw() {
if (i >= arr.length - 1) {
return;
}
ctx.moveTo(arr[i][0],arr[i][1]);
ctx.lineTo(arr[i+1][0],arr[i+1][1]);
ctx.strokeStyle = '#fff';
ctx.stroke();
++i;
if (delay > 0) {
setTimeout(delayDraw, delay);
}
else {
delayDraw();
}
}
if (pause > 0) {
setTimeout(delayDraw, pause);
}
else {
delayDraw();
}
}
function drawPixels(ctx, arr, delay, pause) {
if (delay === undefined) {
delay = 10;
}
if (pause === undefined) {
pause = delay;
}
var i = 0;
var pxl = ctx.createImageData(2,2);
var d = pxl.data; // only do this once per page
d[0] = 0;
d[1] = 0;
d[2] = 0;
d[3] = 255;
function delayDraw() {
if (i >= arr.length - 1) {
return;
}
ctx.putImageData(pxl, arr[i][0], arr[i][1]);
++i;
if (delay > 0) {
setTimeout(delayDraw, delay);
}
else {
delayDraw();
}
}
if (pause > 0) {
setTimeout(delayDraw, pause);
}
else {
delayDraw();
}
}
// Рисуем контрольные точки
// ctx - rendering context холста, arr - массив точек по которым строим кривую
// delay - задержка перед отрисовкой следующей точки, pause - пауза перед началом рисования
function drawPoints(ctx, arr, delay, pause) {
if (delay === undefined) {
delay = 0;
}
if (pause === undefined) {
pause = delay;
}
var i = 0;
function delayDraw() {
ctx.beginPath();
ctx.arc(arr[i][0],arr[i][1],pointRadius,0,2*Math.PI);
ctx.strokeStyle = '#FFF';
ctx.stroke();
ctx.fillStyle = '#FFF';
ctx.fillText((i + 1),arr[i][0],arr[i][1] - 10);
ctx.fillStyle = '#fff';
ctx.fillText(' (' + arr[i][0] + ', ' + arr[i][1] + ')', arr[i][0] + 15,arr[i][1] - 10);
if (++i >= arr.length) {
return;
}
if (delay > 0) {
setTimeout(delayDraw, delay);
}
else {
delayDraw();
}
}
if (pause > 0) {
setTimeout(delayDraw, pause);
}
else {
delayDraw();
}
}
drawC = document.getElementById('bezier');
if (drawC && drawC.getContext) {
ctx = drawC.getContext('2d');
ctx.fillStyle="#FFF";
ctx.lineWidth=1.2;
var flow; // Массив точек
var arr = new Array();
// 1
arr[0] = new Array(193.82,155.18);
arr[1] = new Array(205.61, 177.94);
arr[2] = new Array(217.4, 197.86);
arr[3] = new Array(229.59, 214.53);
//2
arr[4] = new Array(242.2, 228.35);
arr[5] = new Array(255.2, 236.48);
arr[6] = new Array(270.24, 241.36);
arr[7] = new Array(285.28, 231.60);
arr[8] = new Array(298.29, 214.93);
arr[9] = new Array(311.3, 196.64);
arr[10] = new Array(321.46,177.54);
arr[11] = new Array(332.44, 159.65);
arr[12] = new Array(343.41, 141.36);
arr[13] = new Array(354.8, 123.47);
arr[14] = new Array(366.18, 108.89);
arr[15] = new Array(382.44, 96.64);
arr[16] = new Array(399.51, 101.13);
arr[17] = new Array(413.33, 113.72);
arr[18] = new Array(425.93, 124.28);
arr[19] = new Array(437.72, 135.26);
arr[20] = new Array(448.29, 145.42);
arr[20.5] = new Array(461.3, 156.4);
arr[21] = new Array(471.46, 165.75);
arr[22] = new Array(482.85, 172.25);
arr[23] = new Array(495.04,175.5);
arr[24] = new Array(509.67, 169.81);
arr[25] = new Array(522.28, 158.84);
arr[26] = new Array(531.22,149.08);
arr[27] = new Array(540.57, 135.67);
arr[28] = new Array(548.7,122.66);
arr[29] = new Array(554.8, 109.24);
arr[30] = new Array(562.52, 92.98);
arr[31] = new Array(569.43, 77.54);
arr[32] = new Array(572.12, 62.5);
arr[33] = new Array(581.22, 44.61);
flow = getBezierCurve(new Array(arr[0], arr[1], arr[2], arr[3]), 0.3); // Из кривой 1 вырастают 2, 3. Кривые 1, 2 рисуем одной линией
flow = flow.concat(getBezierCurve(new Array(arr[3], arr[4], arr[5], arr[6], arr[7], arr[8], arr[9], arr[10], arr[11], arr[12]), 0.2));
flow = flow.concat(getBezierCurve(new Array(arr[12], arr[13], arr[14], arr[15], arr[16], arr[17], arr[18], arr[19], arr[20], arr[20.5]), 0.3));
flow = flow.concat(getBezierCurve(new Array(arr[20.5], arr[21], arr[22], arr[23], arr[24], arr[25], arr[26], arr[27], arr[28]), 0.4));
flow = flow.concat(getBezierCurve(new Array(arr[28], arr[29], arr[30], arr[31], arr[32], arr[33]), 1.5));
}
function mainFunc()
{
drawLines(ctx, flow, 10)
ctx.clearRect(0, 0, 700, 310);
myFunc() //такой вариант приводит к сбою сценария на странице
}
mainFunc();
}
посмотреть анимацию можно здесь
http://lopushansky.com