cornerstone-source 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|