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.
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +20 -0
- data/Rakefile +8 -0
- data/config.rb +79 -0
- data/config.ru +4 -0
- data/cornerstone.gemspec +22 -0
- data/doc_scraper.rb +51 -0
- data/game.js +4293 -0
- data/lib/assets/javascripts/cornerstone.js +4719 -0
- data/lib/cornerstone.rb +11 -0
- data/lib/cornerstone/rails.rb +5 -0
- data/lib/cornerstone/sprockets.rb +2 -0
- data/lib/cornerstone/version.rb +3 -0
- data/manifest.json +15 -0
- data/pixie.json +12 -0
- data/source/javascripts/_cornerstone/_object_extensions.js.coffee +108 -0
- data/source/javascripts/_cornerstone/array_extensions.js.coffee +570 -0
- data/source/javascripts/_cornerstone/bindable.js.coffee +125 -0
- data/source/javascripts/_cornerstone/command_stack.js.coffee +36 -0
- data/source/javascripts/_cornerstone/core_object.js.coffee +183 -0
- data/source/javascripts/_cornerstone/function_extensions.js.coffee +60 -0
- data/source/javascripts/_cornerstone/logging.js.coffee +19 -0
- data/source/javascripts/_cornerstone/matrix.js.coffee +337 -0
- data/source/javascripts/_cornerstone/number_extensions.js.coffee +491 -0
- data/source/javascripts/_cornerstone/point.js.coffee +641 -0
- data/source/javascripts/_cornerstone/random.js.coffee +86 -0
- data/source/javascripts/_cornerstone/rectangle.js.coffee +35 -0
- data/source/javascripts/_cornerstone/string_extensions.js.coffee +232 -0
- data/source/javascripts/_cornerstone/stubs.js.coffee +1042 -0
- data/source/javascripts/_cornerstone/uuid.js +96 -0
- data/source/javascripts/_test/array_extensions.coffee +173 -0
- data/source/javascripts/_test/bindable.coffee +68 -0
- data/source/javascripts/_test/command_stack.coffee +99 -0
- data/source/javascripts/_test/core_object.coffee +95 -0
- data/source/javascripts/_test/function_extensions.coffee +50 -0
- data/source/javascripts/_test/logging.coffee +7 -0
- data/source/javascripts/_test/matrix.coffee +174 -0
- data/source/javascripts/_test/number_extensions.coffee +138 -0
- data/source/javascripts/_test/object_extensions.coffee +53 -0
- data/source/javascripts/_test/point.coffee +196 -0
- data/source/javascripts/_test/random.coffee +22 -0
- data/source/javascripts/_test/rectangle.coffee +70 -0
- data/source/javascripts/_test/string_extensions.coffee +59 -0
- data/source/javascripts/cornerstone.js.coffee +1 -0
- data/source/javascripts/cornerstone_tests.js.coffee +2 -0
- data/source/test.html.haml +13 -0
- data/vendor/javascripts/qunit.js +1275 -0
- data/vendor/stylesheets/qunit.css.sass +115 -0
- 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
|
+
|