|
|
- // Generated by CoffeeScript 1.6.3
- (function() {
- "use strict";
- var ArcSegment, Board, Chain, FPS, Gear, GearSketch, LineSegment, MIN_GEAR_TEETH, MIN_MOMENTUM, Point, Util,
- __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- __hasProp = {}.hasOwnProperty,
- __slice = [].slice;
-
- Point = window.gearsketch.Point;
-
- ArcSegment = window.gearsketch.ArcSegment;
-
- LineSegment = window.gearsketch.LineSegment;
-
- Util = window.gearsketch.Util;
-
- Gear = window.gearsketch.model.Gear;
-
- Chain = window.gearsketch.model.Chain;
-
- Board = window.gearsketch.model.Board;
-
- FPS = 60;
-
- MIN_GEAR_TEETH = 8;
-
- MIN_MOMENTUM = 0.2;
-
- GearSketch = (function() {
- var AXIS_RADIUS, BUTTON_INFO, MODULE, MovementAction, MovementType;
-
- MODULE = Util.MODULE;
-
- AXIS_RADIUS = Util.AXIS_RADIUS;
-
- BUTTON_INFO = [["gearButton", "GearIcon.png"], ["chainButton", "ChainIcon.png"], ["momentumButton", "MomentumIcon.png"], ["playButton", "PlayIcon.png"], ["clearButton", "ClearIcon.png"], ["cloudButton", "CloudIcon.png"], ["helpButton", "HelpIcon.png"]];
-
- MovementAction = {
- PEN_DOWN: "penDown",
- PEN_UP: "penUp",
- PEN_TAP: "penTap"
- };
-
- MovementType = {
- STRAIGHT: "straight",
- CIRCLE: "circle",
- LEFT_HALF_CIRCLE: "leftHalfCircle",
- RIGHT_HALF_CIRCLE: "rightHalfCircle"
- };
-
- GearSketch.prototype.buttons = {};
-
- GearSketch.prototype.loadedButtons = 0;
-
- GearSketch.prototype.areButtonsLoaded = false;
-
- GearSketch.prototype.selectedButton = BUTTON_INFO[0][0];
-
- GearSketch.prototype.gearImages = {};
-
- GearSketch.prototype.isPenDown = false;
-
- GearSketch.prototype.stroke = [];
-
- GearSketch.prototype.offset = new Point();
-
- GearSketch.prototype.message = "";
-
- GearSketch.prototype.messageColor = "black";
-
- GearSketch.prototype.pointerLocation = new Point();
-
- GearSketch.prototype.currentDemoMovement = 0;
-
- GearSketch.prototype.movementCompletion = 0;
-
- GearSketch.prototype.restTimer = 0;
-
- function GearSketch(showButtons) {
- if (showButtons == null) {
- showButtons = true;
- }
- this.update = __bind(this.update, this);
- this.updateAndDrawNoRAF = __bind(this.updateAndDrawNoRAF, this);
- this.updateAndDraw = __bind(this.updateAndDraw, this);
- this.loadButtons();
- this.showButtons = showButtons;
- this.loadDemoPointer();
- this.loadBoard();
- this.canvas = document.getElementById("gearsketch_canvas");
- this.canvasOffsetX = this.canvas.getBoundingClientRect().left;
- this.canvasOffsetY = this.canvas.getBoundingClientRect().top;
- this.isDemoPlaying = false;
- this.updateCanvasSize();
- this.addCanvasListeners();
- this.lastUpdateTime = new Date().getTime();
- this.updateAndDrawNoRAF();
- }
-
- GearSketch.prototype.buttonLoaded = function() {
- this.loadedButtons++;
- if (this.loadedButtons === BUTTON_INFO.length) {
- return this.areButtonsLoaded = true;
- }
- };
-
- GearSketch.prototype.loadButtons = function() {
- var button, file, name, x, y, _i, _len, _ref, _results,
- _this = this;
- x = y = 20;
- _results = [];
- for (_i = 0, _len = BUTTON_INFO.length; _i < _len; _i++) {
- _ref = BUTTON_INFO[_i], name = _ref[0], file = _ref[1];
- button = new Image();
- button.name = name;
- button.onload = function() {
- return _this.buttonLoaded();
- };
- button.src = "img/" + file;
- button.location = new Point(x, y);
- button.padding = 3;
- this.buttons[name] = button;
- _results.push(x += 80);
- }
- return _results;
- };
-
- GearSketch.prototype.loadDemoPointer = function() {
- var image,
- _this = this;
- image = new Image();
- image.onload = function() {
- return _this.pointerImage = image;
- };
- return image.src = "img/hand.png";
- };
-
- GearSketch.prototype.loadBoard = function() {
- var boardJSON, error, gear, hash, id, _ref, _results;
- this.board = (function() {
- if (parent.location.hash.length > 1) {
- try {
- hash = parent.location.hash.substr(1);
- boardJSON = Util.sendGetRequest("boards/" + hash + ".txt");
- return Board.fromObject(JSON.parse(boardJSON));
- } catch (_error) {
- error = _error;
- this.displayMessage("Error: could not load board", "red", 2000);
- return new Board();
- }
- } else {
- return new Board();
- }
- }).call(this);
- _ref = this.board.getGears();
- _results = [];
- for (id in _ref) {
- gear = _ref[id];
- _results.push(this.addGearImage(gear));
- }
- return _results;
- };
-
- GearSketch.prototype.displayMessage = function(message, color, time) {
- var _this = this;
- if (color == null) {
- color = "black";
- }
- if (time == null) {
- time = 0;
- }
- this.message = message;
- this.messageColor = color;
- if (time > 0) {
- return setTimeout((function() {
- return _this.clearMessage();
- }), time);
- }
- };
-
- GearSketch.prototype.clearMessage = function() {
- return this.message = "";
- };
-
- GearSketch.prototype.selectButton = function(buttonName) {
- return this.selectedButton = buttonName;
- };
-
- GearSketch.prototype.shouldShowButtons = function() {
- return this.showButtons || this.isDemoPlaying;
- };
-
- GearSketch.prototype.addCanvasListeners = function() {
- var canvasEventHandler,
- _this = this;
- canvasEventHandler = Hammer(this.canvas, {
- drag_min_distance: 1
- });
- canvasEventHandler.on("touch", (function(e) {
- return _this.forwardPenDownEvent.call(_this, e);
- }));
- canvasEventHandler.on("drag", (function(e) {
- return _this.forwardPenMoveEvent.call(_this, e);
- }));
- return canvasEventHandler.on("release", (function(e) {
- return _this.forwardPenUpEvent.call(_this, e);
- }));
- };
-
- GearSketch.prototype.forwardPenDownEvent = function(event) {
- var x, y;
- event.gesture.preventDefault();
- if (this.isDemoPlaying) {
- return this.stopDemo();
- } else {
- x = event.gesture.center.pageX - this.canvasOffsetX;
- y = event.gesture.center.pageY - this.canvasOffsetY;
- return this.handlePenDown(x, y);
- }
- };
-
- GearSketch.prototype.forwardPenMoveEvent = function(event) {
- var x, y;
- event.gesture.preventDefault();
- if (!this.isDemoPlaying) {
- x = event.gesture.center.pageX - this.canvasOffsetX;
- y = event.gesture.center.pageY - this.canvasOffsetY;
- return this.handlePenMove(x, y);
- }
- };
-
- GearSketch.prototype.forwardPenUpEvent = function(event) {
- if (!this.isDemoPlaying) {
- return this.handlePenUp();
- }
- };
-
- GearSketch.prototype.handlePenDown = function(x, y) {
- var button, point;
- point = new Point(x, y);
- if (this.isPenDown) {
- return this.handlePenUp();
- } else {
- button = this.getButtonAt(x, y);
- if (button) {
- if (button.name === "clearButton") {
- parent.location.hash = "";
- return this.board.clear();
- } else if (button.name === "cloudButton") {
- return this.uploadBoard();
- } else if (button.name === "helpButton") {
- return this.playDemo();
- } else {
- return this.selectButton(button.name);
- }
- } else if (this.selectedButton === "gearButton") {
- this.selectedGear = this.board.getTopLevelGearAt(point);
- if (this.selectedGear != null) {
- this.offset = point.minus(this.selectedGear.location);
- } else if (this.board.getGearAt(point) == null) {
- this.stroke.push(point);
- }
- return this.isPenDown = true;
- } else if (this.selectedButton === "chainButton") {
- this.stroke.push(point);
- return this.isPenDown = true;
- } else if (this.selectedButton === "momentumButton") {
- this.selectedGear = this.board.getGearAt(point);
- if (this.selectedGear) {
- this.selectedGear.momentum = 0;
- this.selectedGearMomentum = this.calculateMomentumFromCoords(this.selectedGear, x, y);
- }
- return this.isPenDown = true;
- }
- }
- };
-
- GearSketch.prototype.handlePenMove = function(x, y) {
- var canPlaceGear, goalLocation, point;
- point = new Point(x, y);
- if (this.isPenDown) {
- if (this.selectedButton === "gearButton") {
- if (this.selectedGear) {
- goalLocation = point.minus(this.offset);
- canPlaceGear = this.board.placeGear(this.selectedGear, goalLocation);
- if (canPlaceGear) {
- return this.goalLocationGear = null;
- } else {
- return this.goalLocationGear = new Gear(goalLocation, this.selectedGear.rotation, this.selectedGear.numberOfTeeth, this.selectedGear.id, this.selectedGear.hue);
- }
- } else if (this.stroke.length > 0) {
- return this.stroke.push(point);
- }
- } else if (this.selectedButton === "chainButton") {
- return this.stroke.push(point);
- } else if (this.selectedButton === "momentumButton") {
- if (this.selectedGear) {
- return this.selectedGearMomentum = this.calculateMomentumFromCoords(this.selectedGear, x, y);
- }
- }
- }
- };
-
- GearSketch.prototype.handlePenUp = function() {
- if (this.isPenDown) {
- if (this.selectedButton === "gearButton") {
- if (!((this.selectedGear != null) || this.stroke.length === 0)) {
- this.processGearStroke();
- }
- } else if (this.selectedButton === "chainButton") {
- this.processChainStroke();
- } else if (this.selectedButton === "momentumButton") {
- if (this.selectedGear) {
- if (Math.abs(this.selectedGearMomentum) > MIN_MOMENTUM) {
- this.selectedGear.momentum = this.selectedGearMomentum;
- } else {
- this.selectedGear.momentum = 0;
- }
- }
- this.selectedGearMomentum = 0;
- }
- this.selectedGear = null;
- this.goalLocationGear = null;
- return this.isPenDown = false;
- }
- };
-
- GearSketch.prototype.isButtonAt = function(x, y, button) {
- return x > button.location.x && x < button.location.x + button.width + 2 * button.padding && y > button.location.y && y < button.location.y + button.height + 2 * button.padding;
- };
-
- GearSketch.prototype.getButtonAt = function(x, y) {
- var button, buttonName, _ref;
- if (!this.shouldShowButtons()) {
- return null;
- }
- _ref = this.buttons;
- for (buttonName in _ref) {
- if (!__hasProp.call(_ref, buttonName)) continue;
- button = _ref[buttonName];
- if (this.isButtonAt(x, y, button)) {
- return button;
- }
- }
- return null;
- };
-
- GearSketch.prototype.normalizeStroke = function(stroke) {
- var MIN_POINT_DISTANCE, normalizedStroke, p1, p2, strokeTail, _i, _len;
- MIN_POINT_DISTANCE = 10;
- normalizedStroke = [];
- if (stroke.length > 0) {
- p1 = stroke[0], strokeTail = 2 <= stroke.length ? __slice.call(stroke, 1) : [];
- normalizedStroke.push(p1);
- for (_i = 0, _len = strokeTail.length; _i < _len; _i++) {
- p2 = strokeTail[_i];
- if (p1.distance(p2) > MIN_POINT_DISTANCE) {
- normalizedStroke.push(p2);
- p1 = p2;
- }
- }
- }
- return normalizedStroke;
- };
-
- GearSketch.prototype.createGearFromStroke = function(stroke) {
- var area, doubleArea, height, i, idealTrueAreaRatio, j, maxX, maxY, minX, minY, numberOfPoints, p, radius, sumX, sumY, t, width, x, y, _i, _j, _len;
- numberOfPoints = stroke.length;
- if (numberOfPoints > 0) {
- sumX = 0;
- sumY = 0;
- minX = Number.MAX_VALUE;
- maxX = Number.MIN_VALUE;
- minY = Number.MAX_VALUE;
- maxY = Number.MIN_VALUE;
- for (_i = 0, _len = stroke.length; _i < _len; _i++) {
- p = stroke[_i];
- sumX += p.x;
- sumY += p.y;
- minX = Math.min(minX, p.x);
- maxX = Math.max(maxX, p.x);
- minY = Math.min(minY, p.y);
- maxY = Math.max(maxY, p.y);
- }
- width = maxX - minX;
- height = maxY - minY;
- t = Math.floor(0.5 * (width + height) / MODULE);
- doubleArea = 0;
- for (i = _j = 0; 0 <= numberOfPoints ? _j < numberOfPoints : _j > numberOfPoints; i = 0 <= numberOfPoints ? ++_j : --_j) {
- j = (i + 1) % numberOfPoints;
- doubleArea += stroke[i].x * stroke[j].y;
- doubleArea -= stroke[i].y * stroke[j].x;
- }
- area = Math.abs(doubleArea) / 2;
- radius = 0.25 * ((maxX - minX) + (maxY - minY));
- idealTrueAreaRatio = (Math.PI * Math.pow(radius, 2)) / area;
- if (idealTrueAreaRatio > 0.80 && idealTrueAreaRatio < 1.20 && t > MIN_GEAR_TEETH) {
- x = sumX / numberOfPoints;
- y = sumY / numberOfPoints;
- return new Gear(new Point(x, y), 0, t);
- }
- }
- return null;
- };
-
- GearSketch.prototype.removeStrokedGears = function(stroke) {
- var gear, id, _ref, _results;
- _ref = this.board.getTopLevelGears();
- _results = [];
- for (id in _ref) {
- if (!__hasProp.call(_ref, id)) continue;
- gear = _ref[id];
- if (Util.pointPathDistance(gear.location, stroke, false) < gear.innerRadius) {
- _results.push(this.board.removeGear(gear));
- } else {
- _results.push(void 0);
- }
- }
- return _results;
- };
-
- GearSketch.prototype.processGearStroke = function() {
- var gear, isGearAdded, normalizedStroke;
- normalizedStroke = this.normalizeStroke(this.stroke);
- gear = this.createGearFromStroke(normalizedStroke);
- if (gear != null) {
- isGearAdded = this.board.addGear(gear);
- if (isGearAdded && !(gear.numberOfTeeth in this.gearImages)) {
- this.addGearImage(gear);
- }
- } else {
- this.removeStrokedGears(normalizedStroke);
- }
- return this.stroke = [];
- };
-
- GearSketch.prototype.gearImageLoaded = function(numberOfTeeth, image) {
- return this.gearImages[numberOfTeeth] = image;
- };
-
- GearSketch.prototype.addGearImage = function(gear) {
- var ctx, gearCanvas, gearCopy, image, size,
- _this = this;
- gearCanvas = document.createElement("canvas");
- size = 2 * (gear.outerRadius + MODULE);
- gearCanvas.height = size;
- gearCanvas.width = size;
- ctx = gearCanvas.getContext("2d");
- gearCopy = new Gear(new Point(0.5 * size, 0.5 * size), 0, gear.numberOfTeeth, gear.id, null, null, null, null, gear.hue);
- this.drawGear(ctx, gearCopy);
- image = new Image();
- image.onload = function() {
- return _this.gearImageLoaded(gear.numberOfTeeth, image);
- };
- return image.src = gearCanvas.toDataURL("image/png");
- };
-
- GearSketch.prototype.removeStrokedChains = function(stroke) {
- var chain, id, _ref, _results;
- _ref = this.board.getChains();
- _results = [];
- for (id in _ref) {
- if (!__hasProp.call(_ref, id)) continue;
- chain = _ref[id];
- if (chain.intersectsPath(stroke)) {
- _results.push(this.board.removeChain(chain));
- } else {
- _results.push(void 0);
- }
- }
- return _results;
- };
-
- GearSketch.prototype.processChainStroke = function() {
- var chain, gearsInChain, normalizedStroke;
- normalizedStroke = this.normalizeStroke(this.stroke);
- this.stroke = [];
- gearsInChain = Util.findGearsInsidePolygon(normalizedStroke, this.board.getGears());
- if (normalizedStroke.length >= 3 && gearsInChain.length > 0) {
- chain = new Chain(normalizedStroke);
- return this.board.addChain(chain);
- } else if (normalizedStroke.length >= 2) {
- return this.removeStrokedChains(normalizedStroke);
- }
- };
-
- GearSketch.prototype.calculateMomentumFromCoords = function(gear, x, y) {
- var angle, angleFromTop;
- angle = Math.atan2(y - gear.location.y, x - gear.location.x);
- angleFromTop = angle + 0.5 * Math.PI;
- if (angleFromTop < Math.PI) {
- return angleFromTop;
- } else {
- return angleFromTop - 2 * Math.PI;
- }
- };
-
- GearSketch.prototype.updateAndDraw = function() {
- var _this = this;
- return setTimeout((function() {
- requestAnimationFrame(_this.updateAndDraw);
- _this.update();
- return _this.draw();
- }), 1000 / FPS);
- };
-
- GearSketch.prototype.updateAndDrawNoRAF = function() {
- var _this = this;
- this.update();
- this.draw();
- return setTimeout((function() {
- return _this.updateAndDrawNoRAF();
- }), 1000 / FPS);
- };
-
- GearSketch.prototype.update = function() {
- var delta, updateTime;
- updateTime = new Date().getTime();
- delta = updateTime - this.lastUpdateTime;
- if (this.selectedButton === "playButton") {
- this.board.rotateAllTurningObjects(delta);
- }
- if (this.isDemoPlaying) {
- this.updateDemo(delta);
- }
- return this.lastUpdateTime = updateTime;
- };
-
- GearSketch.prototype.drawGear = function(ctx, gear, color) {
- var angleStep, gearImage, i, innerPoints, numberOfTeeth, outerPoints, r, rotation, x, y, _i, _j, _k, _ref, _ref1;
- if (color == null) {
- color = "black";
- }
- _ref = gear.location, x = _ref.x, y = _ref.y;
- rotation = gear.rotation;
- numberOfTeeth = gear.numberOfTeeth;
- gearImage = this.gearImages[gear.numberOfTeeth];
- if (color === "black" && (gearImage != null)) {
- gearImage = this.gearImages[gear.numberOfTeeth];
- ctx.save();
- ctx.translate(x, y);
- ctx.rotate(rotation);
- ctx.drawImage(gearImage, -0.5 * gearImage.width, -0.5 * gearImage.height);
- ctx.restore();
- return;
- }
- angleStep = 2 * Math.PI / numberOfTeeth;
- innerPoints = [];
- outerPoints = [];
- for (i = _i = 0; 0 <= numberOfTeeth ? _i < numberOfTeeth : _i > numberOfTeeth; i = 0 <= numberOfTeeth ? ++_i : --_i) {
- for (r = _j = 0; _j < 4; r = ++_j) {
- if (r === 0 || r === 3) {
- innerPoints.push(Point.polar((i + 0.25 * r) * angleStep, gear.innerRadius));
- } else {
- outerPoints.push(Point.polar((i + 0.25 * r) * angleStep, gear.outerRadius));
- }
- }
- }
- ctx.save();
-
- if (color === "black") {
- if (!gear.hue) {
- gear.hue = Math.floor(Math.random()*360);
- }
- ctx.fillStyle = "hsla(" + gear.hue + ", 85%, 60%, 0.8)";
- } else {
- ctx.fillStyle = "hsla(0, 0%, 90%, 0.2)";
- }
-
- ctx.strokeStyle = color;
- ctx.lineWidth = 2;
- ctx.translate(x, y);
- ctx.rotate(rotation);
- ctx.beginPath();
- ctx.moveTo(gear.innerRadius, 0);
- for (i = _k = 0, _ref1 = numberOfTeeth * 2; 0 <= _ref1 ? _k < _ref1 : _k > _ref1; i = 0 <= _ref1 ? ++_k : --_k) {
- if (i % 2 === 0) {
- ctx.lineTo(innerPoints[i].x, innerPoints[i].y);
- ctx.lineTo(outerPoints[i].x, outerPoints[i].y);
- } else {
- ctx.lineTo(outerPoints[i].x, outerPoints[i].y);
- ctx.lineTo(innerPoints[i].x, innerPoints[i].y);
- }
- }
- ctx.closePath();
- ctx.fill();
- ctx.stroke();
- ctx.beginPath();
- ctx.moveTo(AXIS_RADIUS, 0);
- ctx.arc(0, 0, AXIS_RADIUS, 0, 2 * Math.PI, true);
- ctx.closePath();
- ctx.stroke();
- ctx.beginPath();
- ctx.moveTo(AXIS_RADIUS, 0);
- ctx.lineTo(gear.innerRadius, 0);
- ctx.closePath();
- ctx.stroke();
- return ctx.restore();
- };
-
- GearSketch.prototype.drawButton = function(ctx, button) {
- var height, padding, radius, width, x, y, _ref;
- _ref = button.location, x = _ref.x, y = _ref.y;
- padding = button.padding;
- ctx.save();
- ctx.translate(x, y);
- ctx.beginPath();
- radius = 10;
- width = button.width + 2 * padding;
- height = button.height + 2 * padding;
- ctx.moveTo(radius, 0);
- ctx.lineTo(width - radius, 0);
- ctx.quadraticCurveTo(width, 0, width, radius);
- ctx.lineTo(width, height - radius);
- ctx.quadraticCurveTo(width, height, width - radius, height);
- ctx.lineTo(radius, height);
- ctx.quadraticCurveTo(0, height, 0, height - radius);
- ctx.lineTo(0, radius);
- ctx.quadraticCurveTo(0, 0, radius, 0);
- if (button.name === this.selectedButton) {
- ctx.fillStyle = "rgba(50, 150, 255, 0.8)";
- } else {
- ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
- }
- ctx.fill();
- ctx.lineWidth = 1;
- ctx.strokeStyle = "black";
- ctx.stroke();
- ctx.drawImage(button, padding, padding);
- return ctx.restore();
- };
-
- GearSketch.prototype.drawMomentum = function(ctx, gear, momentum, color) {
- var angle, head, headX, headY, length, p1, p2, pitchRadius, sign, top;
- if (color == null) {
- color = "red";
- }
- pitchRadius = gear.pitchRadius;
- top = new Point(gear.location.x, gear.location.y - pitchRadius);
- ctx.save();
- ctx.lineWidth = 5;
- ctx.lineCap = "round";
- ctx.strokeStyle = color;
- ctx.translate(top.x, top.y);
- ctx.beginPath();
- ctx.arc(0, pitchRadius, pitchRadius, -0.5 * Math.PI, momentum - 0.5 * Math.PI, momentum < 0);
- ctx.stroke();
- length = 15;
- angle = 0.2 * Math.PI;
- headX = -Math.cos(momentum + 0.5 * Math.PI) * pitchRadius;
- headY = pitchRadius - Math.sin(momentum + 0.5 * Math.PI) * pitchRadius;
- head = new Point(headX, headY);
- sign = Util.sign(momentum);
- p1 = head.minus(Point.polar(momentum + angle, sign * length));
- ctx.beginPath();
- ctx.moveTo(headX, headY);
- ctx.lineTo(p1.x, p1.y);
- ctx.stroke();
- p2 = head.minus(Point.polar(momentum - angle, sign * length));
- ctx.beginPath();
- ctx.moveTo(headX, headY);
- ctx.lineTo(p2.x, p2.y);
- ctx.stroke();
- return ctx.restore();
- };
-
- GearSketch.prototype.drawChain = function(ctx, chain) {
- var isCounterClockwise, point, segment, _i, _j, _len, _len1, _ref, _ref1;
- ctx.save();
- ctx.lineWidth = Chain.WIDTH;
- ctx.lineCap = "round";
- ctx.strokeStyle = "rgb(0, 0, 255)";
- ctx.moveTo(chain.segments[0].start.x, chain.segments[0].start.y);
- _ref = chain.segments;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- segment = _ref[_i];
- if (segment instanceof ArcSegment) {
- isCounterClockwise = segment.direction === Util.Direction.COUNTER_CLOCKWISE;
- ctx.beginPath();
- ctx.arc(segment.center.x, segment.center.y, segment.radius, segment.startAngle, segment.endAngle, isCounterClockwise);
- ctx.stroke();
- } else {
- ctx.beginPath();
- ctx.moveTo(segment.start.x, segment.start.y);
- ctx.lineTo(segment.end.x, segment.end.y);
- ctx.stroke();
- }
- }
- ctx.fillStyle = "white";
- _ref1 = chain.findPointsOnChain(25);
- for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
- point = _ref1[_j];
- ctx.beginPath();
- ctx.arc(point.x, point.y, 3, 0, 2 * Math.PI, true);
- ctx.fill();
- }
- return ctx.restore();
- };
-
- GearSketch.prototype.drawDemoPointer = function(ctx, location) {
- return ctx.drawImage(this.pointerImage, location.x - 0.5 * this.pointerImage.width, location.y);
- };
-
- GearSketch.prototype.draw = function() {
- var arrow, arrowsToDraw, buttonName, chain, ctx, gear, i, momentum, shouldDrawChainsAndArrows, sortedGears, _i, _j, _k, _l, _len, _len1, _ref, _ref1, _ref2, _ref3;
- if (this.canvas.getContext != null) {
- this.updateCanvasSize();
- ctx = this.canvas.getContext("2d");
- ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
- sortedGears = this.board.getGearsSortedByGroupAndLevel();
- arrowsToDraw = [];
- for (i = _i = 0, _ref = sortedGears.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
- gear = sortedGears[i];
- momentum = gear.momentum;
- if (gear === this.selectedGear && this.goalLocationGear) {
- this.drawGear(ctx, gear, "grey");
- if (momentum) {
- arrowsToDraw.push([gear, momentum, "grey"]);
- }
- } else {
- this.drawGear(ctx, gear);
- if (momentum) {
- arrowsToDraw.push([gear, momentum, "red"]);
- }
- }
- shouldDrawChainsAndArrows = (i === sortedGears.length - 1) || (this.board.getLevelScore(gear) !== this.board.getLevelScore(sortedGears[i + 1]));
- if (shouldDrawChainsAndArrows) {
- _ref1 = this.board.getChainsInGroupOnLevel(gear.group, gear.level);
- for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
- chain = _ref1[_j];
- this.drawChain(ctx, chain);
- }
- for (_k = 0, _len1 = arrowsToDraw.length; _k < _len1; _k++) {
- arrow = arrowsToDraw[_k];
- this.drawMomentum(ctx, arrow[0], arrow[1], arrow[2]);
- }
- arrowsToDraw = [];
- }
- }
- if (this.goalLocationGear) {
- this.drawGear(ctx, this.goalLocationGear, "red");
- }
- if ((this.selectedGear != null) && this.selectedGearMomentum) {
- this.drawMomentum(ctx, this.selectedGear, this.selectedGearMomentum);
- }
- if (this.stroke.length > 0) {
- ctx.save();
- if (this.selectedButton === "gearButton") {
- ctx.strokeStyle = "black";
- ctx.lineWidth = 2;
- } else {
- ctx.strokeStyle = "blue";
- ctx.lineWidth = 4;
- }
- ctx.beginPath();
- ctx.moveTo(this.stroke[0].x, this.stroke[0].y);
- for (i = _l = 1, _ref2 = this.stroke.length; 1 <= _ref2 ? _l < _ref2 : _l > _ref2; i = 1 <= _ref2 ? ++_l : --_l) {
- ctx.lineTo(this.stroke[i].x, this.stroke[i].y);
- }
- ctx.stroke();
- ctx.restore();
- }
- if (this.areButtonsLoaded && this.shouldShowButtons()) {
- _ref3 = this.buttons;
- for (buttonName in _ref3) {
- if (!__hasProp.call(_ref3, buttonName)) continue;
- this.drawButton(ctx, this.buttons[buttonName]);
- }
- }
- if (this.message.length > 0) {
- ctx.save();
- ctx.fillStyle = this.messageColor;
- ctx.font = "bold 20px Arial";
- ctx.fillText(this.message, 20, 120);
- ctx.restore();
- }
- if (this.isDemoPlaying && this.pointerImage) {
- return this.drawDemoPointer(ctx, this.pointerLocation);
- }
- }
- };
-
- GearSketch.prototype.updateCanvasSize = function() {
- this.canvas.width = this.canvas.parentElement.getBoundingClientRect().width;
- this.canvas.height = this.canvas.parentElement.getBoundingClientRect().height;
- this.buttons["clearButton"].location.x = Math.max(this.canvas.width - 260, this.buttons["playButton"].location.x + 80);
- this.buttons["cloudButton"].location.x = this.buttons["clearButton"].location.x + 80;
- return this.buttons["helpButton"].location.x = this.buttons["cloudButton"].location.x + 80;
- };
-
- GearSketch.prototype.loadDemoMovements = function() {
- return this.demoMovements = [
- {
- from: this.getButtonCenter("helpButton"),
- to: this.getButtonCenter("gearButton"),
- atEnd: MovementAction.PEN_TAP,
- type: MovementType.STRAIGHT,
- duration: 2000
- }, {
- to: new Point(300, 200),
- type: MovementType.STRAIGHT,
- duration: 1500
- }, {
- atStart: MovementAction.PEN_DOWN,
- atEnd: MovementAction.PEN_UP,
- type: MovementType.CIRCLE,
- radius: 100,
- duration: 1500
- }, {
- to: new Point(500, 200),
- type: MovementType.STRAIGHT,
- duration: 1000
- }, {
- atStart: MovementAction.PEN_DOWN,
- atEnd: MovementAction.PEN_UP,
- type: MovementType.CIRCLE,
- radius: 40,
- duration: 1000
- }, {
- to: new Point(500, 240),
- type: MovementType.STRAIGHT,
- duration: 500
- }, {
- to: new Point(300, 300),
- atStart: MovementAction.PEN_DOWN,
- atEnd: MovementAction.PEN_UP,
- type: MovementType.STRAIGHT,
- duration: 1500
- }, {
- to: new Point(100, 180),
- type: MovementType.STRAIGHT,
- duration: 1000
- }, {
- atStart: MovementAction.PEN_DOWN,
- atEnd: MovementAction.PEN_UP,
- type: MovementType.CIRCLE,
- radius: 90,
- duration: 1000
- }, {
- to: new Point(100, 260),
- type: MovementType.STRAIGHT,
- duration: 500
- }, {
- to: new Point(180, 260),
- atStart: MovementAction.PEN_DOWN,
- atEnd: MovementAction.PEN_UP,
- type: MovementType.STRAIGHT,
- duration: 1500
- }, {
- to: new Point(550, 220),
- type: MovementType.STRAIGHT,
- duration: 1500
- }, {
- atStart: MovementAction.PEN_DOWN,
- atEnd: MovementAction.PEN_UP,
- type: MovementType.CIRCLE,
- radius: 80,
- duration: 1000
- }, {
- to: this.getButtonCenter("chainButton"),
- atEnd: MovementAction.PEN_TAP,
- type: MovementType.STRAIGHT,
- duration: 1500
- }, {
- to: new Point(280, 150),
- type: MovementType.STRAIGHT,
- duration: 1500
- }, {
- atStart: MovementAction.PEN_DOWN,
- type: MovementType.LEFT_HALF_CIRCLE,
- radius: 140,
- duration: 1500,
- pause: 0
- }, {
- to: new Point(600, 400),
- type: MovementType.STRAIGHT,
- duration: 1000,
- pause: 0
- }, {
- type: MovementType.RIGHT_HALF_CIRCLE,
- radius: 110,
- duration: 1000,
- pause: 0
- }, {
- to: new Point(280, 150),
- atEnd: MovementAction.PEN_UP,
- type: MovementType.STRAIGHT,
- duration: 1000
- }, {
- to: this.getButtonCenter("momentumButton"),
- atEnd: MovementAction.PEN_TAP,
- type: MovementType.STRAIGHT,
- duration: 1500
- }, {
- to: new Point(185, 180),
- type: MovementType.STRAIGHT,
- duration: 1500
- }, {
- to: new Point(150, 190),
- atStart: MovementAction.PEN_DOWN,
- atEnd: MovementAction.PEN_UP,
- type: MovementType.STRAIGHT,
- duration: 1000
- }, {
- to: this.getButtonCenter("playButton"),
- atEnd: MovementAction.PEN_TAP,
- type: MovementType.STRAIGHT,
- duration: 1500
- }, {
- to: this.getButtonCenter("chainButton"),
- atEnd: MovementAction.PEN_TAP,
- type: MovementType.STRAIGHT,
- duration: 3000
- }, {
- to: new Point(425, 250),
- type: MovementType.STRAIGHT,
- duration: 1000
- }, {
- to: new Point(525, 150),
- atStart: MovementAction.PEN_DOWN,
- atEnd: MovementAction.PEN_UP,
- type: MovementType.STRAIGHT,
- duration: 1000
- }, {
- to: this.getButtonCenter("gearButton"),
- atEnd: MovementAction.PEN_TAP,
- type: MovementType.STRAIGHT,
- duration: 1500
- }, {
- to: new Point(20, 250),
- type: MovementType.STRAIGHT,
- duration: 1000
- }, {
- to: new Point(650, 300),
- atStart: MovementAction.PEN_DOWN,
- atEnd: MovementAction.PEN_UP,
- type: MovementType.STRAIGHT,
- duration: 1500
- }, {
- to: new Point(425, 200),
- type: MovementType.STRAIGHT,
- duration: 1000
- }, {
- to: new Point(200, 400),
- atStart: MovementAction.PEN_DOWN,
- atEnd: MovementAction.PEN_UP,
- type: MovementType.STRAIGHT,
- duration: 1500
- }
- ];
- };
-
- GearSketch.prototype.getButtonCenter = function(buttonName) {
- var button, buttonCorner;
- button = this.buttons[buttonName];
- buttonCorner = new Point(button.location.x, button.location.y);
- return buttonCorner.plus(new Point(0.5 * button.width + button.padding, 0.5 * button.height + button.padding));
- };
-
- GearSketch.prototype.updateDemo = function(delta) {
- var movement;
- if (this.restTimer > 0) {
- this.restTimer = Math.max(this.restTimer - delta, 0);
- return;
- } else if (this.currentDemoMovement === this.demoMovements.length) {
- this.stopDemo();
- return;
- }
- movement = this.demoMovements[this.currentDemoMovement];
- if (this.movementCompletion === 0) {
- if (movement.from == null) {
- movement.from = this.pointerLocation;
- }
- if (movement.pause == null) {
- movement.pause = 500;
- }
- this.pointerLocation = movement.from.clone();
- if (movement.atStart === MovementAction.PEN_DOWN) {
- this.handlePenDown(this.pointerLocation.x, this.pointerLocation.y);
- }
- }
- if (this.movementCompletion < 1) {
- this.movementCompletion = Math.min(1, this.movementCompletion + delta / movement.duration);
- this.updatePointerLocation(movement, this.movementCompletion);
- this.handlePenMove(this.pointerLocation.x, this.pointerLocation.y);
- }
- if (this.movementCompletion === 1) {
- if (movement.atEnd === MovementAction.PEN_TAP) {
- this.handlePenDown(this.pointerLocation.x, this.pointerLocation.y);
- this.handlePenUp();
- } else if (movement.atEnd === MovementAction.PEN_UP) {
- this.handlePenUp();
- }
- this.restTimer = movement.pause;
- this.movementCompletion = 0;
- return this.currentDemoMovement++;
- }
- };
-
- GearSketch.prototype.updatePointerLocation = function(movement, movementCompletion) {
- var angle, center, delta;
- if (movement.type === MovementType.STRAIGHT) {
- delta = movement.to.minus(movement.from);
- return this.pointerLocation = movement.from.plus(delta.times(movementCompletion));
- } else if (movement.type === MovementType.CIRCLE) {
- center = new Point(movement.from.x, movement.from.y + movement.radius);
- return this.pointerLocation = center.plus(Point.polar(Math.PI - (movementCompletion - 0.25) * 2 * Math.PI, movement.radius));
- } else if (movement.type === MovementType.LEFT_HALF_CIRCLE) {
- center = new Point(movement.from.x, movement.from.y + movement.radius);
- angle = 1.5 * Math.PI - movementCompletion * Math.PI;
- return this.pointerLocation = center.plus(Point.polar(angle, movement.radius));
- } else if (movement.type === MovementType.RIGHT_HALF_CIRCLE) {
- center = new Point(movement.from.x, movement.from.y - movement.radius);
- angle = 0.5 * Math.PI - movementCompletion * Math.PI;
- return this.pointerLocation = center.plus(Point.polar(angle, movement.radius));
- }
- };
-
- GearSketch.prototype.playDemo = function() {
- this.loadDemoMovements();
- this.boardBackup = this.board.clone();
- this.board.clear();
- this.currentDemoMovement = 0;
- this.movementCompletion = 0;
- this.isDemoPlaying = true;
- return this.displayMessage("click anywhere to stop the demo");
- };
-
- GearSketch.prototype.stopDemo = function() {
- this.isDemoPlaying = false;
- this.restTimer = 0;
- this.stroke = [];
- this.selectedGear = null;
- this.selectedIcon = "gearIcon";
- this.board.restoreAfterDemo(this.boardBackup);
- return this.clearMessage();
- };
-
- GearSketch.prototype.boardUploaded = function(event) {
- parent.location.hash = event.target.responseText.trim();
- return this.displayMessage("Board saved. Share it by copying the text in your address bar.", "black", 4000);
- };
-
- GearSketch.prototype.uploadBoard = function() {
- var boardJSON,
- _this = this;
- boardJSON = JSON.stringify(this.board);
- return Util.sendPostRequest(boardJSON, "upload_board.php", (function(event) {
- return _this.boardUploaded(event);
- }));
- };
-
- return GearSketch;
-
- })();
-
- window.gearsketch.GearSketch = GearSketch;
-
- }).call(this);
-
- /*
- //@ sourceMappingURL=gearsketch_main.map
- */
|