From 7b9b937483b1107d28ee5a93750e55bfb292c64b Mon Sep 17 00:00:00 2001 From: dsc Date: Thu, 9 Dec 2010 14:09:26 -0800 Subject: [PATCH] Checkpoint on fixing the positioning mess. --- src/Y/class.cjs | 22 +++-- src/Y/core.cjs | 54 +++++++-- src/Y/delegate.cjs | 12 ++ src/Y/modules/metaclass.js | 2 +- src/Y/op.cjs | 4 +- src/Y/types/array.cjs | 28 ++--- src/evt.cjs | 30 +++-- src/ezl/layer.cjs | 107 +++++++++-------- src/ezl/loc/boundingbox.cjs | 53 +-------- src/ezl/math/rect.cjs | 66 ++++++----- src/ezl/shape/circle.cjs | 20 ++-- src/ezl/shape/line.cjs | 6 +- src/ezl/shape/polygon.cjs | 16 +++ src/ezl/shape/rect.cjs | 5 +- src/ezl/shape/shape.cjs | 18 +--- src/tanks/map/pathmap.cjs | 8 +- src/tanks/map/trajectory.cjs | 2 +- src/tanks/thing/player.cjs | 2 +- src/tanks/thing/tank.cjs | 4 +- test/math/index.php | 77 ------------ test/math/math.test.js | 251 ---------------------------------------- test/uki/index.php | 79 ------------- www/commonjs.php | 25 ++++ www/index.php | 28 +---- www/scripts.php | 12 ++ www/test | 1 - www/test/math/index.php | 71 +++++++++++ www/test/math/test-math.js | 251 ++++++++++++++++++++++++++++++++++++++++ www/test/shapes/index.php | 60 ++++++++++ www/test/shapes/test-shapes.js | 40 +++++++ www/test/uki/index.php | 79 +++++++++++++ 31 files changed, 787 insertions(+), 646 deletions(-) delete mode 100644 test/math/index.php delete mode 100644 test/math/math.test.js delete mode 100644 test/uki/index.php delete mode 100644 test/uki/test-uki.js create mode 100644 www/commonjs.php create mode 100644 www/scripts.php delete mode 120000 www/test create mode 100644 www/test/math/index.php create mode 100644 www/test/math/test-math.js create mode 100644 www/test/shapes/index.php create mode 100644 www/test/shapes/test-shapes.js create mode 100644 www/test/uki/index.php create mode 100644 www/test/uki/test-uki.js diff --git a/src/Y/class.cjs b/src/Y/class.cjs index 0aa02c8..2fc6520 100644 --- a/src/Y/class.cjs +++ b/src/Y/class.cjs @@ -14,8 +14,11 @@ var type = require('Y/type') , _String = globals.String , _Number = globals.Number -, hasOwn = _Object.prototype.hasOwnProperty +, P = 'prototype' +, hasOwn = _Object[P].hasOwnProperty , getProto = _Object.getPrototypeOf +, getDesc = _Object.getOwnPropertyDescriptor +, setDesc = _Object.defineProperty , KNOWN_CLASSES = type.type.KNOWN_CLASSES , classToString = function toString(){ return this.className+"()"; } @@ -56,7 +59,7 @@ function _Class() { * @param {Object} [members] Instance members to add to the new class's prototype; a class * constructor can be supplied as `init`. * - * @returns {Class} A new Class. + * @return {Class} A new Class. */ function Class(className, Parent, members) { var ClassFactory = arguments.callee @@ -81,7 +84,7 @@ function Class(className, Parent, members) { prototype = Parent; // Parent is a constructor: check ClassFactory - } else if (Parent.prototype instanceof ClassFactory) { + } else if (Parent[P] instanceof ClassFactory) { SuperClass = Parent; prototype = Parent.fabricate(); @@ -90,7 +93,7 @@ function Class(className, Parent, members) { return new ClassFactory(className, Parent, members); } else { - parentMembers = Parent.prototype || {}; + parentMembers = Parent[P] || {}; } // Creates a new function with the appropriate name @@ -109,13 +112,16 @@ function Class(className, Parent, members) { // Copy parent methods, then add new instance methods for (var k in parentMembers) - prototype[k] = parentMembers[k]; + if ( hasOwn.call(parentMembers,k) ) + setDesc(prototype, k, getDesc(parentMembers,k)); + else + prototype[k] = parentMembers[k]; if ( prototype.toString === toString ) prototype.toString = classToString; // Fix Constructors, prototypes - NewClass.prototype = NewClass.fn = prototype; + NewClass[P] = NewClass.fn = prototype; prototype.constructor = prototype.__class__ = NewClass; NewClass.__super__ = SuperClass; // don't override NewClass.constructor -- it should be Function NewClass.className = prototype.className = className; @@ -127,7 +133,7 @@ function Class(className, Parent, members) { // Or add new instance methods } else for (var k in members) { if ( hasOwn.call(members, k) ) - prototype[k] = members[k]; + setDesc(prototype, k, getDesc(members,k)); } if (prototype.init) NewClass.init = YFunction(prototype.init); @@ -139,7 +145,7 @@ function Class(className, Parent, members) { // Add metaprogramming data to Class object Class.__super__ = Object; -Class.fn = Class.prototype; +Class.fn = Class[P]; Class.fn.__class__ = Class; Class.className = Class.fn.className = "Class"; diff --git a/src/Y/core.cjs b/src/Y/core.cjs index 620723c..ded75cc 100644 --- a/src/Y/core.cjs +++ b/src/Y/core.cjs @@ -1,10 +1,19 @@ // Generic Collection Functions var undefined + , globals = (function(){ return this; })() +, _Object = globals.Object , _Function = globals.Function , _Array = globals.Array -, slice = _Array.prototype.slice + +, getProto = _Object.getPrototypeOf +, getDesc = _Object.getOwnPropertyDescriptor +, setDesc = _Object.defineProperty + +, P = 'prototype' +, hasOwn = _Object[P].hasOwnProperty +, slice = _Array[P].slice , type = require('Y/type') ; @@ -97,14 +106,41 @@ function extend( A, B ){ function extendall(A, donor){ return reduce(donor, attrvk, A); } function attrvk(o, v, k){ return attr(o, k, v, o[k]); } +/** + * Fetches the descriptor for each property that is an accessor (getter/setter). + * @param {Object} o Object for inspection. + * @return {Object} A map of property to descriptor. + * nb. An Array is safer, but: + * 1) Object.defineProperties takes an Object + * 2) That'd be much worse to work with + */ +function accessors(o){ + if ( !(o && typeof o === "object") ) + return {}; + return reduce(o, function(acc, v, k, obj){ + + // Ignore inherited properties + if ( !hasOwn.call(obj,k) ) + return acc; + + // Only yield accessors + var desc = getDesc(obj,k); + if ( !hasOwn.call(desc,'value') ) + acc[k] = desc; + + return acc; + }, {}); +} + -exports['reduce'] = reduce; -exports['map'] = map; -exports['forEach'] = forEach; -exports['filter'] = filter; +exports['reduce'] = reduce; +exports['map'] = map; +exports['forEach'] = forEach; +exports['filter'] = filter; -exports['set'] = set; -exports['attr'] = attr; -exports['extend'] = extend; +exports['set'] = set; +exports['attr'] = attr; +exports['extend'] = extend; -exports['slice'] = slice; +exports['accessors'] = accessors; +exports['slice'] = slice; diff --git a/src/Y/delegate.cjs b/src/Y/delegate.cjs index 8bc9e64..469a1e0 100644 --- a/src/Y/delegate.cjs +++ b/src/Y/delegate.cjs @@ -108,6 +108,15 @@ function extend( A, B ){ function extendall(A, donor){ return reduce(donor, attrvk, A); } function attrvk(o, v, k){ return attr(o, k, v, o[k]); } +function accessors(o){ + if ( !(o && typeof o === "object") ) + return {}; + + if ( notWrapped(o.accessors) ) + return o.accessors.apply(o, slice.call(arguments,1)); + + return core.accessors(o); +} exports['reduce'] = reduce; exports['map'] = map; @@ -117,3 +126,6 @@ exports['filter'] = filter; exports['set'] = set; exports['attr'] = attr; exports['extend'] = extend; + +exports['accessors'] = accessors; + diff --git a/src/Y/modules/metaclass.js b/src/Y/modules/metaclass.js index 3aebbbd..d4fdc85 100644 --- a/src/Y/modules/metaclass.js +++ b/src/Y/modules/metaclass.js @@ -112,7 +112,7 @@ function _Class() { * @param {Object} [members] Instance members to add to the new class's prototype; a class * constructor can be supplied as `init`. * - * @returns {Class} A new Class. + * @return {Class} A new Class. */ function Class(className, Parent, members){ var ClassFactory = arguments.callee diff --git a/src/Y/op.cjs b/src/Y/op.cjs index 3b2971c..769cab3 100644 --- a/src/Y/op.cjs +++ b/src/Y/op.cjs @@ -65,7 +65,9 @@ var core = require('Y/core') else return obj; }; - } + }, + + end : function end(o){ return ((o && o.__y__) ? o.end() : o); } }; diff --git a/src/Y/types/array.cjs b/src/Y/types/array.cjs index c9f11e8..0bd0b4f 100644 --- a/src/Y/types/array.cjs +++ b/src/Y/types/array.cjs @@ -1,6 +1,7 @@ var Y = require('Y/y').Y // I *think* this is safe , del = require('Y/delegate') , type = require('Y/type') +, op = require('Y/op') , mixin = require('Y/utils').mixin , YCollection = require('Y/types/collection').YCollection @@ -58,9 +59,6 @@ YCollection.subclass('YArray', function(YArray){ function concat( donor ){ var A = this._o; return new YArray(A.concat.apply( A, slice.call(arguments,0).map(unwrapY) )); - // return new YArray( slice.call(arguments).reduce(function(A, donor ){ - // return A.concat(donor instanceof YArray ? donor.end() : donor); - // }, this._o) ); }; this['extend'] = @@ -90,22 +88,18 @@ YCollection.subclass('YArray', function(YArray){ acc.push(v); return acc; }, new YArray(), this ); - - // return this.filter(function(v, i){ - // // Executes in the context of the new array, so - // // `this.indexOf` is checking what we've already - // // collected. - // return (this.indexOf(v) === -1); - // }); }; - // this.zip = - // function zip(){ - // var sequences = new YArray(slice.call(arguments)).map( Y.limit(1) ).unshift(this); - // return this.map(function(_, k){ - // return sequences.invoke('attr', k); - // }).invoke('end'); - // }; + this['zip'] = + function zip(){ + var sequences = new YArray(slice.call(arguments)).unshift(this._o) + , kget = op.curried.kget ; + return this.map(function(_, k){ + return sequences.map(function(seq){ + return del.attr(seq,k); + }); + }); //.invoke('end'); + }; /** * Like map, but produces a YObject: diff --git a/src/evt.cjs b/src/evt.cjs index 14b0090..345db7a 100644 --- a/src/evt.cjs +++ b/src/evt.cjs @@ -29,9 +29,14 @@ var Y = require('Y').Y , isFunction = Y.isFunction , KNOWN_CLASSES = Class.KNOWN_CLASSES = exports['KNOWN_CLASSES'] = {} -, getProto = Object.getPrototypeOf -, hasOwn = Object.prototype.hasOwnProperty -, objToString = Object.prototype.toString + +, P = 'prototype' +, _Object = Object +, hasOwn = _Object[P].hasOwnProperty +, getProto = _Object.getPrototypeOf +, getDesc = _Object.getOwnPropertyDescriptor +, setDesc = _Object.defineProperty + , classToString = function toString(){ return this.className+"()"; } ; @@ -77,7 +82,7 @@ function ConstructorTemplate() { * @param {Object} [members] Instance members to add to the new class's prototype; a class * constructor can be supplied as `init`. * - * @returns {Class} A new Class. + * @return {Class} A new Class. */ function Class(className, Parent, members){ var ClassFactory = arguments.callee @@ -133,9 +138,12 @@ function Class(className, Parent, members){ NewClass[k] = v; } - // Copy parent methods + // Copy parent methods, then add new instance methods for (var k in parentMembers) - prototype[k] = parentMembers[k]; + if ( hasOwn.call(parentMembers,k) ) + setDesc(prototype, k, getDesc(parentMembers,k)); + else + prototype[k] = parentMembers[k]; if ( prototype.toString === objToString ) prototype.toString = classToString; @@ -149,7 +157,7 @@ function Class(className, Parent, members){ NewClass.init = // XXX: This means subclasses will fire events. prototype.initialise = - function initialise(){ + Y(function initialise(){ var instance = this , init = NewClass.prototype.init ; @@ -168,7 +176,7 @@ function Class(className, Parent, members){ }); return instance; - }; + }); // Add class emitter var ParentEmitter = (Parent.__emitter__ ? Parent : ClassFactory) @@ -182,7 +190,7 @@ function Class(className, Parent, members){ // Or add new instance methods } else for (var k in members) { if ( hasOwn.call(members, k) ) - prototype[k] = members[k]; + setDesc(prototype, k, getDesc(members,k)); } // Record for metaprogramming @@ -215,8 +223,8 @@ Class.className = Class.fn.className = "Class"; * Create a new instance and run delegate constructor if it exists. * Unlike the keyword `new`, instantiate can be applied. */ -function instantiate(){ - var instance = this.fabricate(); +function instantiate(cls){ + var instance = cls.fabricate(); if ( instance.initialise ) instance.initialise.apply(instance, arguments); return instance; diff --git a/src/ezl/layer.cjs b/src/ezl/layer.cjs index 53f0f54..1111c0d 100644 --- a/src/ezl/layer.cjs +++ b/src/ezl/layer.cjs @@ -28,8 +28,9 @@ Y.subclass('Layer', { ctx : null, dirty : true, - canvasWidth : 0, layerWidth : 0, - canvasHeight : 0, layerHeight : 0, + + layerWidth : 0, canvasWidth : 0, + layerHeight : 0, canvasHeight : 0, x: 0, y: 0, loc : null, // Position relative to parent @@ -38,6 +39,7 @@ Y.subclass('Layer', { posBleed : null, // Loc // Transforms + _origin : null, // rotational origin transform : null, // Object useCanvasScaling : false, // default to CSS3 scaling @@ -53,8 +55,8 @@ Y.subclass('Layer', { this.boundingBox = new BoundingBox(0,0, 0,0); + this._origin = new Loc('50%','50%'); this.transform = { - origin : new Loc('50%','50%'), // rotational origin rotate : 0, scale : new Loc(1.0,1.0), translate : new Loc(0,0) // translates canvas @@ -120,7 +122,7 @@ Y.subclass('Layer', { }, /** - * @returns The root of the scene graph. + * @return The root of the scene graph. */ root : function root(){ if (this.parent) @@ -135,17 +137,7 @@ Y.subclass('Layer', { /// Attributes /// - - attr : function attr(key, value, def){ - if (!key) return this; - - if ( Y.isPlainObject(key) ) { - for (var k in key) - this.attr(k, key[k]); - return this; - } else - return Y.op.attr(this, key, value, def); - }, + attr : Y.attr.methodize(), /** * Changes the layer's width and then updates the canvas. @@ -155,16 +147,19 @@ Y.subclass('Layer', { return this.layerWidth; this.layerWidth = w; + + var origin = this._origin + , nb = this.negBleed + , v = this.canvasWidth = Math.ceil(w + nb.x + this.posBleed.x); // HTMLCanvas.width is a long + this.boundingBox = this.boundingBox.resize(w, this.layerHeight); + this.layer.width(w).css('margin-left', (-nb.x)+'px') - var nb = this.negBleed.x - , v = this.canvasWidth = Math.ceil(w + nb + this.posBleed.x); - this.layer.width(w).css('margin-left', (-nb)+'px') - this.canvas.width(v); - // this.canvas.css({ - // 'width' : v+'px', - // 'margin-left' : (-nb)+'px' - // }); + // this.canvas.width(v); + this.canvas.css({ + 'width' : v+'px', + 'margin-left' : (-nb)+'px' + }); this.canvas[0].width = v; @@ -176,10 +171,10 @@ Y.subclass('Layer', { return this.layerHeight; this.layerHeight = h; - this.boundingBox = this.boundingBox.resize(this.layerWidth, h); + this.boundingBox = this.boundingBox.resize(this.layerWidth, h); var nb = this.negBleed.y - , v = this.canvasHeight = Math.ceil(h + nb + this.posBleed.y); + , v = this.canvasHeight = Math.ceil(h + nb + this.posBleed.y); // HTMLCanvas.height is a long this.layer.height(h).css('margin-top', (-nb)+'px') this.canvas.height(v); // this.canvas.css({ @@ -192,35 +187,45 @@ Y.subclass('Layer', { }, /** - * position() -> object + * position() -> {Loc} * Gets position of the layer relative to the parent. + * @return {Loc} */ /** - * position(top, left) -> this + * position(x,y) -> {this} * Sets the position of this node, and then returns it. - * @param {Number|String|undefined} top If omitted, this method must be invoked with `undefined` as the first argument. - * @param {Number|String|undefined} left + * @param {Number|String|undefined} x + * @param {Number|String|undefined} y If omitted, this method must be invoked with `undefined` as the first argument. + * @return {this} */ /** - * position(pos) -> this + * position(pos) -> {this} * Sets the position of this node, and then returns it. - * @param {Object} pos An object with "top" and/or "left" properties as in `position(top, left)`. + * @param {Object} pos An object with "x" and/or "y" properties as in `position(x,y)`. + * @return {this} */ - position : function position(left, top){ - if (top === undefined && left === undefined) + position : function position(x,y){ + if (x === undefined && y === undefined) return this.layer.position(); - if (top && Y.isPlainObject(top)) - var pos = top; - else - var pos = { 'top': top, 'left':left }; + if ( Y.isPlainObject(x) ){ + y = x.y; + x = x.x; + } + + // if (pos.x !== undefined) pos.x -= this.offsetX; + // if (pos.y !== undefined) pos.y -= this.offsetY; - // if (pos.left !== undefined) pos.left -= this.offsetX; - // if (pos.top !== undefined) pos.top -= this.offsetY; + this.boundingBox = this.boundingBox.relocate(x,y); + this.loc = this.boundingBox.midpoint(); - this.boundingBox = this.boundingBox.add(pos.left,pos.top); - this.loc = this.boundingBox.p1; - this.css(pos); + var origin = this.origin(); + this.css({ + 'left' : x, + 'top' : y, + 'margin-left' : -origin.x, + 'margin-top' : -origin.y + }); return this; }, @@ -259,10 +264,11 @@ Y.subclass('Layer', { /// Transformations /// /** - * Gets and sets the transformation origin. + * Gets and sets the origin-location for this shape, used for + * position and rotation. Defaults to the midpoint. */ origin : function origin(x,y){ - var o = this.transform.origin; + var o = this._origin; if (arguments.length === 0) return o.absolute(this.layerWidth, this.layerHeight); @@ -323,15 +329,16 @@ Y.subclass('Layer', { tfns.push('scale('+t.scale.x+','+t.scale.y+')'); var trans = (tfns.length ? tfns.join(' ') : 'none') - , o = t.origin.toUnits() + , o = this._origin.toUnits('px') , origin = o.x+' '+o.y ; - this.layer.css( - ['', '-moz-', '-webkit-'].reduce( + this.layer.css(['', '-moz-', '-webkit-'] + .reduce( function(values, prefix){ values[prefix+'transform'] = trans; values[prefix+'transform-origin'] = origin; return values; - }, {}) ); + }, + {}) ); return this; }, @@ -482,8 +489,8 @@ Y.subclass('Layer', { /// Misc /// toString : function toString(){ - var pos = (this.layer ? this.position() : {top:NaN, left:NaN}); - return this.className+'['+pos.left+','+pos.top+']( children='+this.children.size()+' )'; + var pos = (this.layer ? this.position() : {y:NaN, x:NaN}); + return this.className+'['+pos.x+','+pos.y+']( children='+this.children.size()+' )'; } }); diff --git a/src/ezl/loc/boundingbox.cjs b/src/ezl/loc/boundingbox.cjs index f7ae7d5..7e17ea2 100644 --- a/src/ezl/loc/boundingbox.cjs +++ b/src/ezl/loc/boundingbox.cjs @@ -8,67 +8,20 @@ var Y = require('Y').Y BoundingBox = exports['BoundingBox'] = Rect.subclass('BoundingBox', { - init : function initBoundingBox(x1,y1, x2,y2){ - Rect.init.call(this, x1,y1, x2,y2); - - this.sides = { - top : new Line(x1,y1, x2,y1), - bottom : new Line(x1,y2, x2,y2), - left : new Line(x1,y1, x1,y2), - right : new Line(x2,y1, x2,y2) - }; - }, - - set : function set(k, v, def){ - v = (v !== undefined ? v : def); - - switch (k) { - case 'x1': case 0: case 'x': this.x1 = this[0] = this.x = v; break; - case 'y1': case 1: case 'y': this.y1 = this[1] = this.y = v; break; - case 'x2': case 2: this.x2 = this[2] = v; break; - case 'y1': case 3: this.y2 = this[3] = v; break; - - default: this[k] = v; - } - - this.width = this.x2 - this.x1; - this.height = this.y2 - this.y1; - - return this._updateSides(); - }, - - _updateSides : function _updateSides(){ - var s = this.sides - , x1 = this.x1, y1 = this.y1 - , x2 = this.x2, y2 = this.y2 - , dx1 = x1 !== s.top.x1, dy1 = y1 !== s.top.y1 - , dx2 = x2 !== s.top.x2, dy2 = y2 !== s.left.y2 - ; - - if ( dx1 || dy1 ) this.p1 = new Vec(x1,y1); - if ( dx2 || dy2 ) this.p2 = new Vec(x2,y2); - - if ( dx1 || dy1 || dx2 ) s.top = new Line(x1,y1, x2,y1); - if ( dx1 || dx2 || dy2 ) s.bottom = new Line(x1,y2, x2,y2); - if ( dx1 || dy1 || dy2 ) s.left = new Line(x1,y1, x1,y2); - if ( dy1 || dy2 || dx2 ) s.right = new Line(x2,y1, x2,y2); - - return this; - }, attr : Y.attr.methodize(), - add : function add(x,y){ + relocate : function relocate(x,y){ return new BoundingBox(x,y, x+this.width,y+this.height); }, resize : function resize(w,h){ - var x = this.x, y = this.y; + var x = this.x1, y = this.y1; return new BoundingBox(x,y, x+w,y+h); }, clone : function clone(){ - return new BoundingBox( this.p1.clone(), this.p2.clone() ); + return new BoundingBox(this[0],this[1], this[2],this[3]); } }); diff --git a/src/ezl/math/rect.cjs b/src/ezl/math/rect.cjs index c5e8794..8420caa 100644 --- a/src/ezl/math/rect.cjs +++ b/src/ezl/math/rect.cjs @@ -2,44 +2,52 @@ var Y = require('Y').Y , Vec = require('ezl/math/vec').Vec , + Rect = exports['Rect'] = Y.subclass('Rect', [], { - init : function initRect(x1,y1, x2,y2){ - if (x1 instanceof Array && y1 instanceof Array) { - y2 = y1[1]; x2 = y1[0]; - y1 = x1[1]; x1 = x1[0]; + init : function initRect(_x1,_y1, _x2,_y2){ + if (_x1 instanceof Array && _y1 instanceof Array) { + _y2 = _y1[1]; _x2 = _y1[0]; + _y1 = _x1[1]; _x1 = _x1[0]; } - // init : function initRect(_x1,_y1, _x2,_y2){ - // if (_x1 instanceof Array && _y1 instanceof Array) { - // _y2 = _y1[1]; _x2 = _y1[0]; - // _y1 = _x1[1]; _x1 = _x1[0]; - // } - // var x1 = Math.min(_x1,_x2), x2 = Math.max(_x1,_x2) - // , y1 = Math.min(_y1,_y2), y2 = Math.max(_y1,_y2); + var x1 = Math.min(_x1,_x2), x2 = Math.max(_x1,_x2) + , y1 = Math.min(_y1,_y2), y2 = Math.max(_y1,_y2); this.length = 4; - this.x1 = this[0] = this.x = x1; - this.y1 = this[1] = this.y = y1; - this.x2 = this[2] = x2; - this.y2 = this[3] = y2; - - this.width = x2 - x1; - this.height = y2 - y1; - - this.p1 = new Vec(x1,y1); - this.p2 = new Vec(x2,y2); + this[0] = x1; this[1] = y1; + this[2] = x2; this[3] = y2; + }, + + get x1(){ return this[0]; }, set x1(v){ this[0] = v; }, + get y1(){ return this[1]; }, set y1(v){ this[1] = v; }, + get x2(){ return this[2]; }, set x2(v){ this[2] = v; }, + get y2(){ return this[3]; }, set y2(v){ this[3] = v; }, + + get p1(){ return new Vec(this[0],this[1]); }, + set p1(v){ this[0] = v.x; this[1] = this.y }, + get p2(){ return new Vec(this[2],this[3]); }, + set p2(v){ this[2] = v.x; this[3] = this.y }, + + // TODO: .origin + // TODO: Scale w/h proportionally if .origin is percentage + get width(){ return this[2] - this[0]; }, + get height(){ return this[3] - this[1]; }, + + get midpoint(){ + return new Vec( this[0] + (this[2]-this[0]) / 2 + , this[1] + (this[3]-this[1]) / 2 ); }, contains : function contains(x,y){ - return ( x >= this.x1 && x <= this.x2 && - y >= this.y1 && y <= this.y2 ); + return ( x >= this[0] && x <= this[2] && + y >= this[1] && y <= this[3] ); }, intersects : function intersects(line){ - var x1 = Math.min(this.x1,this.x2), x2 = Math.max(this.x1,this.x2) - , y1 = Math.min(this.y1,this.y2), y2 = Math.max(this.y1,this.y2) + var x1 = this[0], x2 = this[2] + , y1 = this[1], y2 = this[3] , cx1,cy1, cx2,cy2 ; return ( ( (cx1 = line.calcX(y1)) >= x1 && cx1 <= x2 ) || ( (cy1 = line.calcY(x1)) >= y1 && cy1 <= y2 ) @@ -47,14 +55,8 @@ Y.subclass('Rect', [], { || ( (cy2 = line.calcY(x2)) >= y1 && cy2 <= y2 ) ); }, - midpoint : function midpoint(){ - return new Vec( this.x1 + this.width /2 - , this.y1 + this.height/2 ); - }, - clone : function clone(){ - return new Rect( this.p1.clone() - , this.p2.clone() ); + return new Rect(this[0],this[1], this[2],this[3]); }, toString : function toString(){ diff --git a/src/ezl/shape/circle.cjs b/src/ezl/shape/circle.cjs index 8e61bf6..00acd8b 100644 --- a/src/ezl/shape/circle.cjs +++ b/src/ezl/shape/circle.cjs @@ -7,20 +7,24 @@ exports['Circle'] = Shape.subclass('Circle', { _cssClasses : 'ezl layer shape circle', - init : function initCircle(radius, centerTL){ + init : function initCircle(radius){ Shape.init.call(this); + this.radius(radius); + }, + + radius : function radius(r){ + if (r === undefined) + return this._radius; - var d = radius * 2; - this.radius = radius; - if (!centerTL) - this.negBleed.x = this.negBleed.y = radius; + var d = r * 2; + this.dirty = true; + this._radius = r; this.width(d).height(d); - // .origin(radius,radius); + return this; }, drawShape : function drawShape(ctx){ - var r = this.radius, nb = this.negBleed; - ctx.arc(r-nb.x,r-nb.y, r, 0, Math.PI*2, false); + ctx.arc(0,0, this._radius, 0, Math.PI*2, false); ctx.fill(); ctx.stroke(); } diff --git a/src/ezl/shape/line.cjs b/src/ezl/shape/line.cjs index 9de4298..34bc660 100644 --- a/src/ezl/shape/line.cjs +++ b/src/ezl/shape/line.cjs @@ -1,9 +1,9 @@ //#ensure "jquery" -var Y = require('Y').Y +var Y = require('Y').Y +, math = require('ezl/math') , Layer = require('ezl/layer').Layer , Shape = require('ezl/shape/shape').Shape -, math = require('ezl/math') , Line = @@ -46,7 +46,7 @@ Shape.subclass('Line', { }, origin : function origin(x,y){ - var o = this.transform.origin; + var o = this._origin; if (arguments.length === 0) return o.absolute(this.layerWidth, this.layerHeight); diff --git a/src/ezl/shape/polygon.cjs b/src/ezl/shape/polygon.cjs index 80254fb..5b51520 100644 --- a/src/ezl/shape/polygon.cjs +++ b/src/ezl/shape/polygon.cjs @@ -1,3 +1,5 @@ +// FIXME: Origin and Bleeds are busted for Polygons that want negative coords + var Y = require('Y').Y , Shape = require('ezl/shape/shape').Shape , Loc = require('ezl/loc').Loc @@ -27,6 +29,20 @@ Shape.subclass('Polygon', { // .origin(w/2, h/2); }, + _calcDimension : function _calcDimension(which, values){ + values.unshift(0); + var self = this + , neg = -1 * Math.min.apply(Math, values) + // , pos = Math.min(0, Math.max.apply(Max, values) - max) + ; + + // XXX: Busted + self.negBleed.attr(which, neg); + // self.posBleed.attr(which, pos); + + return values.map(function(v, i){ return (self[which+i] = v); }); + }, + drawShape : function drawShape(ctx){ this.points.forEach(function(loc, i){ ctx.lineTo(loc.x, loc.y); diff --git a/src/ezl/shape/rect.cjs b/src/ezl/shape/rect.cjs index 6222886..563a441 100644 --- a/src/ezl/shape/rect.cjs +++ b/src/ezl/shape/rect.cjs @@ -8,8 +8,9 @@ Shape.subclass('Rect', { init : function initRect(w,h){ Shape.init.call(this); - this.width(w).height(h); - // .origin(w/2, h/2); + this.origin(0,0) + .width(w) + .height(h); }, drawShape : function drawShape(ctx){ diff --git a/src/ezl/shape/shape.cjs b/src/ezl/shape/shape.cjs index 1c3aa8c..9e84fcc 100644 --- a/src/ezl/shape/shape.cjs +++ b/src/ezl/shape/shape.cjs @@ -6,24 +6,10 @@ Shape = exports['Shape'] = Layer.subclass('Shape', { _cssClasses : 'ezl layer shape', + fillStyle : 'rgba(231,48,117, 1)', strokeStyle : 'transparent', - lineWidth : 0, - - _calcDimension : function _calcDimension(which, values){ - values.unshift(0); - var self = this - , neg = -1 * Math.min.apply(Math, values) - // , pos = Math.min(0, Math.max.apply(Max, values) - max) - ; - - self.negBleed.attr(which, neg); - // self.posBleed.attr(which, pos); - - return values.map(function(v, i){ - return (self[which+i] = v); - }); - } + lineWidth : 0 }); diff --git a/src/tanks/map/pathmap.cjs b/src/tanks/map/pathmap.cjs index 90bb5ba..56c90b0 100644 --- a/src/tanks/map/pathmap.cjs +++ b/src/tanks/map/pathmap.cjs @@ -101,22 +101,22 @@ QuadTree.subclass('PathMap', { var B = blocker.boundingBox; if (bb.x2 <= B.x1 && x2 >= B.x1) { msg += 'left'; - side = B.sides.left; + side = new Line(B.x1,B.y1, B.x1,B.y2); to = trj.pointAtX(B.x1-bw-offX-1); } else if (bb.x1 >= B.x2 && x1 <= B.x2) { msg += 'right'; - side = B.sides.right; + side = new Line(B.x2,B.y1, B.x2,B.y2); to = trj.pointAtX(B.x2-offX+1); } else if (bb.y2 <= B.y1 && y2 >= B.y1) { msg += 'top'; - side = B.sides.top; + side = new Line(B.x1,B.y1, B.x2,B.y1); to = trj.pointAtY(B.y1-bh-offY-1); } else if (bb.y1 >= B.y2 && y1 <= B.y2) { msg += 'bottom'; - side = B.sides.bottom; + side = new Line(B.x1,B.y2, B.x2,B.y2); to = trj.pointAtY(B.y2-offY+1); } diff --git a/src/tanks/map/trajectory.cjs b/src/tanks/map/trajectory.cjs index fa38fc0..f406acc 100644 --- a/src/tanks/map/trajectory.cjs +++ b/src/tanks/map/trajectory.cjs @@ -79,7 +79,7 @@ Line.subclass('Trajectory', { * Compares how distant in the future two objects are on this trajectory. * Objects that have been passed are always further away than those in the future, * but otherwise the comparison is performed by absolute distance. - * @returns -1 if a closer b, 1 if a further b, 0 if a same as b + * @return -1 if a closer b, 1 if a further b, 0 if a same as b */ compare : function compare(a, b){ if (a instanceof Thing) a = a.midpoint; diff --git a/src/tanks/thing/player.cjs b/src/tanks/thing/player.cjs index d330055..64f9125 100644 --- a/src/tanks/thing/player.cjs +++ b/src/tanks/thing/player.cjs @@ -90,7 +90,7 @@ Tank.subclass('PlayerTank', { var toLoc = this.loc.moveByDir(dir, (this.stats.move * SQUARETH)) , x = toLoc.x, y = toLoc.y - , bb = this.boundingBox.add(x,y) + , bb = this.boundingBox.reloacte(x,y) , blockers = this.game.pathmap.get(bb.x1,bb.y1, bb.x2,bb.y2).remove(this) ; diff --git a/src/tanks/thing/tank.cjs b/src/tanks/thing/tank.cjs index c166ff5..2be964d 100644 --- a/src/tanks/thing/tank.cjs +++ b/src/tanks/thing/tank.cjs @@ -427,8 +427,8 @@ Thing.subclass('Tank', function(Tank){ .appendTo( parent ) ; this.turret = - new Circle(r, true) - .position(w2-r, h2-r) + new Circle(r) + .position(w2, h2) .fill(this.turretColor) .appendTo( this.shape ) ; diff --git a/test/math/index.php b/test/math/index.php deleted file mode 100644 index 830a32c..0000000 --- a/test/math/index.php +++ /dev/null @@ -1,77 +0,0 @@ - - - -math - - - - -
-
- -
-
- - - ( , ) - ( , ) - -
-

-    
- -
-

Trigonometry and Reflection Test

-
    -
  • The main line is pink (and the light-orange line is its tangent).
  • -
  • Click anywhere to add a point. It will be purple, and its reflection in the main line will be orange.
  • -
  • You can drag the blue control points of the main line to change it.
  • -
-
-
- -
- -
- - \ No newline at end of file diff --git a/test/math/math.test.js b/test/math/math.test.js deleted file mode 100644 index 237ac71..0000000 --- a/test/math/math.test.js +++ /dev/null @@ -1,251 +0,0 @@ -PPU = 25; -PX = 2.5/PPU; - -$(function(){ - -plot = $('#plot'); - -w = plot.width(); w2 = w/2; -h = plot.height(); h2 = h/2; -COLS = w/PPU; COLS2 = COLS/2; -ROWS = h/PPU; ROWS2 = ROWS/2; - -grid = new Grid( COLS, ROWS, PPU ).appendTo(plot); -grid.createTableGrid = false; -grid.lineWidth = 1.0; -grid.strokeStyle = '#E0E0E0'; //'#EEEEEE'; // -grid.draw(); - -// Draw axes -ctx = grid.ctx; -drawLine(-w,-h2, w, -h2, '#CCCCCC', 2.0); -drawLine(w2,-h, w2, h, '#CCCCCC', 2.0); - -P = new Layer() - .width(w).height(h) - .appendTo(grid); - -ctx = P.ctx; -ctx.translate(w2, h2); -ctx.scale(PPU, PPU); - - -r = new Loc.Rect(2,6, 4,2); -R = Rect.fromPoints(r.x1*PPU,-r.y1*PPU, r.x2*PPU,-r.y2*PPU) - .fill('rgba(131,187,50, 0.5)') - .appendTo(P); -R.position(R.loc.x+w2, R.loc.y+h2); - -points = Y([]); -line = mkLine(0,0, 2.3125,1); -addPoint(-5,2); - -dragging = false; - -P.layer.bind('click', function(evt){ - if (!dragging) { - var v = convertLoc(evt); - addPoint(v.x,v.y); - } - return false; -}); - - -$('form#line, #line input').bind('submit blur', function(evt){ - var x1 = parseFloat($('#info [name=x1]').val()) - , y1 = parseFloat($('#info [name=y1]').val()) - , x2 = parseFloat($('#info [name=x2]').val()) - , y2 = parseFloat($('#info [name=y2]').val()) - ; - - if ( !(isNaN(x1) || isNaN(y1)) && (line.x1 !== x1 || line.y1 !== y1) ) - mvLine(1, x1,y1); - - if ( !(isNaN(x2) || isNaN(y2)) && (line.x2 !== x2 || line.y2 !== y2) ) - mvLine(2, x2,y2); - - return false; -}); - - -}); - -function updateInfo(){ - $('#info [name=x1]').val(line.x1); - $('#info [name=y1]').val(line.y1); - $('#info [name=x2]').val(line.x2); - $('#info [name=y2]').val(line.y2); - $('#info #inter').text([ 'rect:'+r, 'rect.intersects(line)? '+r.intersects(line) ].join('\n')); -} - -function redraw(color){ - color = color || 'rgba(231,48,117, 0.5)'; - var pts = points.clone(); - clear(); - - // drawAngle(line.theta); - - // drawLine(-COLS, line.calcY(-COLS), COLS, line.calcY(COLS), color); - // drawLine(-COLS, tan.calcY(-COLS), COLS, tan.calcY(COLS), 'rgba(226,127,8, 0.2)'); - - P.append(oline, otan, p1, p2).draw(); - bindPoint(p1, 1); - bindPoint(p2, 2); - - pts.forEach(addPoint); - - updateInfo(); -} - -function addPoint(x,y){ - if (x instanceof Shape) { - var c = x; - removePoint(c); - P.append(x); - } else { - var v = new math.Vec(x,y) - , c = drawPoint(v, null, '#552F74'); - } - - var rv = math.reflect(c.vec,line) - , rc = c.reflected = drawPoint(rv, null, '#F25522'); - points.push(c); - return c; -} - -function removePoint(c){ - if (c.reflected) c.reflected.remove(); - points.remove(c); - c.remove(); -} - -function mkLine(x1,y1, x2,y2){ - var lcolor = 'rgba(231,48, 117, 0.5)' - , tcolor = 'rgba(226,127,8, 0.5)' - , pcolor = 'rgba(69, 150,255, 1.0)'; - - if (window.oline) oline.remove(); - oline = Line.fromPoints(x1,y1, x2,y2) - .attr('invertY', true) - .stroke(lcolor, PX) - .translate(COLS2, ROWS2) - .scale(PPU, PPU); - line = oline.line; - oline.layer.attr('title', line+''); - - if (window.otan) otan.remove(); - tan = line.tangent(line.p2); - otan = Line.fromPoints(tan.x1,tan.y1, tan.x2,tan.y2) - .attr('invertY', true) - .stroke(tcolor, PX) - .translate(COLS2, ROWS2) - .scale(PPU, PPU); - otan.layer.attr('title', tan+''); - - if (window.p1) p1.remove(); - p1 = drawPoint(line.x1, line.y1, pcolor); - - if (window.p2) p2.remove(); - p2 = drawPoint(line.x2, line.y2, pcolor); - - p1.layer.add(p2.layer).addClass('handle'); - redraw(); - - return line; -} - -function bindPoint(pt, pn){ - pt.layer.bind('mousedown', function(){ - dragging = true; - function onMove(evt){ - var r = 3.75, v = convertLoc(evt); - mvLine(pn, v.x,v.y); - return false; - } - P.layer.bind('mousemove', onMove); - P.layer.bind('mouseup', function(evt){ - dragging = false; - P.layer.unbind('mousemove', onMove); - P.layer.unbind('mouseup', arguments.callee); - return false; - }); - return false; - }); - return pt; -} -function convertLoc(evt){ - var off = P.layer.offset() - , x = (evt.pageX - off.left - w2)/PPU - , y = (evt.pageY - off.top - h2)/PPU * -1; - return new math.Vec(x,y); -} - -function clear(){ - ctx.clearRect(-2*w,-2*h, 4*w,4*h); - points.forEach(removePoint); - p1.remove(); p2.remove(); -} - -function mvLine(pn, x,y){ - var x1 = (pn === 1 ? x : line.x1) - , y1 = (pn === 1 ? y : line.y1) - , x2 = (pn === 2 ? x : line.x2) - , y2 = (pn === 2 ? y : line.y2) - ; - mkLine(x1,y1, x2,y2); -} - - - - - - -function drawLine(x1,y1, x2,y2, color, width){ - try { - ctx.beginPath(); - ctx.lineWidth = width || PX; - ctx.strokeStyle = color || '#000000'; - ctx.moveTo(x1, -y1); - ctx.lineTo(x2, -y2); - ctx.stroke(); - ctx.closePath(); - } catch (e) { - window.console && console.log('drawLine error:', e, '(',x1,y1,')', '(',x2,y2,')'); - } -} - -function drawPoint(x,y, color, r){ - r = r || 3.75; - if (x instanceof math.Vec) { - var v = x; - x = v.x; - y = v.y; - } else - var v = new math.Vec(x,y); - - var c = new Circle(r) - .position(w2 + x*PPU, h2 - y*PPU) - .attr({ - 'strokeStyle' : 'transparent', - 'fillStyle' : color || 'rgba(0,0,0,0.5)' - }) - .appendTo(P) - .draw(); - - c.vec = v; - c.layer.attr('title', '('+x+','+y+')'); - return c; -} - -function drawAngle(theta, radius){ - radius = radius || 3; - ctx.beginPath(); - ctx.strokeStyle = 'transparent'; - ctx.fillStyle = 'rgba(36,71,146, 0.25)'; - ctx.moveTo(0,0); - ctx.lineTo(radius,0); - ctx.arc(0,0, radius, 0, -theta, true); - ctx.lineTo(0,0); - ctx.fill(); - ctx.closePath(); -} diff --git a/test/uki/index.php b/test/uki/index.php deleted file mode 100644 index d71bc76..0000000 --- a/test/uki/index.php +++ /dev/null @@ -1,79 +0,0 @@ - - - -uki test - - - - -
-
- -
-
- - - ( , ) - ( , ) - -
-

-    
- -
-

Trigonometry and Reflection Test

-
    -
  • The main line is pink (and the light-orange line is its tangent).
  • -
  • Click anywhere to add a point. It will be purple, and its reflection in the main line will be orange.
  • -
  • You can drag the blue control points of the main line to change it.
  • -
-
-
- -
- -
- - \ No newline at end of file diff --git a/test/uki/test-uki.js b/test/uki/test-uki.js deleted file mode 100644 index e69de29..0000000 diff --git a/www/commonjs.php b/www/commonjs.php new file mode 100644 index 0000000..e9af8be --- /dev/null +++ b/www/commonjs.php @@ -0,0 +1,25 @@ +&1"); +} diff --git a/www/index.php b/www/index.php index 1c125f0..7d9be22 100644 --- a/www/index.php +++ b/www/index.php @@ -1,23 +1,7 @@ - -
-&1"); - echo "\n-->\n"; - - include "deps.html"; -?> -
- - +require 'header.html'; +require 'welcome.html'; +require 'game.html'; +require 'debug.html'; +require 'scripts.php'; +require 'footer.html'; diff --git a/www/scripts.php b/www/scripts.php new file mode 100644 index 0000000..a7e0016 --- /dev/null +++ b/www/scripts.php @@ -0,0 +1,12 @@ +
+$errors"; + +// Precompiled dependency list +require "deps.html"; + +?> +
\ No newline at end of file diff --git a/www/test b/www/test deleted file mode 120000 index 419df4f..0000000 --- a/www/test +++ /dev/null @@ -1 +0,0 @@ -../test \ No newline at end of file diff --git a/www/test/math/index.php b/www/test/math/index.php new file mode 100644 index 0000000..14a3dda --- /dev/null +++ b/www/test/math/index.php @@ -0,0 +1,71 @@ + + + +math + + + + +
+
+ +
+
+ + + ( , ) + ( , ) + +
+

+    
+ +
+

Trigonometry and Reflection Test

+
    +
  • The main line is pink (and the light-orange line is its tangent).
  • +
  • Click anywhere to add a point. It will be purple, and its reflection in the main line will be orange.
  • +
  • You can drag the blue control points of the main line to change it.
  • +
+
+
+ +
+ +
+ + + \ No newline at end of file diff --git a/www/test/math/test-math.js b/www/test/math/test-math.js new file mode 100644 index 0000000..237ac71 --- /dev/null +++ b/www/test/math/test-math.js @@ -0,0 +1,251 @@ +PPU = 25; +PX = 2.5/PPU; + +$(function(){ + +plot = $('#plot'); + +w = plot.width(); w2 = w/2; +h = plot.height(); h2 = h/2; +COLS = w/PPU; COLS2 = COLS/2; +ROWS = h/PPU; ROWS2 = ROWS/2; + +grid = new Grid( COLS, ROWS, PPU ).appendTo(plot); +grid.createTableGrid = false; +grid.lineWidth = 1.0; +grid.strokeStyle = '#E0E0E0'; //'#EEEEEE'; // +grid.draw(); + +// Draw axes +ctx = grid.ctx; +drawLine(-w,-h2, w, -h2, '#CCCCCC', 2.0); +drawLine(w2,-h, w2, h, '#CCCCCC', 2.0); + +P = new Layer() + .width(w).height(h) + .appendTo(grid); + +ctx = P.ctx; +ctx.translate(w2, h2); +ctx.scale(PPU, PPU); + + +r = new Loc.Rect(2,6, 4,2); +R = Rect.fromPoints(r.x1*PPU,-r.y1*PPU, r.x2*PPU,-r.y2*PPU) + .fill('rgba(131,187,50, 0.5)') + .appendTo(P); +R.position(R.loc.x+w2, R.loc.y+h2); + +points = Y([]); +line = mkLine(0,0, 2.3125,1); +addPoint(-5,2); + +dragging = false; + +P.layer.bind('click', function(evt){ + if (!dragging) { + var v = convertLoc(evt); + addPoint(v.x,v.y); + } + return false; +}); + + +$('form#line, #line input').bind('submit blur', function(evt){ + var x1 = parseFloat($('#info [name=x1]').val()) + , y1 = parseFloat($('#info [name=y1]').val()) + , x2 = parseFloat($('#info [name=x2]').val()) + , y2 = parseFloat($('#info [name=y2]').val()) + ; + + if ( !(isNaN(x1) || isNaN(y1)) && (line.x1 !== x1 || line.y1 !== y1) ) + mvLine(1, x1,y1); + + if ( !(isNaN(x2) || isNaN(y2)) && (line.x2 !== x2 || line.y2 !== y2) ) + mvLine(2, x2,y2); + + return false; +}); + + +}); + +function updateInfo(){ + $('#info [name=x1]').val(line.x1); + $('#info [name=y1]').val(line.y1); + $('#info [name=x2]').val(line.x2); + $('#info [name=y2]').val(line.y2); + $('#info #inter').text([ 'rect:'+r, 'rect.intersects(line)? '+r.intersects(line) ].join('\n')); +} + +function redraw(color){ + color = color || 'rgba(231,48,117, 0.5)'; + var pts = points.clone(); + clear(); + + // drawAngle(line.theta); + + // drawLine(-COLS, line.calcY(-COLS), COLS, line.calcY(COLS), color); + // drawLine(-COLS, tan.calcY(-COLS), COLS, tan.calcY(COLS), 'rgba(226,127,8, 0.2)'); + + P.append(oline, otan, p1, p2).draw(); + bindPoint(p1, 1); + bindPoint(p2, 2); + + pts.forEach(addPoint); + + updateInfo(); +} + +function addPoint(x,y){ + if (x instanceof Shape) { + var c = x; + removePoint(c); + P.append(x); + } else { + var v = new math.Vec(x,y) + , c = drawPoint(v, null, '#552F74'); + } + + var rv = math.reflect(c.vec,line) + , rc = c.reflected = drawPoint(rv, null, '#F25522'); + points.push(c); + return c; +} + +function removePoint(c){ + if (c.reflected) c.reflected.remove(); + points.remove(c); + c.remove(); +} + +function mkLine(x1,y1, x2,y2){ + var lcolor = 'rgba(231,48, 117, 0.5)' + , tcolor = 'rgba(226,127,8, 0.5)' + , pcolor = 'rgba(69, 150,255, 1.0)'; + + if (window.oline) oline.remove(); + oline = Line.fromPoints(x1,y1, x2,y2) + .attr('invertY', true) + .stroke(lcolor, PX) + .translate(COLS2, ROWS2) + .scale(PPU, PPU); + line = oline.line; + oline.layer.attr('title', line+''); + + if (window.otan) otan.remove(); + tan = line.tangent(line.p2); + otan = Line.fromPoints(tan.x1,tan.y1, tan.x2,tan.y2) + .attr('invertY', true) + .stroke(tcolor, PX) + .translate(COLS2, ROWS2) + .scale(PPU, PPU); + otan.layer.attr('title', tan+''); + + if (window.p1) p1.remove(); + p1 = drawPoint(line.x1, line.y1, pcolor); + + if (window.p2) p2.remove(); + p2 = drawPoint(line.x2, line.y2, pcolor); + + p1.layer.add(p2.layer).addClass('handle'); + redraw(); + + return line; +} + +function bindPoint(pt, pn){ + pt.layer.bind('mousedown', function(){ + dragging = true; + function onMove(evt){ + var r = 3.75, v = convertLoc(evt); + mvLine(pn, v.x,v.y); + return false; + } + P.layer.bind('mousemove', onMove); + P.layer.bind('mouseup', function(evt){ + dragging = false; + P.layer.unbind('mousemove', onMove); + P.layer.unbind('mouseup', arguments.callee); + return false; + }); + return false; + }); + return pt; +} +function convertLoc(evt){ + var off = P.layer.offset() + , x = (evt.pageX - off.left - w2)/PPU + , y = (evt.pageY - off.top - h2)/PPU * -1; + return new math.Vec(x,y); +} + +function clear(){ + ctx.clearRect(-2*w,-2*h, 4*w,4*h); + points.forEach(removePoint); + p1.remove(); p2.remove(); +} + +function mvLine(pn, x,y){ + var x1 = (pn === 1 ? x : line.x1) + , y1 = (pn === 1 ? y : line.y1) + , x2 = (pn === 2 ? x : line.x2) + , y2 = (pn === 2 ? y : line.y2) + ; + mkLine(x1,y1, x2,y2); +} + + + + + + +function drawLine(x1,y1, x2,y2, color, width){ + try { + ctx.beginPath(); + ctx.lineWidth = width || PX; + ctx.strokeStyle = color || '#000000'; + ctx.moveTo(x1, -y1); + ctx.lineTo(x2, -y2); + ctx.stroke(); + ctx.closePath(); + } catch (e) { + window.console && console.log('drawLine error:', e, '(',x1,y1,')', '(',x2,y2,')'); + } +} + +function drawPoint(x,y, color, r){ + r = r || 3.75; + if (x instanceof math.Vec) { + var v = x; + x = v.x; + y = v.y; + } else + var v = new math.Vec(x,y); + + var c = new Circle(r) + .position(w2 + x*PPU, h2 - y*PPU) + .attr({ + 'strokeStyle' : 'transparent', + 'fillStyle' : color || 'rgba(0,0,0,0.5)' + }) + .appendTo(P) + .draw(); + + c.vec = v; + c.layer.attr('title', '('+x+','+y+')'); + return c; +} + +function drawAngle(theta, radius){ + radius = radius || 3; + ctx.beginPath(); + ctx.strokeStyle = 'transparent'; + ctx.fillStyle = 'rgba(36,71,146, 0.25)'; + ctx.moveTo(0,0); + ctx.lineTo(radius,0); + ctx.arc(0,0, radius, 0, -theta, true); + ctx.lineTo(0,0); + ctx.fill(); + ctx.closePath(); +} diff --git a/www/test/shapes/index.php b/www/test/shapes/index.php new file mode 100644 index 0000000..f77f097 --- /dev/null +++ b/www/test/shapes/index.php @@ -0,0 +1,60 @@ + + + +shapes + + + + +
+
+ +
+

Trigonometry and Reflection Test

+
    +
  • The main line is pink (and the light-orange line is its tangent).
  • +
  • Click anywhere to add a point. It will be purple, and its reflection in the main line will be orange.
  • +
  • You can drag the blue control points of the main line to change it.
  • +
+
+
+ +
+ +
+ + + \ No newline at end of file diff --git a/www/test/shapes/test-shapes.js b/www/test/shapes/test-shapes.js new file mode 100644 index 0000000..0fa526b --- /dev/null +++ b/www/test/shapes/test-shapes.js @@ -0,0 +1,40 @@ +REF_SIZE = 50; + +Y = require('Y').Y; +ezl = require('ezl'); +shape = require('ezl/shape'); +Grid = require('tanks/ui/grid').Grid; + + + +$(function(){ + el = $('#plot'); + + w = el.width(); w2 = w/2; + h = el.height(); h2 = h/2; + COLS = w/REF_SIZE; COLS2 = COLS/2; + ROWS = h/REF_SIZE; ROWS2 = ROWS/2; + + grid = new Grid( COLS, ROWS, REF_SIZE ).appendTo(el); + grid.createTableGrid = false; + grid.lineWidth = 1.0; + grid.strokeStyle = '#E0E0E0'; //'#EEEEEE'; // + grid.draw(); + + // Draw axes + shape.Line // X Axis + .fromPoints(-w,-h2, w,-h2) + .stroke('#CCCCCC', 2.0) + .appendTo(grid); + shape.Line // Y Axis + .fromPoints(w2,-h, w2,h) + .stroke('#CCCCCC', 2.0) + .appendTo(grid); + + plot = new ezl.Layer() + .width(w).height(h) + .appendTo(grid); + + + +}); diff --git a/www/test/uki/index.php b/www/test/uki/index.php new file mode 100644 index 0000000..d71bc76 --- /dev/null +++ b/www/test/uki/index.php @@ -0,0 +1,79 @@ + + + +uki test + + + + +
+
+ +
+
+ + + ( , ) + ( , ) + +
+

+    
+ +
+

Trigonometry and Reflection Test

+
    +
  • The main line is pink (and the light-orange line is its tangent).
  • +
  • Click anywhere to add a point. It will be purple, and its reflection in the main line will be orange.
  • +
  • You can drag the blue control points of the main line to change it.
  • +
+
+
+ +
+ +
+ + \ No newline at end of file diff --git a/www/test/uki/test-uki.js b/www/test/uki/test-uki.js new file mode 100644 index 0000000..e69de29 -- 1.7.0.4