cornerstone-source 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. data/.gitignore +22 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +20 -0
  5. data/Rakefile +8 -0
  6. data/config.rb +79 -0
  7. data/config.ru +4 -0
  8. data/cornerstone.gemspec +22 -0
  9. data/doc_scraper.rb +51 -0
  10. data/game.js +4293 -0
  11. data/lib/assets/javascripts/cornerstone.js +4719 -0
  12. data/lib/cornerstone.rb +11 -0
  13. data/lib/cornerstone/rails.rb +5 -0
  14. data/lib/cornerstone/sprockets.rb +2 -0
  15. data/lib/cornerstone/version.rb +3 -0
  16. data/manifest.json +15 -0
  17. data/pixie.json +12 -0
  18. data/source/javascripts/_cornerstone/_object_extensions.js.coffee +108 -0
  19. data/source/javascripts/_cornerstone/array_extensions.js.coffee +570 -0
  20. data/source/javascripts/_cornerstone/bindable.js.coffee +125 -0
  21. data/source/javascripts/_cornerstone/command_stack.js.coffee +36 -0
  22. data/source/javascripts/_cornerstone/core_object.js.coffee +183 -0
  23. data/source/javascripts/_cornerstone/function_extensions.js.coffee +60 -0
  24. data/source/javascripts/_cornerstone/logging.js.coffee +19 -0
  25. data/source/javascripts/_cornerstone/matrix.js.coffee +337 -0
  26. data/source/javascripts/_cornerstone/number_extensions.js.coffee +491 -0
  27. data/source/javascripts/_cornerstone/point.js.coffee +641 -0
  28. data/source/javascripts/_cornerstone/random.js.coffee +86 -0
  29. data/source/javascripts/_cornerstone/rectangle.js.coffee +35 -0
  30. data/source/javascripts/_cornerstone/string_extensions.js.coffee +232 -0
  31. data/source/javascripts/_cornerstone/stubs.js.coffee +1042 -0
  32. data/source/javascripts/_cornerstone/uuid.js +96 -0
  33. data/source/javascripts/_test/array_extensions.coffee +173 -0
  34. data/source/javascripts/_test/bindable.coffee +68 -0
  35. data/source/javascripts/_test/command_stack.coffee +99 -0
  36. data/source/javascripts/_test/core_object.coffee +95 -0
  37. data/source/javascripts/_test/function_extensions.coffee +50 -0
  38. data/source/javascripts/_test/logging.coffee +7 -0
  39. data/source/javascripts/_test/matrix.coffee +174 -0
  40. data/source/javascripts/_test/number_extensions.coffee +138 -0
  41. data/source/javascripts/_test/object_extensions.coffee +53 -0
  42. data/source/javascripts/_test/point.coffee +196 -0
  43. data/source/javascripts/_test/random.coffee +22 -0
  44. data/source/javascripts/_test/rectangle.coffee +70 -0
  45. data/source/javascripts/_test/string_extensions.coffee +59 -0
  46. data/source/javascripts/cornerstone.js.coffee +1 -0
  47. data/source/javascripts/cornerstone_tests.js.coffee +2 -0
  48. data/source/test.html.haml +13 -0
  49. data/vendor/javascripts/qunit.js +1275 -0
  50. data/vendor/stylesheets/qunit.css.sass +115 -0
  51. metadata +141 -0
@@ -0,0 +1,125 @@
1
+ ###*
2
+ Bindable module.
3
+
4
+ player = Core
5
+ x: 5
6
+ y: 10
7
+
8
+ player.bind "update", ->
9
+ updatePlayer()
10
+ # => Uncaught TypeError: Object has no method 'bind'
11
+
12
+ player.include(Bindable)
13
+
14
+ player.bind "update", ->
15
+ updatePlayer()
16
+ # => this will call updatePlayer each time through the main loop
17
+
18
+ @name Bindable
19
+ @module
20
+ @constructor
21
+ ###
22
+ Bindable = (I={}, self) ->
23
+ eventCallbacks = {}
24
+
25
+ bind: (args...) ->
26
+ self.on(args...)
27
+
28
+ unbind: (args...) ->
29
+ self.off(args...)
30
+
31
+ ###*
32
+ Adds a function as an event listener.
33
+
34
+ # this will call coolEventHandler after
35
+ # yourObject.trigger "someCustomEvent" is called.
36
+ yourObject.on "someCustomEvent", coolEventHandler
37
+
38
+ #or
39
+ yourObject.on "anotherCustomEvent", ->
40
+ doSomething()
41
+
42
+ @name on
43
+ @methodOf Bindable#
44
+ @param {String} event The event to listen to.
45
+ @param {Function} callback The function to be called when the specified event
46
+ is triggered.
47
+ ###
48
+ on: (namespacedEvent, callback) ->
49
+ [event, namespace] = namespacedEvent.split(".")
50
+
51
+ # HACK: Here we annotate the callback function with namespace metadata
52
+ # This will probably lead to some strange edge cases, but should work fine
53
+ # for simple cases.
54
+ if namespace
55
+ callback.__PIXIE ||= {}
56
+ callback.__PIXIE[namespace] = true
57
+
58
+ eventCallbacks[event] ||= []
59
+ eventCallbacks[event].push(callback)
60
+
61
+ return this
62
+
63
+ ###*
64
+ Removes a specific event listener, or all event listeners if
65
+ no specific listener is given.
66
+
67
+ # removes the handler coolEventHandler from the event
68
+ # "someCustomEvent" while leaving the other events intact.
69
+ yourObject.off "someCustomEvent", coolEventHandler
70
+
71
+ # removes all handlers attached to "anotherCustomEvent"
72
+ yourObject.off "anotherCustomEvent"
73
+
74
+ @name off
75
+ @methodOf Bindable#
76
+ @param {String} event The event to remove the listener from.
77
+ @param {Function} [callback] The listener to remove.
78
+ ###
79
+ off: (namespacedEvent, callback) ->
80
+ [event, namespace] = namespacedEvent.split(".")
81
+
82
+ if event
83
+ eventCallbacks[event] ||= []
84
+
85
+ if namespace
86
+ # Select only the callbacks that do not have this namespace metadata
87
+ eventCallbacks[event] = eventCallbacks.select (callback) ->
88
+ !callback.__PIXIE?[namespace]?
89
+
90
+ else
91
+ if callback
92
+ eventCallbacks[event].remove(callback)
93
+ else
94
+ eventCallbacks[event] = []
95
+ else if namespace
96
+ # No event given
97
+ # Select only the callbacks that do not have this namespace metadata
98
+ # for any events bound
99
+ for key, callbacks of eventCallbacks
100
+ eventCallbacks[key] = callbacks.select (callback) ->
101
+ !callback.__PIXIE?[namespace]?
102
+
103
+ return this
104
+
105
+ ###*
106
+ Calls all listeners attached to the specified event.
107
+
108
+ # calls each event handler bound to "someCustomEvent"
109
+ yourObject.trigger "someCustomEvent"
110
+
111
+ @name trigger
112
+ @methodOf Bindable#
113
+ @param {String} event The event to trigger.
114
+ @param {Array} [parameters] Additional parameters to pass to the event listener.
115
+ ###
116
+ trigger: (event, parameters...) ->
117
+ callbacks = eventCallbacks[event]
118
+
119
+ if callbacks && callbacks.length
120
+ self = this
121
+
122
+ callbacks.each (callback) ->
123
+ callback.apply(self, parameters)
124
+
125
+ (exports ? this)["Bindable"] = Bindable
@@ -0,0 +1,36 @@
1
+ CommandStack = ->
2
+ stack = []
3
+ index = 0
4
+
5
+ execute: (command) ->
6
+ stack[index] = command
7
+ command.execute()
8
+
9
+ # Be sure to blast obsolete redos
10
+ stack.length = index += 1
11
+
12
+ undo: ->
13
+ if @canUndo()
14
+ index -= 1
15
+
16
+ command = stack[index]
17
+ command.undo()
18
+
19
+ return command
20
+
21
+ redo: ->
22
+ if @canRedo()
23
+ command = stack[index]
24
+ command.execute()
25
+
26
+ index += 1
27
+
28
+ return command
29
+
30
+ canUndo: ->
31
+ index > 0
32
+
33
+ canRedo: ->
34
+ stack[index]?
35
+
36
+ (exports ? this)["CommandStack"] = CommandStack
@@ -0,0 +1,183 @@
1
+ ###*
2
+ The Core class is used to add extended functionality to objects without
3
+ extending the object class directly. Inherit from Core to gain its utility
4
+ methods.
5
+
6
+ @name Core
7
+ @constructor
8
+
9
+ @param {Object} I Instance variables
10
+ ###
11
+
12
+ ( ->
13
+ root = exports ? this
14
+
15
+ root.Core = (I={}) ->
16
+ Object.reverseMerge I,
17
+ includedModules: []
18
+
19
+ self =
20
+ ###*
21
+ External access to instance variables. Use of this property should be avoided
22
+ in general, but can come in handy from time to time.
23
+
24
+ I =
25
+ r: 255
26
+ g: 0
27
+ b: 100
28
+
29
+ myObject = Core(I)
30
+
31
+ # a bad idea most of the time, but it's
32
+ # pretty convenient to have available.
33
+ myObject.I.r
34
+ # => 255
35
+
36
+ myObject.I.g
37
+ # => 0
38
+
39
+ myObject.I.b
40
+ # => 100
41
+
42
+ @name I
43
+ @fieldOf Core#
44
+ ###
45
+ I: I
46
+
47
+ ###*
48
+ Generates a public jQuery style getter / setter method for each
49
+ String argument.
50
+
51
+ myObject = Core
52
+ r: 255
53
+ g: 0
54
+ b: 100
55
+
56
+ myObject.attrAccessor "r", "g", "b"
57
+
58
+ myObject.r(254)
59
+ myObject.r()
60
+
61
+ => 254
62
+
63
+ @name attrAccessor
64
+ @methodOf Core#
65
+ ###
66
+ attrAccessor: (attrNames...) ->
67
+ attrNames.each (attrName) ->
68
+ self[attrName] = (newValue) ->
69
+ if newValue?
70
+ I[attrName] = newValue
71
+ return self
72
+ else
73
+ I[attrName]
74
+
75
+ ###*
76
+ Generates a public jQuery style getter method for each String argument.
77
+
78
+ myObject = Core
79
+ r: 255
80
+ g: 0
81
+ b: 100
82
+
83
+ myObject.attrReader "r", "g", "b"
84
+
85
+ myObject.r()
86
+ => 255
87
+
88
+ myObject.g()
89
+ => 0
90
+
91
+ myObject.b()
92
+ => 100
93
+
94
+ @name attrReader
95
+ @methodOf Core#
96
+ ###
97
+ attrReader: (attrNames...) ->
98
+ attrNames.each (attrName) ->
99
+ self[attrName] = ->
100
+ I[attrName]
101
+
102
+ ###*
103
+ Extends this object with methods from the passed in object. A shortcut for Object.extend(self, methods)
104
+
105
+ I =
106
+ x: 30
107
+ y: 40
108
+ maxSpeed: 5
109
+
110
+ # we are using extend to give player
111
+ # additional methods that Core doesn't have
112
+ player = Core(I).extend
113
+ increaseSpeed: ->
114
+ I.maxSpeed += 1
115
+
116
+ player.I.maxSpeed
117
+ => 5
118
+
119
+ player.increaseSpeed()
120
+
121
+ player.I.maxSpeed
122
+ => 6
123
+
124
+ @name extend
125
+ @methodOf Core#
126
+ @see Object.extend
127
+ @returns self
128
+ ###
129
+ extend: (options) ->
130
+ Object.extend self, options
131
+
132
+ return self
133
+
134
+ ###*
135
+ Includes a module in this object.
136
+
137
+ myObject = Core()
138
+ myObject.include(Bindable)
139
+
140
+ # now you can bind handlers to functions
141
+ myObject.bind "someEvent", ->
142
+ alert("wow. that was easy.")
143
+
144
+ @name include
145
+ @methodOf Core#
146
+ @param {String} Module the module to include. A module is a constructor that takes two parameters, I and self, and returns an object containing the public methods to extend the including object with.
147
+ ###
148
+ include: (modules...) ->
149
+ for Module in modules
150
+ if Module.isString?()
151
+ moduleName = Module
152
+ Module = Module.constantize()
153
+ else if moduleName = Module._name
154
+ # Nothing, captured name in if condition
155
+ else
156
+ # Attempt to look up module in global namespace
157
+ for key, value of root
158
+ if value is Module
159
+ Module._name = moduleName = key # Cache module name
160
+
161
+ if moduleName
162
+ unless I.includedModules.include moduleName
163
+ I.includedModules.push moduleName
164
+ self.extend Module(I, self)
165
+ else
166
+ warn "Unable to discover name for module: ", Module, "\nSerialization issues may occur."
167
+ self.extend Module(I, self)
168
+
169
+ return self
170
+
171
+ send: (name, args...) ->
172
+ self[name](args...)
173
+
174
+ # Include Bindable by default
175
+ self.include "Bindable"
176
+
177
+ # Initial module inclue, for reconstructing objects from JSON
178
+ for moduleName in I.includedModules
179
+ Module = moduleName.constantize()
180
+ self.extend Module(I, self)
181
+
182
+ return self
183
+ )()
@@ -0,0 +1,60 @@
1
+ Function::once = ->
2
+ func = this
3
+
4
+ ran = false
5
+ memo = undefined
6
+
7
+ return ->
8
+ return memo if ran
9
+ ran = true
10
+
11
+ return memo = func.apply(this, arguments)
12
+
13
+ ###*
14
+ Calling a debounced function will postpone its execution until after
15
+ wait milliseconds have elapsed since the last time the function was
16
+ invoked. Useful for implementing behavior that should only happen after
17
+ the input has stopped arriving. For example: rendering a preview of a
18
+ Markdown comment, recalculating a layout after the window has stopped
19
+ being resized...
20
+
21
+ lazyLayout = calculateLayout.debounce(300)
22
+ $(window).resize(lazyLayout)
23
+
24
+ @name debounce
25
+ @methodOf Function#
26
+ @returns {Function} The debounced version of this function.
27
+ ###
28
+ Function::debounce = (wait) ->
29
+ timeout = null
30
+ func = this
31
+
32
+ return ->
33
+ context = this
34
+ args = arguments
35
+
36
+ later = ->
37
+ timeout = null
38
+ func.apply(context, args)
39
+
40
+ clearTimeout(timeout)
41
+ timeout = setTimeout(later, wait)
42
+
43
+ # Not sure about the future of this, but trying it out
44
+ Function::returning = (x) ->
45
+ func = this
46
+
47
+ ->
48
+ func.apply(this, arguments)
49
+ return x
50
+
51
+ Function::delay = (wait, args...) ->
52
+ func = this
53
+
54
+ setTimeout ->
55
+ func.apply(null, args)
56
+ , wait
57
+
58
+ Function::defer = (args...) ->
59
+ this.delay.apply this, [1].concat(args)
60
+
@@ -0,0 +1,19 @@
1
+ ###*
2
+ @name Logging
3
+ @namespace
4
+
5
+ Gives you some convenience methods for outputting data while developing.
6
+
7
+ log "Testing123"
8
+ info "Hey, this is happening"
9
+ warn "Be careful, this might be a problem"
10
+ error "Kaboom!"
11
+ ###
12
+
13
+ ["log", "info", "warn", "error"].each (name) ->
14
+ if typeof console != "undefined"
15
+ (exports ? this)[name] = (args...) ->
16
+ if console[name]
17
+ console[name](args...)
18
+ else
19
+ (exports ? this)[name] = ->
@@ -0,0 +1,337 @@
1
+ ###*
2
+ * Matrix.js v1.3.0pre
3
+ *
4
+ * Copyright (c) 2010 STRd6
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ *
24
+ * Loosely based on flash:
25
+ * http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/geom/Matrix.html
26
+ ###
27
+ ( ->
28
+ ###*
29
+ <pre>
30
+ _ _
31
+ | a c tx |
32
+ | b d ty |
33
+ |_0 0 1 _|
34
+ </pre>
35
+ Creates a matrix for 2d affine transformations.
36
+
37
+ concat, inverse, rotate, scale and translate return new matrices with the
38
+ transformations applied. The matrix is not modified in place.
39
+
40
+ Returns the identity matrix when called with no arguments.
41
+
42
+ @name Matrix
43
+ @param {Number} [a]
44
+ @param {Number} [b]
45
+ @param {Number} [c]
46
+ @param {Number} [d]
47
+ @param {Number} [tx]
48
+ @param {Number} [ty]
49
+ @constructor
50
+ ###
51
+ Matrix = (a, b, c, d, tx, ty) ->
52
+ if Object.isObject(a)
53
+ {a, b, c, d, tx, ty} = a
54
+
55
+ __proto__: Matrix::
56
+ ###*
57
+ @name a
58
+ @fieldOf Matrix#
59
+ ###
60
+ a: if a? then a else 1
61
+
62
+ ###*
63
+ @name b
64
+ @fieldOf Matrix#
65
+ ###
66
+ b: b || 0
67
+
68
+ ###*
69
+ @name c
70
+ @fieldOf Matrix#
71
+ ###
72
+ c: c || 0,
73
+
74
+ ###*
75
+ @name d
76
+ @fieldOf Matrix#
77
+ ###
78
+ d: if d? then d else 1
79
+
80
+ ###*
81
+ @name tx
82
+ @fieldOf Matrix#
83
+ ###
84
+ tx: tx || 0
85
+
86
+ ###*
87
+ @name ty
88
+ @fieldOf Matrix#
89
+ ###
90
+ ty: ty || 0
91
+
92
+ Matrix:: =
93
+ ###*
94
+ Returns the result of this matrix multiplied by another matrix
95
+ combining the geometric effects of the two. In mathematical terms,
96
+ concatenating two matrixes is the same as combining them using matrix multiplication.
97
+ If this matrix is A and the matrix passed in is B, the resulting matrix is A x B
98
+ http://mathworld.wolfram.com/MatrixMultiplication.html
99
+ @name concat
100
+ @methodOf Matrix#
101
+ @param {Matrix} matrix The matrix to multiply this matrix by.
102
+ @returns {Matrix} The result of the matrix multiplication, a new matrix.
103
+ ###
104
+ concat: (matrix) ->
105
+ Matrix(
106
+ @a * matrix.a + @c * matrix.b,
107
+ @b * matrix.a + @d * matrix.b,
108
+ @a * matrix.c + @c * matrix.d,
109
+ @b * matrix.c + @d * matrix.d,
110
+ @a * matrix.tx + @c * matrix.ty + @tx,
111
+ @b * matrix.tx + @d * matrix.ty + @ty
112
+ )
113
+
114
+ ###*
115
+ Copy this matrix.
116
+ @name copy
117
+ @methodOf Matrix#
118
+ @returns {Matrix} A copy of this matrix.
119
+ ###
120
+ copy: ->
121
+ Matrix(@a, @b, @c, @d, @tx, @ty)
122
+
123
+ ###*
124
+ Given a point in the pretransform coordinate space, returns the coordinates of
125
+ that point after the transformation occurs. Unlike the standard transformation
126
+ applied using the transformPoint() method, the deltaTransformPoint() method
127
+ does not consider the translation parameters tx and ty.
128
+ @name deltaTransformPoint
129
+ @methodOf Matrix#
130
+ @see #transformPoint
131
+ @return {Point} A new point transformed by this matrix ignoring tx and ty.
132
+ ###
133
+ deltaTransformPoint: (point) ->
134
+ Point(
135
+ @a * point.x + @c * point.y,
136
+ @b * point.x + @d * point.y
137
+ )
138
+
139
+ ###*
140
+ Returns the inverse of the matrix.
141
+ http://mathworld.wolfram.com/MatrixInverse.html
142
+ @name inverse
143
+ @methodOf Matrix#
144
+ @returns {Matrix} A new matrix that is the inverse of this matrix.
145
+ ###
146
+ inverse: ->
147
+ determinant = @a * @d - @b * @c
148
+
149
+ Matrix(
150
+ @d / determinant,
151
+ -@b / determinant,
152
+ -@c / determinant,
153
+ @a / determinant,
154
+ (@c * @ty - @d * @tx) / determinant,
155
+ (@b * @tx - @a * @ty) / determinant
156
+ )
157
+
158
+ ###*
159
+ Returns a new matrix that corresponds this matrix multiplied by a
160
+ a rotation matrix.
161
+ @name rotate
162
+ @methodOf Matrix#
163
+ @see Matrix.rotation
164
+ @param {Number} theta Amount to rotate in radians.
165
+ @param {Point} [aboutPoint] The point about which this rotation occurs. Defaults to (0,0).
166
+ @returns {Matrix} A new matrix, rotated by the specified amount.
167
+ ###
168
+ rotate: (theta, aboutPoint) ->
169
+ @concat(Matrix.rotation(theta, aboutPoint))
170
+
171
+ ###*
172
+ Returns a new matrix that corresponds this matrix multiplied by a
173
+ a scaling matrix.
174
+ @name scale
175
+ @methodOf Matrix#
176
+ @see Matrix.scale
177
+ @param {Number} sx
178
+ @param {Number} [sy]
179
+ @param {Point} [aboutPoint] The point that remains fixed during the scaling
180
+ @returns {Matrix} A new Matrix. The original multiplied by a scaling matrix.
181
+ ###
182
+ scale: (sx, sy, aboutPoint) ->
183
+ @concat(Matrix.scale(sx, sy, aboutPoint))
184
+
185
+ ###*
186
+ Returns a new matrix that corresponds this matrix multiplied by a
187
+ a skewing matrix.
188
+
189
+ @name skew
190
+ @methodOf Matrix#
191
+ @see Matrix.skew
192
+ @param {Number} skewX The angle of skew in the x dimension.
193
+ @param {Number} skewY The angle of skew in the y dimension.
194
+ ###
195
+ skew: (skewX, skewY) ->
196
+ @concat(Matrix.skew(skewX, skewY))
197
+
198
+ ###*
199
+ Returns a string representation of this matrix.
200
+
201
+ @name toString
202
+ @methodOf Matrix#
203
+ @returns {String} A string reperesentation of this matrix.
204
+ ###
205
+ toString: ->
206
+ "Matrix(#{@a}, #{@b}, #{@c}, #{@d}, #{@tx}, #{@ty})"
207
+
208
+ ###*
209
+ Returns the result of applying the geometric transformation represented by the
210
+ Matrix object to the specified point.
211
+ @name transformPoint
212
+ @methodOf Matrix#
213
+ @see #deltaTransformPoint
214
+ @returns {Point} A new point with the transformation applied.
215
+ ###
216
+ transformPoint: (point) ->
217
+ Point(
218
+ @a * point.x + @c * point.y + @tx,
219
+ @b * point.x + @d * point.y + @ty
220
+ )
221
+
222
+ ###*
223
+ Translates the matrix along the x and y axes, as specified by the tx and ty parameters.
224
+ @name translate
225
+ @methodOf Matrix#
226
+ @see Matrix.translation
227
+ @param {Number} tx The translation along the x axis.
228
+ @param {Number} ty The translation along the y axis.
229
+ @returns {Matrix} A new matrix with the translation applied.
230
+ ###
231
+ translate: (tx, ty) ->
232
+ @concat(Matrix.translation(tx, ty))
233
+
234
+ ###*
235
+ Creates a matrix transformation that corresponds to the given rotation,
236
+ around (0,0) or the specified point.
237
+ @see Matrix#rotate
238
+ @param {Number} theta Rotation in radians.
239
+ @param {Point} [aboutPoint] The point about which this rotation occurs. Defaults to (0,0).
240
+ @returns {Matrix} A new matrix rotated by the given amount.
241
+ ###
242
+ Matrix.rotate = Matrix.rotation = (theta, aboutPoint) ->
243
+ rotationMatrix = Matrix(
244
+ Math.cos(theta),
245
+ Math.sin(theta),
246
+ -Math.sin(theta),
247
+ Math.cos(theta)
248
+ )
249
+
250
+ if aboutPoint?
251
+ rotationMatrix =
252
+ Matrix.translation(aboutPoint.x, aboutPoint.y).concat(
253
+ rotationMatrix
254
+ ).concat(
255
+ Matrix.translation(-aboutPoint.x, -aboutPoint.y)
256
+ )
257
+
258
+ return rotationMatrix
259
+
260
+ ###*
261
+ Returns a matrix that corresponds to scaling by factors of sx, sy along
262
+ the x and y axis respectively.
263
+ If only one parameter is given the matrix is scaled uniformly along both axis.
264
+ If the optional aboutPoint parameter is given the scaling takes place
265
+ about the given point.
266
+ @see Matrix#scale
267
+ @param {Number} sx The amount to scale by along the x axis or uniformly if no sy is given.
268
+ @param {Number} [sy] The amount to scale by along the y axis.
269
+ @param {Point} [aboutPoint] The point about which the scaling occurs. Defaults to (0,0).
270
+ @returns {Matrix} A matrix transformation representing scaling by sx and sy.
271
+ ###
272
+ Matrix.scale = (sx, sy, aboutPoint) ->
273
+ sy = sy || sx
274
+
275
+ scaleMatrix = Matrix(sx, 0, 0, sy)
276
+
277
+ if aboutPoint
278
+ scaleMatrix =
279
+ Matrix.translation(aboutPoint.x, aboutPoint.y).concat(
280
+ scaleMatrix
281
+ ).concat(
282
+ Matrix.translation(-aboutPoint.x, -aboutPoint.y)
283
+ )
284
+
285
+ return scaleMatrix
286
+
287
+ ###*
288
+ Returns a matrix that corresponds to a skew of skewX, skewY.
289
+
290
+ @see Matrix#skew
291
+ @param {Number} skewX The angle of skew in the x dimension.
292
+ @param {Number} skewY The angle of skew in the y dimension.
293
+ @return {Matrix} A matrix transformation representing a skew by skewX and skewY.
294
+ ###
295
+ Matrix.skew = (skewX, skewY) ->
296
+ Matrix(0, Math.tan(skewY), Math.tan(skewX), 0)
297
+
298
+ ###*
299
+ Returns a matrix that corresponds to a translation of tx, ty.
300
+ @see Matrix#translate
301
+ @param {Number} tx The amount to translate in the x direction.
302
+ @param {Number} ty The amount to translate in the y direction.
303
+ @return {Matrix} A matrix transformation representing a translation by tx and ty.
304
+ ###
305
+ Matrix.translate = Matrix.translation = (tx, ty) ->
306
+ Matrix(1, 0, 0, 1, tx, ty)
307
+
308
+ ###*
309
+ A constant representing the identity matrix.
310
+ @name IDENTITY
311
+ @fieldOf Matrix
312
+ ###
313
+ Matrix.IDENTITY = Matrix()
314
+
315
+ ###*
316
+ A constant representing the horizontal flip transformation matrix.
317
+ @name HORIZONTAL_FLIP
318
+ @fieldOf Matrix
319
+ ###
320
+ Matrix.HORIZONTAL_FLIP = Matrix(-1, 0, 0, 1)
321
+
322
+ ###*
323
+ A constant representing the vertical flip transformation matrix.
324
+ @name VERTICAL_FLIP
325
+ @fieldOf Matrix
326
+ ###
327
+ Matrix.VERTICAL_FLIP = Matrix(1, 0, 0, -1)
328
+
329
+ if Object.freeze
330
+ Object.freeze Matrix.IDENTITY
331
+ Object.freeze Matrix.HORIZONTAL_FLIP
332
+ Object.freeze Matrix.VERTICAL_FLIP
333
+
334
+ # Export to window
335
+ (exports ? this)["Matrix"] = Matrix
336
+ )()
337
+