Статья по теме:
Демо JavaScript:
Points
Line
<canvas id="canvas" width="1500" height="800"></canvas><br/> <input type="checkbox" id="Points">Points<br /> <input type="checkbox" id="Line">Line<br /> <input type="button" onclick="update()" value="Update"> <script type="text/javascript"> var coords = []; var k=0; var plot = function(x, y, c) { // ”становить пиксель в т. (x, y) с прозрачностью c if(isFinite(x) && isFinite(y)){ var color = { r: plot.color.r, g: plot.color.g, b: plot.color.b, a: plot.color.a*c }; setPixel(x,y, color); } }; function setPixel (x,y,c) { // функция установки пикселя в js c = c||1; var p=canva.createImageData(1,1); p.data[0]=c.r; p.data[1]=c.g; p.data[2]=c.b; p.data[3]=c.a; var data = canva.getImageData(x, y, 1,1).data; if(data[3] <= p.data[3]) canva.putImageData(p,x,y); } function drawSpline(color) { var num = 0; for(var i=0; i<2*k; i+=2){ if(i>0){ var deltaX = coords[i/2+1].X - coords[i/2].X; var deltaY = coords[i/2+1].Y - coords[i/2].Y; num += Math.sqrt(deltaX*deltaX+deltaY*deltaY); } } coords[0] = coords[1]; coords[coords.length] = coords[coords.length-1]; plot.color = color; for (var i = 1; i <= coords.length-3; i++)// в цикле по всем четвёркам точек { var a = [], b = []; arrs = {a:a, b:b}; _SplineCoefficient(i, arrs, coords);// считаем коэффициенты q ` var points = {};// создаём массив промежуточных точек for(var j=0;j<num;j++) { var t = j/num;// шаг интерполяции // передаём массиву точек значения по методу beta-spline points.X = (arrs.a[0] + t * (arrs.a[1] + t * (arrs.a[2] + t * arrs.a[3]))); points.Y = (arrs.b[0] + t * (arrs.b[1] + t * (arrs.b[2] + t * arrs.b[3]))); plot(points.X, points.Y,color.a/255); } } } function _SplineCoefficient(i, arrs, coords)// в функции рассчитываютс¤ коэффициенты a0-a3, b0-b3 { arrs.a[3] = (-coords[i - 1].X + 3*coords[i].X - 3*coords[i + 1].X + coords[i + 2].X)/6; arrs.a[2] = (coords[i - 1].X - 2*coords[i].X + coords[i + 1].X)/2; arrs.a[1] = (-coords[i - 1].X + coords[i + 1].X)/2; arrs.a[0] = (coords[i - 1].X + 4*coords[i].X + coords[i + 1].X)/6; arrs.b[3] = (-coords[i - 1].Y + 3*coords[i].Y - 3*coords[i + 1].Y + coords[i + 2].Y)/6; arrs.b[2] = (coords[i - 1].Y - 2*coords[i].Y + coords[i + 1].Y)/2; arrs.b[1] = (-coords[i - 1].Y + coords[i + 1].Y)/2; arrs.b[0] = (coords[i - 1].Y + 4*coords[i].Y + coords[i + 1].Y)/6; } var canva = document.getElementById("canvas").getContext('2d'); var mouseX,mouseY; var Line,Points; canvas.onclick = function(event) { canva.clearRect(0,0,1500,800); Line=document.getElementById('Line').checked; //проверяем chekbox'ы Points=document.getElementById('Points').checked; mouseX = event.clientX; //запоминаем координаты мыши mouseY = event.clientY; k++; coords[k] = {X:mouseX, Y:mouseY}; if (k>3){ drawSpline( {r:255, g:0, b:0, a:255}, coords[k-3].X, coords[k-3].Y, coords[k-2].X, coords[k-2].Y, coords[k-1].X, coords[k-1].Y, coords[k].X, coords[k].Y); } if (Points==true){ //рисуем точки for (var i=0;i<coords.length-1;i++){ canva.beginPath(); canva.arc(coords[i+1].X,coords[i+1].Y,2,0,2*Math.PI); canva.stroke(); canva.fillStyle="green"; canva.fill(); } } if (Line==true){ //проводим ломанную canva.beginPath(); canva.moveTo(coords[1].X,coords[1].Y); for (i=1;i<coords.length-1;i++) canva.lineTo(coords[i+1].X,coords[i+1].Y); canva.stroke(); } } function update(){ canva.clearRect(0,0,1500,800); Line=document.getElementById('Line').checked; //проверяем chekbox'ы Points=document.getElementById('Points').checked; coords.pop(); if (k>3){ drawSpline( {r:255, g:0, b:0, a:255}, coords[k-3].X, coords[k-3].Y, coords[k-2].X, coords[k-2].Y, coords[k-1].X, coords[k-1].Y, coords[k].X, coords[k].Y); } if (Points==true){ //рисуем точки for (var i=0;i<coords.length-1;i++){ canva.beginPath(); canva.arc(coords[i+1].X,coords[i+1].Y,2,0,2*Math.PI); canva.stroke(); canva.fillStyle="green"; canva.fill(); } } if (Line==true){ //проводим ломанную canva.beginPath(); canva.moveTo(coords[1].X,coords[1].Y); for (i=1;i<coords.length-1;i++) canva.lineTo(coords[i+1].X,coords[i+1].Y); canva.stroke(); } } </script>