// It seems that classes have to go up here in Drupal Javascript. // Might be related to jQuery and loading order. // Class Point function Point(px, py) { this.px = px; this.py = py; } // class Circle function Circle(p, radius) { this.p = p; this.radius = radius; } Circle.prototype.show = function() { console.log(this.p.px + " - " + this.p.py + " - " + this.radius); } Circle.prototype.draw = function(ctx, color) { ctx.beginPath(); ctx.arc(this.p.px, this.p.py, this.radius, 0, 2 * Math.PI, false); ctx.fillStyle = color; ctx.fill(); ctx.lineWidth = 1; ctx.strokeStyle = "black"; ctx.stroke(); } // Use the bbox. Circle.prototype.contains = function(t) { var left = this.p.px - this.radius; var right = this.p.px + this.radius; var top = this.p.py - this.radius; var bottom = this.p.py + this.radius; var bInside = (t.px > left) && (t.px < right) && (t.py > top) && (t.py < bottom); return bInside; } //------------------------ // End of classes. //------------------------ var canvas; var ctx; var WAITING = 0; var DRAGGING = 1; var state = WAITING; var activePoint = -1; var points = new Array(new Point(30, 200), new Point(70, 65), new Point(200, 80), new Point(240, 200)); var circles = new Array(); jQuery(document).ready(function() { canvas = document.getElementById("bezier"); if (canvas.getContext) { ctx = canvas.getContext("2d"); // Create circles from points. for (var k = 0; k < points.length; k++) circles.push(new Circle(points[k], 4)); invalidate(); canvas.addEventListener("mousedown", mouseDown, false); canvas.addEventListener("mousemove", mouseMove, false); canvas.addEventListener("mouseup", mouseUp, false); } // if (canvas.getContext) }); // ready() function mouseDown(event) { var userPt = getMousePos(canvas, event); for (var k = 0; k < points.length; k++) if ((state == WAITING) && circles[k].contains(userPt)) { state = DRAGGING; activePoint = k; } } function mouseMove(event) { if (state == DRAGGING) { circles[activePoint].p = getMousePos(canvas, event); invalidate(); } } function mouseUp(event) { if (state == DRAGGING) state = WAITING; } function getMousePos(canvas, event) { // Ints not always returned! var rect = canvas.getBoundingClientRect(); return { px: event.clientX - Math.round(rect.left), py: event.clientY - Math.round(rect.top) }; } function invalidate() { //Here is where everything is redrawn when dragging. ctx.clearRect(0, 0, canvas.width, canvas.height); // Fill background white and draw frame. ctx.fillStyle = "white"; ctx.strokeStyle = "black"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.strokeRect(0, 0, canvas.width, canvas.height); // Draw the handle vectors. ctx.moveTo(circles[0].p.px, circles[0].p.py); ctx.lineTo(circles[1].p.px, circles[1].p.py); ctx.stroke(); ctx.moveTo(circles[3].p.px, circles[3].p.py); ctx.lineTo(circles[2].p.px, circles[2].p.py); ctx.stroke(); // Draw the Bezier curve. ctx.beginPath(); ctx.moveTo(circles[0].p.px, circles[0].p.py); ctx.bezierCurveTo(circles[1].p.px, circles[1].p.py, // first control circles[2].p.px, circles[2].p.py, // second control circles[3].p.px, circles[3].p.py); // end point ctx.stroke(); // Draw the circles. for (var k = 0; k < points.length; k++) circles[k].draw(ctx, "red"); }