lambdaway
::
interactive_cubic
1
|
list
|
login
|
load
|
|
;; _img http://epsilonwiki.free.fr/epsilonwiki/data/elan.png _h1 interactive cubic bézier curve {canvas {@ id="bez_canvas" height="400" width="600" style="border:1px solid grey; box-shadow:0 0 8px #000;"}} {center {pre {@ id="bezier"}}} {hr} _p Play with the handles and read [[decasteljau]] to understand the recursive algorithm. _p Follows the Canvas curves example by [[Craig Buckler|http://twitter.com/craigbuckler]] of [[OptimalWorks.net|http://optimalworks.net/]] for [[SitePoint.com|http://sitepoint.com/]]. {script var BEZ = (function() { var canvas, ctx, code, point, style, drag = null, dPoint; var Init = function (quadratic) { canvas = LAMBDATANK.getId('bez_canvas'); code = LAMBDATANK.getId('bezier'); ctx = canvas.getContext('2d'); point = { p1: { x:100, y:250 }, p2: { x:580, y:380 } }; if (quadratic) { point.cp1 = { x: 250, y: 100 }; } else { point.cp1 = { x: 100, y: 100 }; point.cp2 = { x: 350, y: 100 }; } // default styles style = { curve: { width: 6, color: '#333' }, cpline: { width: 1, color: '#C00' }, point: { radius: 10, width: 2, color: '#900', fill: 'rgba(200,200,200,0.5)', arc1: 0, arc2: 2 * Math.PI } } // line style defaults ctx.lineCap = 'round'; ctx.lineJoin = 'round'; // event handlers /* canvas.onmousedown = DragStart; canvas.onmousemove = Dragging; canvas.onmouseup = canvas.onmouseout = DragEnd; */ canvas.addEventListener('mousedown', DragStart, false); canvas.addEventListener('mousemove', Dragging, false); canvas.addEventListener('mouseup', DragEnd, false); DrawCanvas(); }; var DrawCanvas = function() { ctx.clearRect(0, 0, canvas.width, canvas.height); // control lines ctx.lineWidth = style.cpline.width; ctx.strokeStyle = style.cpline.color; ctx.beginPath(); ctx.moveTo(point.p1.x, point.p1.y); ctx.lineTo(point.cp1.x, point.cp1.y); if (point.cp2) { ctx.moveTo(point.p2.x, point.p2.y); ctx.lineTo(point.cp2.x, point.cp2.y); } else { ctx.lineTo(point.p2.x, point.p2.y); } ctx.stroke(); // curve ctx.lineWidth = style.curve.width; ctx.strokeStyle = style.curve.color; ctx.beginPath(); ctx.moveTo(point.p1.x, point.p1.y); if (point.cp2) { ctx.bezierCurveTo( point.cp1.x, point.cp1.y, point.cp2.x, point.cp2.y, point.p2.x, point.p2.y); } else { ctx.quadraticCurveTo( point.cp1.x, point.cp1.y, point.p2.x, point.p2.y); } ctx.stroke(); // control points for (var p in point) { ctx.lineWidth = style.point.width; ctx.strokeStyle = style.point.color; ctx.fillStyle = style.point.fill; ctx.beginPath(); ctx.arc( point[p].x, point[p].y, style.point.radius, style.point.arc1, style.point.arc2, true); ctx.fill(); ctx.stroke(); } ShowCode(); }; // show canvas code var ShowCode = function() { if (code) { code.innerHTML = '[' + point.p1.x + ',' + point.p1.y +'].' + (point.cp2 ? '[' + point.cp1.x + ',' + point.cp1.y + '].[' + point.cp2.x + ',' + point.cp2.y + '].[' + point.p2.x + ',' + point.p2.y + ']' : '[' + point.cp1.x + ',' + point.cp1.y + '].[' + point.p2.x + ',' + point.p2.y + ']' ) } }; // start dragging var DragStart = function(e) { e = MousePos(e); var dx, dy; for (var p in point) { dx = point[p].x - e.x; dy = point[p].y - e.y; if ((dx * dx) + (dy * dy) < style.point.radius * style.point.radius) { drag = p; dPoint = e; canvas.style.cursor = 'move'; return; } } }; // dragging var Dragging = function(e) { if (drag) { e = MousePos(e); point[drag].x += e.x - dPoint.x; point[drag].y += e.y - dPoint.y; dPoint = e; DrawCanvas(); } }; // end dragging var DragEnd = function(e) { drag = null; canvas.style.cursor = 'default'; DrawCanvas(); }; // event parser with thanks to ryan-artecona for the function relMouseCoords(event) // http: //stackoverflow.com/users/671915/ryan-artecona]]. var relMouseCoords = function(event){ var totalOffsetX = 0, totalOffsetY = 0, canvasX = 0, canvasY = 0; var currentElement = this; do { totalOffsetX += currentElement.offsetLeft; totalOffsetY += currentElement.offsetTop; } while(currentElement = currentElement.offsetParent) canvasX = event.pageX - totalOffsetX; canvasY = event.pageY - totalOffsetY; return { x:canvasX, y:canvasY } }; HTMLCanvasElement.prototype.relMouseCoords = relMouseCoords; var MousePos = function(event) { coords = canvas.relMouseCoords(event); return {x:coords.x, y:coords.y } }; return {Init:Init} })(); setTimeout( BEZ.Init, 1, false ); } {style #page_frame { width:622px; } }
lambdaway v.20211111