A gewgaw is indentified by its dir; its "main" source is index.js.
Chris Pressey
8 years ago
34 | 34 | |
35 | 35 | You ought to be able to say something like this to start any of these gewgaws: |
36 | 36 | |
37 | <script src="some-gewgaw.js"></script> | |
37 | <script src="index.js"></script> | |
38 | 38 | <script> |
39 | 39 | launch('../path/to/scripts', 'element_id', config); |
40 | 40 | </script> |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "sprite-manager.js", | |
5 | "animation.js" | |
6 | ]; | |
7 | var loaded = 0; | |
8 | for (var i = 0; i < deps.length; i++) { | |
9 | var elem = document.createElement('script'); | |
10 | elem.src = prefix + deps[i]; | |
11 | elem.onload = function() { | |
12 | if (++loaded < deps.length) return; | |
13 | var container = document.getElementById(containerId); | |
14 | ||
15 | var canvas = yoob.makeCanvas(container, 600, 400); | |
16 | ||
17 | var g = (new MinimalistCritique()).init({ canvas: canvas }); | |
18 | g.start(); | |
19 | }; | |
20 | document.body.appendChild(elem); | |
21 | } | |
22 | } | |
23 | ||
24 | MinimalistCritique = function() { | |
25 | this.init = function(cfg) { | |
26 | this.canvas = cfg.canvas; | |
27 | this.ctx = this.canvas.getContext('2d'); | |
28 | this.manager = (new yoob.SpriteManager()).init({ canvas: this.canvas }); | |
29 | this.animation = (new yoob.Animation()).init({'object': this}); | |
30 | this.reset(); | |
31 | return this; | |
32 | }; | |
33 | ||
34 | this.reset = function() { | |
35 | this.manager.clearSprites(); | |
36 | ||
37 | this.current = null; | |
38 | this.floorLevel = this.canvas.height; | |
39 | ||
40 | this.sizes = [10, 40, 200, this.canvas.width]; | |
41 | this.stage = 0; | |
42 | ||
43 | this.addNextBlock(); | |
44 | }; | |
45 | ||
46 | this.start = function() { | |
47 | this.animation.start(); | |
48 | }; | |
49 | ||
50 | this.addBlock = function(cfg) { | |
51 | var d = new yoob.Sprite(); | |
52 | cfg.dy = 1; | |
53 | d.init(cfg); | |
54 | d.draw = function(ctx) { | |
55 | ctx.fillStyle = this.fillStyle || "green"; | |
56 | ctx.fillRect(this.getLeftX(), this.getTopY(), this.getWidth(), this.getHeight()); | |
57 | }; | |
58 | d.fillStyle = "green"; | |
59 | this.manager.addSprite(d); | |
60 | this.current = d; | |
61 | }; | |
62 | ||
63 | this.addNextBlock = function() { | |
64 | if (this.stage >= this.sizes.length) { | |
65 | this.animation.stop(); | |
66 | var $this = this; | |
67 | setTimeout(function() { | |
68 | // draw the big red X | |
69 | var angles = [0.125, 0.375]; | |
70 | for (var i = 0; i <= 1; i++) { | |
71 | $this.ctx.save(); | |
72 | $this.ctx.translate($this.canvas.width / 2, $this.canvas.height / 2); | |
73 | $this.ctx.rotate(angles[i] * 2 * Math.PI); | |
74 | $this.ctx.fillStyle = 'red'; | |
75 | $this.ctx.fillRect( | |
76 | $this.canvas.width * -0.40, | |
77 | $this.canvas.height * -0.05, | |
78 | $this.canvas.width * 0.80, | |
79 | $this.canvas.height * 0.10 | |
80 | ); | |
81 | $this.ctx.restore(); | |
82 | } | |
83 | ||
84 | setTimeout(function() { | |
85 | $this.reset(); | |
86 | $this.start(); | |
87 | }, 1000); | |
88 | }, 100); | |
89 | } | |
90 | ||
91 | this.addBlock({ | |
92 | x: this.canvas.width / 2, | |
93 | y: 0 - this.sizes[this.stage] / 2, | |
94 | width: this.sizes[this.stage], | |
95 | height: this.sizes[this.stage] | |
96 | }); | |
97 | }; | |
98 | ||
99 | this.draw = function() { | |
100 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); | |
101 | this.manager.draw(this.ctx); | |
102 | }; | |
103 | ||
104 | this.update = function() { | |
105 | this.manager.move(); | |
106 | if (this.current.getBottomY() >= this.floorLevel) { | |
107 | this.current.setPosition(this.current.getX(), this.floorLevel - this.current.getHeight() / 2); | |
108 | this.floorLevel = this.floorLevel - this.current.getHeight(); | |
109 | this.current.setVelocity(0, 0); | |
110 | this.stage += 1; | |
111 | this.draw(); | |
112 | this.addNextBlock(); | |
113 | } | |
114 | }; | |
115 | } |
9 | 9 | <div id="container"></div> |
10 | 10 | |
11 | 11 | </body> |
12 | <script src="a-minimalist-critique.js"></script> | |
12 | <script src="index.js"></script> | |
13 | 13 | <script> |
14 | 14 | launch('../common-yoob.js-0.11/', 'container'); |
15 | 15 | </script> |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "sprite-manager.js", | |
5 | "animation.js" | |
6 | ]; | |
7 | var loaded = 0; | |
8 | for (var i = 0; i < deps.length; i++) { | |
9 | var elem = document.createElement('script'); | |
10 | elem.src = prefix + deps[i]; | |
11 | elem.onload = function() { | |
12 | if (++loaded < deps.length) return; | |
13 | var container = document.getElementById(containerId); | |
14 | ||
15 | var canvas = yoob.makeCanvas(container, 600, 400); | |
16 | ||
17 | var g = (new MinimalistCritique()).init({ canvas: canvas }); | |
18 | g.start(); | |
19 | }; | |
20 | document.body.appendChild(elem); | |
21 | } | |
22 | } | |
23 | ||
24 | MinimalistCritique = function() { | |
25 | this.init = function(cfg) { | |
26 | this.canvas = cfg.canvas; | |
27 | this.ctx = this.canvas.getContext('2d'); | |
28 | this.manager = (new yoob.SpriteManager()).init({ canvas: this.canvas }); | |
29 | this.animation = (new yoob.Animation()).init({'object': this}); | |
30 | this.reset(); | |
31 | return this; | |
32 | }; | |
33 | ||
34 | this.reset = function() { | |
35 | this.manager.clearSprites(); | |
36 | ||
37 | this.current = null; | |
38 | this.floorLevel = this.canvas.height; | |
39 | ||
40 | this.sizes = [10, 40, 200, this.canvas.width]; | |
41 | this.stage = 0; | |
42 | ||
43 | this.addNextBlock(); | |
44 | }; | |
45 | ||
46 | this.start = function() { | |
47 | this.animation.start(); | |
48 | }; | |
49 | ||
50 | this.addBlock = function(cfg) { | |
51 | var d = new yoob.Sprite(); | |
52 | cfg.dy = 1; | |
53 | d.init(cfg); | |
54 | d.draw = function(ctx) { | |
55 | ctx.fillStyle = this.fillStyle || "green"; | |
56 | ctx.fillRect(this.getLeftX(), this.getTopY(), this.getWidth(), this.getHeight()); | |
57 | }; | |
58 | d.fillStyle = "green"; | |
59 | this.manager.addSprite(d); | |
60 | this.current = d; | |
61 | }; | |
62 | ||
63 | this.addNextBlock = function() { | |
64 | if (this.stage >= this.sizes.length) { | |
65 | this.animation.stop(); | |
66 | var $this = this; | |
67 | setTimeout(function() { | |
68 | // draw the big red X | |
69 | var angles = [0.125, 0.375]; | |
70 | for (var i = 0; i <= 1; i++) { | |
71 | $this.ctx.save(); | |
72 | $this.ctx.translate($this.canvas.width / 2, $this.canvas.height / 2); | |
73 | $this.ctx.rotate(angles[i] * 2 * Math.PI); | |
74 | $this.ctx.fillStyle = 'red'; | |
75 | $this.ctx.fillRect( | |
76 | $this.canvas.width * -0.40, | |
77 | $this.canvas.height * -0.05, | |
78 | $this.canvas.width * 0.80, | |
79 | $this.canvas.height * 0.10 | |
80 | ); | |
81 | $this.ctx.restore(); | |
82 | } | |
83 | ||
84 | setTimeout(function() { | |
85 | $this.reset(); | |
86 | $this.start(); | |
87 | }, 1000); | |
88 | }, 100); | |
89 | } | |
90 | ||
91 | this.addBlock({ | |
92 | x: this.canvas.width / 2, | |
93 | y: 0 - this.sizes[this.stage] / 2, | |
94 | width: this.sizes[this.stage], | |
95 | height: this.sizes[this.stage] | |
96 | }); | |
97 | }; | |
98 | ||
99 | this.draw = function() { | |
100 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); | |
101 | this.manager.draw(this.ctx); | |
102 | }; | |
103 | ||
104 | this.update = function() { | |
105 | this.manager.move(); | |
106 | if (this.current.getBottomY() >= this.floorLevel) { | |
107 | this.current.setPosition(this.current.getX(), this.floorLevel - this.current.getHeight() / 2); | |
108 | this.floorLevel = this.floorLevel - this.current.getHeight(); | |
109 | this.current.setVelocity(0, 0); | |
110 | this.stage += 1; | |
111 | this.draw(); | |
112 | this.addNextBlock(); | |
113 | } | |
114 | }; | |
115 | } |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | "sprite-manager.js", | |
5 | "canvas-resizer.js" | |
6 | ]; | |
7 | var loaded = 0; | |
8 | for (var i = 0; i < deps.length; i++) { | |
9 | var elem = document.createElement('script'); | |
10 | elem.src = prefix + deps[i]; | |
11 | elem.onload = function() { | |
12 | if (++loaded < deps.length) return; | |
13 | ||
14 | var gewgaw = new ANonRandomWalk(); | |
15 | var container = document.getElementById(containerId); | |
16 | var button = yoob.makeButton(container, 'Reset', gewgaw.reset); | |
17 | var hanger = yoob.makeDiv(container); | |
18 | var canvas = yoob.makeCanvas(hanger, 600, 400); | |
19 | var initialized = false; | |
20 | var cr = (new yoob.CanvasResizer()).init({ | |
21 | canvas: canvas, | |
22 | onResizeEnd: function() { | |
23 | if (!initialized) { | |
24 | gewgaw.init(canvas); | |
25 | initialized = true; | |
26 | } | |
27 | }, | |
28 | desiredWidth: 600, | |
29 | desiredHeight: 400 | |
30 | }).register(); | |
31 | }; | |
32 | document.body.appendChild(elem); | |
33 | } | |
34 | } | |
35 | ||
36 | var originX; | |
37 | var x; | |
38 | ||
39 | var walker; | |
40 | var indicator; | |
41 | var cardHistory; | |
42 | ||
43 | var cardsRemaining; | |
44 | ||
45 | Walker = function() { | |
46 | this.init = function(cfg) { | |
47 | cfg.x = 0; | |
48 | cfg.y = 0; | |
49 | cfg.width = 40; | |
50 | cfg.height = 40; | |
51 | // call superclass'es init() method | |
52 | Walker.prototype.init.apply(this, [cfg]); | |
53 | this.dist = 0; | |
54 | return this; | |
55 | }; | |
56 | ||
57 | this.draw = function(ctx) { | |
58 | ctx.beginPath(); | |
59 | ctx.strokeStyle = "black"; | |
60 | ctx.lineWidth = 3; | |
61 | ctx.fillStyle = "rgba(255, 0, 0, 0.5)"; | |
62 | ctx.arc(this.getX(), this.getY(), | |
63 | this.getWidth() / 2, 0, 2 * Math.PI, false); | |
64 | ctx.closePath(); | |
65 | ctx.fill(); | |
66 | ctx.stroke(); | |
67 | }; | |
68 | ||
69 | this.onreachdestination = function() { | |
70 | this.setVelocity(0, 0); | |
71 | indicator.dist = this.dist; | |
72 | if (cardsRemaining === 0) indicator.dist = 0; | |
73 | indicator.setPosition(this.getX(), this.getY()); | |
74 | }; | |
75 | }; | |
76 | ||
77 | Indicator = function() { | |
78 | this.init = function(cfg) { | |
79 | cfg.x = 0; | |
80 | cfg.y = 0; | |
81 | cfg.width = 0; | |
82 | cfg.height = 0; | |
83 | // call superclass'es init() method | |
84 | Indicator.prototype.init.apply(this, [cfg]); | |
85 | this.dist = 0; | |
86 | return this; | |
87 | }; | |
88 | ||
89 | this.draw = function(ctx) { | |
90 | ctx.beginPath(); | |
91 | ctx.strokeStyle = "rgba(255, 0, 0, 0.5)"; | |
92 | ctx.moveTo(this.getX(), this.getY()); | |
93 | ctx.lineTo(this.getX() - this.dist, this.getY()); | |
94 | ctx.stroke(); | |
95 | ||
96 | ctx.beginPath(); | |
97 | ctx.strokeStyle = "rgba(0, 0, 0, 0.5)"; | |
98 | ctx.moveTo(this.getX(), this.getY()); | |
99 | ctx.lineTo(this.getX() + this.dist, this.getY()); | |
100 | ctx.stroke(); | |
101 | }; | |
102 | }; | |
103 | ||
104 | Card = function() { | |
105 | this.init = function(cfg) { | |
106 | this.color = cfg.color; | |
107 | this.faceUp = cfg.faceUp; | |
108 | // call superclass'es init() method | |
109 | Card.prototype.init.apply(this, [cfg]); | |
110 | return this; | |
111 | }; | |
112 | ||
113 | this.onclick = function() { | |
114 | if (this.faceUp) return; | |
115 | var dist = Math.abs(x) / 2; | |
116 | // in case walker was already moving, move indicator | |
117 | if (walker.destCounter) { | |
118 | indicator.dist = dist; | |
119 | indicator.setPosition(originX + x, walker.getY()); | |
120 | } | |
121 | if (this.color === 'red') { | |
122 | x -= dist; | |
123 | } else { | |
124 | x += dist; | |
125 | } | |
126 | // new dist, will be set on indicator when walker finishes | |
127 | walker.dist = Math.abs(x) / 2; | |
128 | cardHistory.push(x); | |
129 | walker.setDestination(originX + x, walker.getY(), 30); | |
130 | this.faceUp = true; | |
131 | cardsRemaining--; | |
132 | }; | |
133 | ||
134 | this.draw = function(ctx) { | |
135 | if (!this.faceUp) { | |
136 | var gradient = ctx.createLinearGradient( | |
137 | this.getLeftX(), this.getTopY(), | |
138 | this.getRightX(), this.getBottomY() | |
139 | ); | |
140 | gradient.addColorStop(0.0, "red"); | |
141 | gradient.addColorStop(0.5, "white"); | |
142 | gradient.addColorStop(1.0, "blue"); | |
143 | ctx.fillStyle = gradient; | |
144 | } else { | |
145 | ctx.fillStyle = this.color; | |
146 | } | |
147 | ctx.fillRect(this.getLeftX(), this.getTopY(), | |
148 | this.getWidth(), this.getHeight()); | |
149 | }; | |
150 | }; | |
151 | ||
152 | function shuffle(array) { | |
153 | var a = []; | |
154 | while (array.length > 0) { | |
155 | a.push(array.splice(Math.random() * array.length, 1)[0]); | |
156 | } | |
157 | return a; | |
158 | } | |
159 | ||
160 | ANonRandomWalk = function() { | |
161 | var canvas; | |
162 | var ctx; | |
163 | ||
164 | var manager; | |
165 | ||
166 | var y; | |
167 | var targetX; | |
168 | ||
169 | this.draw = function() { | |
170 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
171 | ||
172 | // draw floor | |
173 | ctx.strokeStyle = "black"; | |
174 | ctx.lineWidth = 3; | |
175 | ctx.moveTo(0, y); | |
176 | ctx.lineTo(canvas.width, y); | |
177 | ctx.stroke(); | |
178 | ||
179 | // draw origin point | |
180 | ctx.beginPath(); | |
181 | ctx.fillStyle = "black"; | |
182 | ctx.arc(originX, y, 5, 0, 2 * Math.PI, false); | |
183 | ctx.fill(); | |
184 | ctx.stroke(); | |
185 | ctx.closePath(); | |
186 | ||
187 | // draw sprites | |
188 | manager.draw(ctx); | |
189 | ||
190 | // draw target | |
191 | ctx.strokeStyle = "blue"; | |
192 | ctx.lineWidth = 1; | |
193 | ctx.beginPath(); | |
194 | ctx.moveTo(originX + targetX - 10, y + 20); | |
195 | ctx.lineTo(originX + targetX, y); | |
196 | ctx.lineTo(originX + targetX + 10, y + 20); | |
197 | ctx.stroke(); | |
198 | ctx.closePath(); | |
199 | ||
200 | // draw history | |
201 | ctx.strokeStyle = "black"; | |
202 | ctx.lineWidth = 1; | |
203 | ctx.beginPath(); | |
204 | ctx.moveTo(originX + cardHistory[0], y); | |
205 | for (var i = 1; i < cardHistory.length; i++) { | |
206 | ctx.lineTo(originX + cardHistory[i], y + i * 10); | |
207 | } | |
208 | ctx.stroke(); | |
209 | }; | |
210 | ||
211 | this.update = function() { | |
212 | manager.move(); | |
213 | }; | |
214 | ||
215 | this.reset = function() { | |
216 | manager.clearSprites(); | |
217 | ||
218 | walker = (new Walker()).init({}); | |
219 | manager.addSprite(walker); | |
220 | indicator = (new Indicator()).init({}); | |
221 | manager.addSprite(indicator); | |
222 | ||
223 | x = 250; | |
224 | y = 100; | |
225 | targetX = 23.73046875 * (x / 100); | |
226 | originX = canvas.width / 8; | |
227 | cardHistory = [x]; | |
228 | cardsRemaining = 10; | |
229 | var deck = []; | |
230 | for (var i = 0; i < 10; i++) { | |
231 | deck.push(i % 2 === 0 ? "red" : "black"); | |
232 | } | |
233 | deck = shuffle(deck); | |
234 | var cardW = 40; | |
235 | var cardH = 80; | |
236 | for (var i = 0; i < 10; i++) { | |
237 | var cardX = (cardW * 0.75) + (i % 13) * (cardW * 1.5); | |
238 | var cardY = 280; | |
239 | var card = (new Card()).init({ | |
240 | x: cardX, | |
241 | y: cardY, | |
242 | width: cardW, | |
243 | height: cardH, | |
244 | isClickable: true, | |
245 | color: deck[i], | |
246 | faceUp: false | |
247 | }); | |
248 | manager.addSprite(card); | |
249 | } | |
250 | walker.setPosition(originX + x, y - walker.getHeight() / 2); | |
251 | indicator.dist = Math.abs(x) / 2; | |
252 | indicator.setPosition(walker.getX(), walker.getY()); | |
253 | }; | |
254 | ||
255 | this.init = function(c) { | |
256 | /* This is kind of awful, but we can't have these as part of | |
257 | the main script, because yoob/sprite-manager.js might not be | |
258 | loaded yet. */ | |
259 | Walker.prototype = new yoob.Sprite(); | |
260 | Indicator.prototype = new yoob.Sprite(); | |
261 | Card.prototype = new yoob.Sprite(); | |
262 | ||
263 | canvas = c; | |
264 | ctx = canvas.getContext('2d'); | |
265 | ||
266 | manager = (new yoob.SpriteManager()).init({ | |
267 | canvas: canvas | |
268 | }); | |
269 | ||
270 | this.reset(); | |
271 | this.animation = (new yoob.Animation()).init({ | |
272 | object: this | |
273 | }); | |
274 | this.animation.start(); | |
275 | }; | |
276 | } |
16 | 16 | <div id="container"></div> |
17 | 17 | |
18 | 18 | </body> |
19 | <script src="a-non-random-walk.js"></script> | |
19 | <script src="index.js"></script> | |
20 | 20 | <script> |
21 | 21 | launch('../common-yoob.js-0.11/', 'container'); |
22 | 22 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | "sprite-manager.js", | |
5 | "canvas-resizer.js" | |
6 | ]; | |
7 | var loaded = 0; | |
8 | for (var i = 0; i < deps.length; i++) { | |
9 | var elem = document.createElement('script'); | |
10 | elem.src = prefix + deps[i]; | |
11 | elem.onload = function() { | |
12 | if (++loaded < deps.length) return; | |
13 | ||
14 | var gewgaw = new ANonRandomWalk(); | |
15 | var container = document.getElementById(containerId); | |
16 | var button = yoob.makeButton(container, 'Reset', gewgaw.reset); | |
17 | var hanger = yoob.makeDiv(container); | |
18 | var canvas = yoob.makeCanvas(hanger, 600, 400); | |
19 | var initialized = false; | |
20 | var cr = (new yoob.CanvasResizer()).init({ | |
21 | canvas: canvas, | |
22 | onResizeEnd: function() { | |
23 | if (!initialized) { | |
24 | gewgaw.init(canvas); | |
25 | initialized = true; | |
26 | } | |
27 | }, | |
28 | desiredWidth: 600, | |
29 | desiredHeight: 400 | |
30 | }).register(); | |
31 | }; | |
32 | document.body.appendChild(elem); | |
33 | } | |
34 | } | |
35 | ||
36 | var originX; | |
37 | var x; | |
38 | ||
39 | var walker; | |
40 | var indicator; | |
41 | var cardHistory; | |
42 | ||
43 | var cardsRemaining; | |
44 | ||
45 | Walker = function() { | |
46 | this.init = function(cfg) { | |
47 | cfg.x = 0; | |
48 | cfg.y = 0; | |
49 | cfg.width = 40; | |
50 | cfg.height = 40; | |
51 | // call superclass'es init() method | |
52 | Walker.prototype.init.apply(this, [cfg]); | |
53 | this.dist = 0; | |
54 | return this; | |
55 | }; | |
56 | ||
57 | this.draw = function(ctx) { | |
58 | ctx.beginPath(); | |
59 | ctx.strokeStyle = "black"; | |
60 | ctx.lineWidth = 3; | |
61 | ctx.fillStyle = "rgba(255, 0, 0, 0.5)"; | |
62 | ctx.arc(this.getX(), this.getY(), | |
63 | this.getWidth() / 2, 0, 2 * Math.PI, false); | |
64 | ctx.closePath(); | |
65 | ctx.fill(); | |
66 | ctx.stroke(); | |
67 | }; | |
68 | ||
69 | this.onreachdestination = function() { | |
70 | this.setVelocity(0, 0); | |
71 | indicator.dist = this.dist; | |
72 | if (cardsRemaining === 0) indicator.dist = 0; | |
73 | indicator.setPosition(this.getX(), this.getY()); | |
74 | }; | |
75 | }; | |
76 | ||
77 | Indicator = function() { | |
78 | this.init = function(cfg) { | |
79 | cfg.x = 0; | |
80 | cfg.y = 0; | |
81 | cfg.width = 0; | |
82 | cfg.height = 0; | |
83 | // call superclass'es init() method | |
84 | Indicator.prototype.init.apply(this, [cfg]); | |
85 | this.dist = 0; | |
86 | return this; | |
87 | }; | |
88 | ||
89 | this.draw = function(ctx) { | |
90 | ctx.beginPath(); | |
91 | ctx.strokeStyle = "rgba(255, 0, 0, 0.5)"; | |
92 | ctx.moveTo(this.getX(), this.getY()); | |
93 | ctx.lineTo(this.getX() - this.dist, this.getY()); | |
94 | ctx.stroke(); | |
95 | ||
96 | ctx.beginPath(); | |
97 | ctx.strokeStyle = "rgba(0, 0, 0, 0.5)"; | |
98 | ctx.moveTo(this.getX(), this.getY()); | |
99 | ctx.lineTo(this.getX() + this.dist, this.getY()); | |
100 | ctx.stroke(); | |
101 | }; | |
102 | }; | |
103 | ||
104 | Card = function() { | |
105 | this.init = function(cfg) { | |
106 | this.color = cfg.color; | |
107 | this.faceUp = cfg.faceUp; | |
108 | // call superclass'es init() method | |
109 | Card.prototype.init.apply(this, [cfg]); | |
110 | return this; | |
111 | }; | |
112 | ||
113 | this.onclick = function() { | |
114 | if (this.faceUp) return; | |
115 | var dist = Math.abs(x) / 2; | |
116 | // in case walker was already moving, move indicator | |
117 | if (walker.destCounter) { | |
118 | indicator.dist = dist; | |
119 | indicator.setPosition(originX + x, walker.getY()); | |
120 | } | |
121 | if (this.color === 'red') { | |
122 | x -= dist; | |
123 | } else { | |
124 | x += dist; | |
125 | } | |
126 | // new dist, will be set on indicator when walker finishes | |
127 | walker.dist = Math.abs(x) / 2; | |
128 | cardHistory.push(x); | |
129 | walker.setDestination(originX + x, walker.getY(), 30); | |
130 | this.faceUp = true; | |
131 | cardsRemaining--; | |
132 | }; | |
133 | ||
134 | this.draw = function(ctx) { | |
135 | if (!this.faceUp) { | |
136 | var gradient = ctx.createLinearGradient( | |
137 | this.getLeftX(), this.getTopY(), | |
138 | this.getRightX(), this.getBottomY() | |
139 | ); | |
140 | gradient.addColorStop(0.0, "red"); | |
141 | gradient.addColorStop(0.5, "white"); | |
142 | gradient.addColorStop(1.0, "blue"); | |
143 | ctx.fillStyle = gradient; | |
144 | } else { | |
145 | ctx.fillStyle = this.color; | |
146 | } | |
147 | ctx.fillRect(this.getLeftX(), this.getTopY(), | |
148 | this.getWidth(), this.getHeight()); | |
149 | }; | |
150 | }; | |
151 | ||
152 | function shuffle(array) { | |
153 | var a = []; | |
154 | while (array.length > 0) { | |
155 | a.push(array.splice(Math.random() * array.length, 1)[0]); | |
156 | } | |
157 | return a; | |
158 | } | |
159 | ||
160 | ANonRandomWalk = function() { | |
161 | var canvas; | |
162 | var ctx; | |
163 | ||
164 | var manager; | |
165 | ||
166 | var y; | |
167 | var targetX; | |
168 | ||
169 | this.draw = function() { | |
170 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
171 | ||
172 | // draw floor | |
173 | ctx.strokeStyle = "black"; | |
174 | ctx.lineWidth = 3; | |
175 | ctx.moveTo(0, y); | |
176 | ctx.lineTo(canvas.width, y); | |
177 | ctx.stroke(); | |
178 | ||
179 | // draw origin point | |
180 | ctx.beginPath(); | |
181 | ctx.fillStyle = "black"; | |
182 | ctx.arc(originX, y, 5, 0, 2 * Math.PI, false); | |
183 | ctx.fill(); | |
184 | ctx.stroke(); | |
185 | ctx.closePath(); | |
186 | ||
187 | // draw sprites | |
188 | manager.draw(ctx); | |
189 | ||
190 | // draw target | |
191 | ctx.strokeStyle = "blue"; | |
192 | ctx.lineWidth = 1; | |
193 | ctx.beginPath(); | |
194 | ctx.moveTo(originX + targetX - 10, y + 20); | |
195 | ctx.lineTo(originX + targetX, y); | |
196 | ctx.lineTo(originX + targetX + 10, y + 20); | |
197 | ctx.stroke(); | |
198 | ctx.closePath(); | |
199 | ||
200 | // draw history | |
201 | ctx.strokeStyle = "black"; | |
202 | ctx.lineWidth = 1; | |
203 | ctx.beginPath(); | |
204 | ctx.moveTo(originX + cardHistory[0], y); | |
205 | for (var i = 1; i < cardHistory.length; i++) { | |
206 | ctx.lineTo(originX + cardHistory[i], y + i * 10); | |
207 | } | |
208 | ctx.stroke(); | |
209 | }; | |
210 | ||
211 | this.update = function() { | |
212 | manager.move(); | |
213 | }; | |
214 | ||
215 | this.reset = function() { | |
216 | manager.clearSprites(); | |
217 | ||
218 | walker = (new Walker()).init({}); | |
219 | manager.addSprite(walker); | |
220 | indicator = (new Indicator()).init({}); | |
221 | manager.addSprite(indicator); | |
222 | ||
223 | x = 250; | |
224 | y = 100; | |
225 | targetX = 23.73046875 * (x / 100); | |
226 | originX = canvas.width / 8; | |
227 | cardHistory = [x]; | |
228 | cardsRemaining = 10; | |
229 | var deck = []; | |
230 | for (var i = 0; i < 10; i++) { | |
231 | deck.push(i % 2 === 0 ? "red" : "black"); | |
232 | } | |
233 | deck = shuffle(deck); | |
234 | var cardW = 40; | |
235 | var cardH = 80; | |
236 | for (var i = 0; i < 10; i++) { | |
237 | var cardX = (cardW * 0.75) + (i % 13) * (cardW * 1.5); | |
238 | var cardY = 280; | |
239 | var card = (new Card()).init({ | |
240 | x: cardX, | |
241 | y: cardY, | |
242 | width: cardW, | |
243 | height: cardH, | |
244 | isClickable: true, | |
245 | color: deck[i], | |
246 | faceUp: false | |
247 | }); | |
248 | manager.addSprite(card); | |
249 | } | |
250 | walker.setPosition(originX + x, y - walker.getHeight() / 2); | |
251 | indicator.dist = Math.abs(x) / 2; | |
252 | indicator.setPosition(walker.getX(), walker.getY()); | |
253 | }; | |
254 | ||
255 | this.init = function(c) { | |
256 | /* This is kind of awful, but we can't have these as part of | |
257 | the main script, because yoob/sprite-manager.js might not be | |
258 | loaded yet. */ | |
259 | Walker.prototype = new yoob.Sprite(); | |
260 | Indicator.prototype = new yoob.Sprite(); | |
261 | Card.prototype = new yoob.Sprite(); | |
262 | ||
263 | canvas = c; | |
264 | ctx = canvas.getContext('2d'); | |
265 | ||
266 | manager = (new yoob.SpriteManager()).init({ | |
267 | canvas: canvas | |
268 | }); | |
269 | ||
270 | this.reset(); | |
271 | this.animation = (new yoob.Animation()).init({ | |
272 | object: this | |
273 | }); | |
274 | this.animation.start(); | |
275 | }; | |
276 | } |
0 | "use strict"; | |
1 | ||
2 | var bgimg = new Image(); | |
3 | ||
4 | function launch(prefix, containerId, config) { | |
5 | var config = config || {}; | |
6 | var deps = [ | |
7 | "element-factory.js", | |
8 | "canvas-resizer.js" | |
9 | ]; | |
10 | var loaded = 0; | |
11 | for (var i = 0; i < deps.length; i++) { | |
12 | var elem = document.createElement('script'); | |
13 | elem.src = prefix + deps[i]; | |
14 | elem.onload = function() { | |
15 | if (++loaded < deps.length) return; | |
16 | var container = document.getElementById(containerId); | |
17 | ||
18 | yoob.makeParagraph(container, | |
19 | 'When you are finished, see <a href="http://feldmangallery.com/media/pdfs/Ukeles_MANIFESTO.pdf">(Ukeles, 1969)</a> for further instructions</p>' | |
20 | ); | |
21 | ||
22 | container = yoob.makeDiv(container); | |
23 | var msg = yoob.makeParagraph( | |
24 | container, | |
25 | "Not enough room to display the canvas! Resize your browser! Or use a device with a larger screen!" | |
26 | ); | |
27 | msg.style.display = 'none'; | |
28 | ||
29 | var canvas = yoob.makeCanvas(container, 500, 310); | |
30 | canvas.style.position = 'absolute'; | |
31 | canvas.style.background = 'transparent'; | |
32 | canvas.style.zIndex = "100"; | |
33 | canvas.style.cursor = "pointer"; | |
34 | ||
35 | var backing = yoob.makeCanvas(container, 500, 310); | |
36 | backing.style.zIndex = "0"; | |
37 | ||
38 | var resize = function() { | |
39 | backing.style.display = canvas.style.display; | |
40 | backing.style.marginTop = canvas.style.marginTop; | |
41 | backing.style.left = canvas.offsetLeft + "px"; | |
42 | backing.style.top = canvas.offsetTop + "px"; | |
43 | backing.width = canvas.width; | |
44 | backing.height = canvas.height; | |
45 | backing.getContext('2d').drawImage(bgimg, 0, 0, backing.width, backing.height); | |
46 | canvas.style.zIndex = "100"; | |
47 | backing.style.zIndex = "0"; | |
48 | }; | |
49 | ||
50 | var cr = (new yoob.CanvasResizer()).init({ | |
51 | canvas: canvas, | |
52 | desiredWidth: 500, | |
53 | desiredHeight: 310, | |
54 | allowExpansion: false, | |
55 | allowContraction: false, | |
56 | missingCanvasElement: msg, | |
57 | onResizeFail: resize, | |
58 | onResizeEnd: resize | |
59 | }).register(); | |
60 | ||
61 | var artURL = config.artURL || 'art.jpg'; | |
62 | var gewgaw = new ArtRestorationSimulator(); | |
63 | gewgaw.init(canvas, backing, artURL); | |
64 | ||
65 | }; | |
66 | document.body.appendChild(elem); | |
67 | } | |
68 | } | |
69 | ||
70 | ||
71 | var ArtRestorationSimulator = function() { | |
72 | var backing; | |
73 | var canvasCtx; | |
74 | var backingCtx; | |
75 | var intervalId; | |
76 | var imageData; | |
77 | var mouseDown; | |
78 | var canvasX; | |
79 | var canvasY; | |
80 | ||
81 | var mask = [ | |
82 | " *** ", | |
83 | " ****** ", | |
84 | " ******** ", | |
85 | " *********", | |
86 | "**********", | |
87 | "**********", | |
88 | "********* ", | |
89 | " ******** ", | |
90 | " ****** ", | |
91 | " *** " | |
92 | ]; | |
93 | ||
94 | this.init = function(canvas, b, bgimgURL) { | |
95 | this.canvas = canvas; | |
96 | backing = b; | |
97 | backingCtx = backing.getContext('2d'); | |
98 | canvasCtx = this.canvas.getContext('2d'); | |
99 | canvasCtx.clearRect(0, 0, canvas.width, canvas.height); | |
100 | canvasCtx.fillStyle = "rgba(50,80,100,255)"; | |
101 | canvasCtx.fillRect(0, 0, canvas.width, canvas.height); | |
102 | imageData = canvasCtx.getImageData(0, 0, canvas.width, canvas.height); | |
103 | ||
104 | var $this = this; | |
105 | this.canvas.addEventListener('mousedown', function(e) { | |
106 | return $this.onmousedown(e, e); | |
107 | }); | |
108 | this.canvas.addEventListener('touchstart', function(e) { | |
109 | return $this.onmousedown(e, e.touches[0]); | |
110 | }); | |
111 | ||
112 | this.canvas.addEventListener('mousemove', function(e) { | |
113 | return $this.onmousemove(e, e); | |
114 | }); | |
115 | this.canvas.addEventListener('touchmove', function(e) { | |
116 | return $this.onmousemove(e, e.touches[0]); | |
117 | }); | |
118 | ||
119 | this.canvas.addEventListener('mouseup', function(e) { | |
120 | return $this.onmouseup(e, e); | |
121 | }); | |
122 | this.canvas.addEventListener('touchend', function(e) { | |
123 | return $this.onmouseup(e, e.touches[0]); | |
124 | }); | |
125 | ||
126 | var $this = this; | |
127 | bgimg.onload = function() { | |
128 | backingCtx.drawImage(bgimg, 0, 0, backing.width, backing.height); | |
129 | }; | |
130 | bgimg.src = bgimgURL; | |
131 | }; | |
132 | ||
133 | this.onmousedown = function(e, touch) { | |
134 | mouseDown = true; | |
135 | }; | |
136 | ||
137 | this.onmouseup = function(e, touch) { | |
138 | mouseDown = false; | |
139 | }; | |
140 | ||
141 | this.onmousemove = function(e, touch) { | |
142 | if (!mouseDown) return; | |
143 | canvasX = touch.pageX - this.canvas.offsetLeft; | |
144 | canvasY = touch.pageY - this.canvas.offsetTop; | |
145 | canvasCtx.putImageData(imageData, 0, 0); | |
146 | if (mouseDown) { | |
147 | var range = 10; | |
148 | var w = this.canvas.width; | |
149 | for (var dx = 0; dx < range; dx++) { | |
150 | var x = canvasX - range + dx; | |
151 | for (var dy = 0; dy < range; dy++) { | |
152 | if (mask[dy].charAt(dx) !== '*') continue; | |
153 | var y = canvasY - range + dy; | |
154 | var index = (y * w + x) * 4; | |
155 | imageData.data[index + 3] -= 12; | |
156 | } | |
157 | } | |
158 | } | |
159 | }; | |
160 | } |
21 | 21 | <div id="container"></div> |
22 | 22 | |
23 | 23 | </body> |
24 | <script src="art-restoration-simulator.js"></script> | |
24 | <script src="index.js"></script> | |
25 | 25 | <script> |
26 | 26 | launch('../common-yoob.js-0.11/', 'container'); |
27 | 27 | </script> |
0 | "use strict"; | |
1 | ||
2 | var bgimg = new Image(); | |
3 | ||
4 | function launch(prefix, containerId, config) { | |
5 | var config = config || {}; | |
6 | var deps = [ | |
7 | "element-factory.js", | |
8 | "canvas-resizer.js" | |
9 | ]; | |
10 | var loaded = 0; | |
11 | for (var i = 0; i < deps.length; i++) { | |
12 | var elem = document.createElement('script'); | |
13 | elem.src = prefix + deps[i]; | |
14 | elem.onload = function() { | |
15 | if (++loaded < deps.length) return; | |
16 | var container = document.getElementById(containerId); | |
17 | ||
18 | yoob.makeParagraph(container, | |
19 | 'When you are finished, see <a href="http://feldmangallery.com/media/pdfs/Ukeles_MANIFESTO.pdf">(Ukeles, 1969)</a> for further instructions</p>' | |
20 | ); | |
21 | ||
22 | container = yoob.makeDiv(container); | |
23 | var msg = yoob.makeParagraph( | |
24 | container, | |
25 | "Not enough room to display the canvas! Resize your browser! Or use a device with a larger screen!" | |
26 | ); | |
27 | msg.style.display = 'none'; | |
28 | ||
29 | var canvas = yoob.makeCanvas(container, 500, 310); | |
30 | canvas.style.position = 'absolute'; | |
31 | canvas.style.background = 'transparent'; | |
32 | canvas.style.zIndex = "100"; | |
33 | canvas.style.cursor = "pointer"; | |
34 | ||
35 | var backing = yoob.makeCanvas(container, 500, 310); | |
36 | backing.style.zIndex = "0"; | |
37 | ||
38 | var resize = function() { | |
39 | backing.style.display = canvas.style.display; | |
40 | backing.style.marginTop = canvas.style.marginTop; | |
41 | backing.style.left = canvas.offsetLeft + "px"; | |
42 | backing.style.top = canvas.offsetTop + "px"; | |
43 | backing.width = canvas.width; | |
44 | backing.height = canvas.height; | |
45 | backing.getContext('2d').drawImage(bgimg, 0, 0, backing.width, backing.height); | |
46 | canvas.style.zIndex = "100"; | |
47 | backing.style.zIndex = "0"; | |
48 | }; | |
49 | ||
50 | var cr = (new yoob.CanvasResizer()).init({ | |
51 | canvas: canvas, | |
52 | desiredWidth: 500, | |
53 | desiredHeight: 310, | |
54 | allowExpansion: false, | |
55 | allowContraction: false, | |
56 | missingCanvasElement: msg, | |
57 | onResizeFail: resize, | |
58 | onResizeEnd: resize | |
59 | }).register(); | |
60 | ||
61 | var artURL = config.artURL || 'art.jpg'; | |
62 | var gewgaw = new ArtRestorationSimulator(); | |
63 | gewgaw.init(canvas, backing, artURL); | |
64 | ||
65 | }; | |
66 | document.body.appendChild(elem); | |
67 | } | |
68 | } | |
69 | ||
70 | ||
71 | var ArtRestorationSimulator = function() { | |
72 | var backing; | |
73 | var canvasCtx; | |
74 | var backingCtx; | |
75 | var intervalId; | |
76 | var imageData; | |
77 | var mouseDown; | |
78 | var canvasX; | |
79 | var canvasY; | |
80 | ||
81 | var mask = [ | |
82 | " *** ", | |
83 | " ****** ", | |
84 | " ******** ", | |
85 | " *********", | |
86 | "**********", | |
87 | "**********", | |
88 | "********* ", | |
89 | " ******** ", | |
90 | " ****** ", | |
91 | " *** " | |
92 | ]; | |
93 | ||
94 | this.init = function(canvas, b, bgimgURL) { | |
95 | this.canvas = canvas; | |
96 | backing = b; | |
97 | backingCtx = backing.getContext('2d'); | |
98 | canvasCtx = this.canvas.getContext('2d'); | |
99 | canvasCtx.clearRect(0, 0, canvas.width, canvas.height); | |
100 | canvasCtx.fillStyle = "rgba(50,80,100,255)"; | |
101 | canvasCtx.fillRect(0, 0, canvas.width, canvas.height); | |
102 | imageData = canvasCtx.getImageData(0, 0, canvas.width, canvas.height); | |
103 | ||
104 | var $this = this; | |
105 | this.canvas.addEventListener('mousedown', function(e) { | |
106 | return $this.onmousedown(e, e); | |
107 | }); | |
108 | this.canvas.addEventListener('touchstart', function(e) { | |
109 | return $this.onmousedown(e, e.touches[0]); | |
110 | }); | |
111 | ||
112 | this.canvas.addEventListener('mousemove', function(e) { | |
113 | return $this.onmousemove(e, e); | |
114 | }); | |
115 | this.canvas.addEventListener('touchmove', function(e) { | |
116 | return $this.onmousemove(e, e.touches[0]); | |
117 | }); | |
118 | ||
119 | this.canvas.addEventListener('mouseup', function(e) { | |
120 | return $this.onmouseup(e, e); | |
121 | }); | |
122 | this.canvas.addEventListener('touchend', function(e) { | |
123 | return $this.onmouseup(e, e.touches[0]); | |
124 | }); | |
125 | ||
126 | var $this = this; | |
127 | bgimg.onload = function() { | |
128 | backingCtx.drawImage(bgimg, 0, 0, backing.width, backing.height); | |
129 | }; | |
130 | bgimg.src = bgimgURL; | |
131 | }; | |
132 | ||
133 | this.onmousedown = function(e, touch) { | |
134 | mouseDown = true; | |
135 | }; | |
136 | ||
137 | this.onmouseup = function(e, touch) { | |
138 | mouseDown = false; | |
139 | }; | |
140 | ||
141 | this.onmousemove = function(e, touch) { | |
142 | if (!mouseDown) return; | |
143 | canvasX = touch.pageX - this.canvas.offsetLeft; | |
144 | canvasY = touch.pageY - this.canvas.offsetTop; | |
145 | canvasCtx.putImageData(imageData, 0, 0); | |
146 | if (mouseDown) { | |
147 | var range = 10; | |
148 | var w = this.canvas.width; | |
149 | for (var dx = 0; dx < range; dx++) { | |
150 | var x = canvasX - range + dx; | |
151 | for (var dy = 0; dy < range; dy++) { | |
152 | if (mask[dy].charAt(dx) !== '*') continue; | |
153 | var y = canvasY - range + dy; | |
154 | var index = (y * w + x) * 4; | |
155 | imageData.data[index + 3] -= 12; | |
156 | } | |
157 | } | |
158 | } | |
159 | }; | |
160 | } |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId, config) { | |
3 | var config = config || {}; | |
4 | var deps = [ | |
5 | "element-factory.js", | |
6 | "animation.js", | |
7 | "sprite-manager.js", | |
8 | "canvas-resizer.js" | |
9 | ]; | |
10 | var loaded = 0; | |
11 | for (var i = 0; i < deps.length; i++) { | |
12 | var elem = document.createElement('script'); | |
13 | elem.src = prefix + deps[i]; | |
14 | elem.onload = function() { | |
15 | if (++loaded == deps.length) { | |
16 | var container = document.getElementById(containerId); | |
17 | var t = new BlackHolePoem(); | |
18 | var initialized = false; | |
19 | config.canvas = yoob.makeCanvas(container, 800, 450); | |
20 | var cr = (new yoob.CanvasResizer()).init({ | |
21 | canvas: config.canvas, | |
22 | onResizeEnd: function() { | |
23 | if (!initialized) { | |
24 | t.init(config); | |
25 | initialized = true; | |
26 | } | |
27 | t.draw(); | |
28 | }, | |
29 | desiredWidth: 800, | |
30 | desiredHeight: 450 | |
31 | }).register(); | |
32 | } | |
33 | }; | |
34 | document.body.appendChild(elem); | |
35 | } | |
36 | } | |
37 | ||
38 | var makeText = function(cfg) { | |
39 | var sprite = (new yoob.Sprite()).init({ | |
40 | x: cfg.x, | |
41 | y: cfg.y, | |
42 | width: 30, | |
43 | height: 30, | |
44 | isDraggable: true | |
45 | }); | |
46 | ||
47 | sprite.font = cfg.font || "64px Arial,Sans-serif"; | |
48 | sprite.text = cfg.text; | |
49 | sprite.anchorX = cfg.anchorX; | |
50 | sprite.anchorY = cfg.anchorY; | |
51 | ||
52 | sprite.draw = function(ctx) { | |
53 | ctx.fillStyle = "#432e2a"; | |
54 | ctx.fillRect(this.getLeftX(), this.getTopY(), this.getWidth(), this.getHeight()); | |
55 | ||
56 | ctx.textBaseline = "middle"; | |
57 | ctx.font = this.font; | |
58 | ctx.fillStyle = "black"; | |
59 | ||
60 | var x = this.getX(); | |
61 | var endX = this.anchorX(); | |
62 | var y = this.getY(); | |
63 | var endY = this.anchorY(); | |
64 | ||
65 | for (var i = 0; i < this.text.length; i++) { | |
66 | var c = this.text.charAt(i); | |
67 | if (c===' ') continue; | |
68 | var width = ctx.measureText(c).width; | |
69 | var textX = x - width / 2; | |
70 | ctx.fillText(c, textX, y); | |
71 | x += (endX - x) / 2; | |
72 | y += (endY - y) / 2; | |
73 | } | |
74 | }; | |
75 | ||
76 | cfg.manager.addSprite(sprite); | |
77 | return sprite; | |
78 | }; | |
79 | ||
80 | var BlackHolePoem = function() { | |
81 | var canvas; | |
82 | var ctx; | |
83 | var manager; | |
84 | var texts; | |
85 | ||
86 | this.draw = function() { | |
87 | // Illuminant E: #D3BEBA | |
88 | ctx.fillStyle = "#816660"; | |
89 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
90 | manager.draw(ctx); | |
91 | }; | |
92 | ||
93 | this.update = function() { | |
94 | }; | |
95 | ||
96 | this.init = function(config) { | |
97 | canvas = config.canvas; | |
98 | ctx = canvas.getContext("2d"); | |
99 | ||
100 | var anchorX = function() { return canvas.width / 2; }; | |
101 | var anchorY = function() { return canvas.height / 2; }; | |
102 | ||
103 | manager = (new yoob.SpriteManager()).init({ canvas: canvas }); | |
104 | texts = []; | |
105 | texts.push(makeText({ | |
106 | text: "A billion light-years", | |
107 | manager: manager, | |
108 | x: 20, | |
109 | y: 20, | |
110 | anchorX: anchorX, | |
111 | anchorY: anchorY | |
112 | })); | |
113 | ||
114 | texts.push(makeText({ | |
115 | text: "Distant and unseen", | |
116 | manager: manager, | |
117 | x: canvas.width - 20, | |
118 | y: canvas.height - 20, | |
119 | anchorX: anchorX, | |
120 | anchorY: anchorY | |
121 | })); | |
122 | ||
123 | texts.push(makeText({ | |
124 | text: "Relative to nothing", | |
125 | manager: manager, | |
126 | x: 20, | |
127 | y: canvas.height - 20, | |
128 | anchorX: anchorX, | |
129 | anchorY: anchorY | |
130 | })); | |
131 | ||
132 | texts.push(makeText({ | |
133 | text: "Unequalled forces", | |
134 | manager: manager, | |
135 | x: canvas.width - 20, | |
136 | y: 20, | |
137 | anchorX: anchorX, | |
138 | anchorY: anchorY | |
139 | })); | |
140 | ||
141 | var $this = this; | |
142 | $this.animation = (new yoob.Animation()).init({ | |
143 | object: $this | |
144 | }); | |
145 | $this.animation.start(); | |
146 | }; | |
147 | }; |
19 | 19 | <div id="container"></div> |
20 | 20 | |
21 | 21 | </body> |
22 | <script src="black-hole-poem.js"></script> | |
22 | <script src="index.js"></script> | |
23 | 23 | <script> |
24 | 24 | launch('../common-yoob.js-0.11/', 'container'); |
25 | 25 | </script> |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId, config) { | |
3 | var config = config || {}; | |
4 | var deps = [ | |
5 | "element-factory.js", | |
6 | "animation.js", | |
7 | "sprite-manager.js", | |
8 | "canvas-resizer.js" | |
9 | ]; | |
10 | var loaded = 0; | |
11 | for (var i = 0; i < deps.length; i++) { | |
12 | var elem = document.createElement('script'); | |
13 | elem.src = prefix + deps[i]; | |
14 | elem.onload = function() { | |
15 | if (++loaded == deps.length) { | |
16 | var container = document.getElementById(containerId); | |
17 | var t = new BlackHolePoem(); | |
18 | var initialized = false; | |
19 | config.canvas = yoob.makeCanvas(container, 800, 450); | |
20 | var cr = (new yoob.CanvasResizer()).init({ | |
21 | canvas: config.canvas, | |
22 | onResizeEnd: function() { | |
23 | if (!initialized) { | |
24 | t.init(config); | |
25 | initialized = true; | |
26 | } | |
27 | t.draw(); | |
28 | }, | |
29 | desiredWidth: 800, | |
30 | desiredHeight: 450 | |
31 | }).register(); | |
32 | } | |
33 | }; | |
34 | document.body.appendChild(elem); | |
35 | } | |
36 | } | |
37 | ||
38 | var makeText = function(cfg) { | |
39 | var sprite = (new yoob.Sprite()).init({ | |
40 | x: cfg.x, | |
41 | y: cfg.y, | |
42 | width: 30, | |
43 | height: 30, | |
44 | isDraggable: true | |
45 | }); | |
46 | ||
47 | sprite.font = cfg.font || "64px Arial,Sans-serif"; | |
48 | sprite.text = cfg.text; | |
49 | sprite.anchorX = cfg.anchorX; | |
50 | sprite.anchorY = cfg.anchorY; | |
51 | ||
52 | sprite.draw = function(ctx) { | |
53 | ctx.fillStyle = "#432e2a"; | |
54 | ctx.fillRect(this.getLeftX(), this.getTopY(), this.getWidth(), this.getHeight()); | |
55 | ||
56 | ctx.textBaseline = "middle"; | |
57 | ctx.font = this.font; | |
58 | ctx.fillStyle = "black"; | |
59 | ||
60 | var x = this.getX(); | |
61 | var endX = this.anchorX(); | |
62 | var y = this.getY(); | |
63 | var endY = this.anchorY(); | |
64 | ||
65 | for (var i = 0; i < this.text.length; i++) { | |
66 | var c = this.text.charAt(i); | |
67 | if (c===' ') continue; | |
68 | var width = ctx.measureText(c).width; | |
69 | var textX = x - width / 2; | |
70 | ctx.fillText(c, textX, y); | |
71 | x += (endX - x) / 2; | |
72 | y += (endY - y) / 2; | |
73 | } | |
74 | }; | |
75 | ||
76 | cfg.manager.addSprite(sprite); | |
77 | return sprite; | |
78 | }; | |
79 | ||
80 | var BlackHolePoem = function() { | |
81 | var canvas; | |
82 | var ctx; | |
83 | var manager; | |
84 | var texts; | |
85 | ||
86 | this.draw = function() { | |
87 | // Illuminant E: #D3BEBA | |
88 | ctx.fillStyle = "#816660"; | |
89 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
90 | manager.draw(ctx); | |
91 | }; | |
92 | ||
93 | this.update = function() { | |
94 | }; | |
95 | ||
96 | this.init = function(config) { | |
97 | canvas = config.canvas; | |
98 | ctx = canvas.getContext("2d"); | |
99 | ||
100 | var anchorX = function() { return canvas.width / 2; }; | |
101 | var anchorY = function() { return canvas.height / 2; }; | |
102 | ||
103 | manager = (new yoob.SpriteManager()).init({ canvas: canvas }); | |
104 | texts = []; | |
105 | texts.push(makeText({ | |
106 | text: "A billion light-years", | |
107 | manager: manager, | |
108 | x: 20, | |
109 | y: 20, | |
110 | anchorX: anchorX, | |
111 | anchorY: anchorY | |
112 | })); | |
113 | ||
114 | texts.push(makeText({ | |
115 | text: "Distant and unseen", | |
116 | manager: manager, | |
117 | x: canvas.width - 20, | |
118 | y: canvas.height - 20, | |
119 | anchorX: anchorX, | |
120 | anchorY: anchorY | |
121 | })); | |
122 | ||
123 | texts.push(makeText({ | |
124 | text: "Relative to nothing", | |
125 | manager: manager, | |
126 | x: 20, | |
127 | y: canvas.height - 20, | |
128 | anchorX: anchorX, | |
129 | anchorY: anchorY | |
130 | })); | |
131 | ||
132 | texts.push(makeText({ | |
133 | text: "Unequalled forces", | |
134 | manager: manager, | |
135 | x: canvas.width - 20, | |
136 | y: 20, | |
137 | anchorX: anchorX, | |
138 | anchorY: anchorY | |
139 | })); | |
140 | ||
141 | var $this = this; | |
142 | $this.animation = (new yoob.Animation()).init({ | |
143 | object: $this | |
144 | }); | |
145 | $this.animation.start(); | |
146 | }; | |
147 | }; |
0 | function launch(prefix, containerId) { | |
1 | var container = document.getElementById(containerId); | |
2 | container.style.background = 'white'; | |
3 | container.style.color = 'black'; | |
4 | container.style.textAlign = 'left'; | |
5 | ||
6 | var ps = [ | |
7 | "The Cat only grinned when it saw Alice. It looked good-natured, she thought: still it had very long claws and a great many teeth, so she felt that it ought to be treated with respect. ", | |
8 | "'Cheshire Puss,' she began, rather timidly, as she did not at all know whether it would like the name: however, it only grinned a little wider. 'Come, it's pleased so far,' thought Alice, and she went on. 'Would you tell me, please, which way I ought to go from here?' ", | |
9 | "'That depends a good deal on where you want to get to,' said the Cat. ", | |
10 | "'I don't much care where—' said Alice. ", | |
11 | "'Then it doesn't matter which way you go,' said the Cat. ", | |
12 | "'—so long as I get somewhere,' Alice added as an explanation. ", | |
13 | "'Oh, you're sure to do that,' said the Cat, 'if you only walk long enough.' ", | |
14 | "Alice felt that this could not be denied, so she tried another question. 'What sort of people live about here?' ", | |
15 | "'In that direction,' the Cat said, waving its right paw round, 'lives a Hatter: and in that direction,' waving the other paw, 'lives a March Hare. Visit either you like: they're both mad.' ", | |
16 | "'But I don't want to go among mad people,' Alice remarked. ", | |
17 | "'Oh, you can't help that,' said the Cat: 'we're all mad here. I'm mad. You're mad.' ", | |
18 | "'How do you know I'm mad?' said Alice. ", | |
19 | "'You must be,' said the Cat, 'or you wouldn't have come here.' ", | |
20 | "Alice didn't think that proved it at all; however, she went on 'And how do you know that you're mad?' ", | |
21 | "'To begin with,' said the Cat, 'a dog's not mad. You grant that?' ", | |
22 | "'I suppose so,' said Alice. ", | |
23 | "'Well, then,' the Cat went on, 'you see, a dog growls when it's angry, and wags its tail when it's pleased. Now I growl when I'm pleased, and wag my tail when I'm angry. Therefore I'm mad.' ", | |
24 | "'I call it purring, not growling,' said Alice. ", | |
25 | "'Call it what you like,' said the Cat. 'Do you play croquet with the Queen to-day?' ", | |
26 | "'I should like it very much,' said Alice, 'but I haven't been invited yet.' ", | |
27 | "'You'll see me there,' said the Cat, and vanished. ", | |
28 | "Alice was not much surprised at this, she was getting so used to queer things happening. While she was looking at the place where it had been, it suddenly appeared again. ", | |
29 | "'By-the-bye, what became of the baby?' said the Cat. 'I'd nearly forgotten to ask.' ", | |
30 | "'It turned into a pig,' Alice quietly said, just as if it had come back in a natural way. ", | |
31 | "'I thought it would,' said the Cat, and vanished again. ", | |
32 | "Alice waited a little, half expecting to see it again, but it did not appear, and after a minute or two she walked on in the direction in which the March Hare was said to live. 'I've seen hatters before,' she said to herself; 'the March Hare will be much the most interesting, and perhaps as this is May it won't be raving mad—at least not so mad as it was in March.' As she said this, she looked up, and there was the Cat again, sitting on a branch of a tree. ", | |
33 | "'Did you say pig, or fig?' said the Cat. ", | |
34 | "'I said pig,' replied Alice; 'and I wish you wouldn't keep appearing and vanishing so suddenly: you make one quite giddy.' ", | |
35 | "'All right,' said the Cat; and this time it vanished quite slowly, beginning with the end of the tail, and ending with the grin, which remained some time after the rest of it had gone. ", | |
36 | "'Well! I've often seen a cat without a grin,' thought Alice; 'but a grin without a cat! It's the most curious thing I ever saw in my life!' " | |
37 | ]; | |
38 | ||
39 | for (var i = 0; i < ps.length; i++) { | |
40 | var p = document.createElement('p'); | |
41 | // a slightly odd-looking trick to replace all occurrences of a substring in a string | |
42 | // http://stackoverflow.com/questions/1144783/replacing-all-occurrences-of-a-string-in-javascript#1145525 | |
43 | var text = ps[i].split('grin').join('<span style="color: black">grin</span>'); | |
44 | text = text.split('Cat').join('Text'); | |
45 | text = text.split('Puss').join('Text'); | |
46 | text = text.split('cat').join('text'); | |
47 | text = text.split('walked').join('read'); | |
48 | text = text.split('walk').join('read'); | |
49 | p.innerHTML = text; | |
50 | container.appendChild(p); | |
51 | } | |
52 | ||
53 | var scale = 1000; | |
54 | var alpha = scale; | |
55 | var intervalId = setInterval(function() { | |
56 | var col = "rgba(0,0,0," + (alpha / scale) + ")"; | |
57 | container.style.color = col; | |
58 | if (alpha > 0) alpha -= 1; | |
59 | }, 100); | |
60 | } |
9 | 9 | <div id="container"></div> |
10 | 10 | |
11 | 11 | </body> |
12 | <script src="cheshire-text.js"></script> | |
12 | <script src="index.js"></script> | |
13 | 13 | <script> |
14 | 14 | launch('../common-yoob.js-0.11/', 'container'); |
15 | 15 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var container = document.getElementById(containerId); | |
2 | container.style.background = 'white'; | |
3 | container.style.color = 'black'; | |
4 | container.style.textAlign = 'left'; | |
5 | ||
6 | var ps = [ | |
7 | "The Cat only grinned when it saw Alice. It looked good-natured, she thought: still it had very long claws and a great many teeth, so she felt that it ought to be treated with respect. ", | |
8 | "'Cheshire Puss,' she began, rather timidly, as she did not at all know whether it would like the name: however, it only grinned a little wider. 'Come, it's pleased so far,' thought Alice, and she went on. 'Would you tell me, please, which way I ought to go from here?' ", | |
9 | "'That depends a good deal on where you want to get to,' said the Cat. ", | |
10 | "'I don't much care where—' said Alice. ", | |
11 | "'Then it doesn't matter which way you go,' said the Cat. ", | |
12 | "'—so long as I get somewhere,' Alice added as an explanation. ", | |
13 | "'Oh, you're sure to do that,' said the Cat, 'if you only walk long enough.' ", | |
14 | "Alice felt that this could not be denied, so she tried another question. 'What sort of people live about here?' ", | |
15 | "'In that direction,' the Cat said, waving its right paw round, 'lives a Hatter: and in that direction,' waving the other paw, 'lives a March Hare. Visit either you like: they're both mad.' ", | |
16 | "'But I don't want to go among mad people,' Alice remarked. ", | |
17 | "'Oh, you can't help that,' said the Cat: 'we're all mad here. I'm mad. You're mad.' ", | |
18 | "'How do you know I'm mad?' said Alice. ", | |
19 | "'You must be,' said the Cat, 'or you wouldn't have come here.' ", | |
20 | "Alice didn't think that proved it at all; however, she went on 'And how do you know that you're mad?' ", | |
21 | "'To begin with,' said the Cat, 'a dog's not mad. You grant that?' ", | |
22 | "'I suppose so,' said Alice. ", | |
23 | "'Well, then,' the Cat went on, 'you see, a dog growls when it's angry, and wags its tail when it's pleased. Now I growl when I'm pleased, and wag my tail when I'm angry. Therefore I'm mad.' ", | |
24 | "'I call it purring, not growling,' said Alice. ", | |
25 | "'Call it what you like,' said the Cat. 'Do you play croquet with the Queen to-day?' ", | |
26 | "'I should like it very much,' said Alice, 'but I haven't been invited yet.' ", | |
27 | "'You'll see me there,' said the Cat, and vanished. ", | |
28 | "Alice was not much surprised at this, she was getting so used to queer things happening. While she was looking at the place where it had been, it suddenly appeared again. ", | |
29 | "'By-the-bye, what became of the baby?' said the Cat. 'I'd nearly forgotten to ask.' ", | |
30 | "'It turned into a pig,' Alice quietly said, just as if it had come back in a natural way. ", | |
31 | "'I thought it would,' said the Cat, and vanished again. ", | |
32 | "Alice waited a little, half expecting to see it again, but it did not appear, and after a minute or two she walked on in the direction in which the March Hare was said to live. 'I've seen hatters before,' she said to herself; 'the March Hare will be much the most interesting, and perhaps as this is May it won't be raving mad—at least not so mad as it was in March.' As she said this, she looked up, and there was the Cat again, sitting on a branch of a tree. ", | |
33 | "'Did you say pig, or fig?' said the Cat. ", | |
34 | "'I said pig,' replied Alice; 'and I wish you wouldn't keep appearing and vanishing so suddenly: you make one quite giddy.' ", | |
35 | "'All right,' said the Cat; and this time it vanished quite slowly, beginning with the end of the tail, and ending with the grin, which remained some time after the rest of it had gone. ", | |
36 | "'Well! I've often seen a cat without a grin,' thought Alice; 'but a grin without a cat! It's the most curious thing I ever saw in my life!' " | |
37 | ]; | |
38 | ||
39 | for (var i = 0; i < ps.length; i++) { | |
40 | var p = document.createElement('p'); | |
41 | // a slightly odd-looking trick to replace all occurrences of a substring in a string | |
42 | // http://stackoverflow.com/questions/1144783/replacing-all-occurrences-of-a-string-in-javascript#1145525 | |
43 | var text = ps[i].split('grin').join('<span style="color: black">grin</span>'); | |
44 | text = text.split('Cat').join('Text'); | |
45 | text = text.split('Puss').join('Text'); | |
46 | text = text.split('cat').join('text'); | |
47 | text = text.split('walked').join('read'); | |
48 | text = text.split('walk').join('read'); | |
49 | p.innerHTML = text; | |
50 | container.appendChild(p); | |
51 | } | |
52 | ||
53 | var scale = 1000; | |
54 | var alpha = scale; | |
55 | var intervalId = setInterval(function() { | |
56 | var col = "rgba(0,0,0," + (alpha / scale) + ")"; | |
57 | container.style.color = col; | |
58 | if (alpha > 0) alpha -= 1; | |
59 | }, 100); | |
60 | } |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var t = new Chzrxl(); | |
13 | var canvas = yoob.makeCanvas(container, 500, 500); | |
14 | yoob.makeLineBreak(container); | |
15 | var button = yoob.makeButton(container, 'Restart', function() { | |
16 | t.restart(); | |
17 | }); | |
18 | container.appendChild(document.createTextNode("Percent to hold fixed:")); | |
19 | var slider = yoob.makeSlider(container, 0, 100, 10, function(v) { | |
20 | t.setPercentToHoldFixed(v); | |
21 | }); | |
22 | t.init({ | |
23 | 'canvas': canvas, | |
24 | 'percentToHoldFixed': 10 | |
25 | }); | |
26 | } | |
27 | }; | |
28 | document.body.appendChild(elem); | |
29 | } | |
30 | } | |
31 | ||
32 | var twopi = Math.PI * 2; | |
33 | var degrees = twopi / 360; | |
34 | ||
35 | var balls = []; | |
36 | ||
37 | Ball = function() { | |
38 | this.init = function(x, y, pt1, pt2, rate, phase, radius, style) { | |
39 | this.x = x; | |
40 | this.y = y; | |
41 | this.pt1 = pt1; | |
42 | this.pt2 = pt2; | |
43 | this.style = style; | |
44 | this.radius = radius; | |
45 | this.rate = rate; | |
46 | this.phase = phase; | |
47 | return this; | |
48 | }; | |
49 | ||
50 | this.updateXY = function(p) { | |
51 | // p is between 0.0 (at pt1) and 1.0 (at pt2) | |
52 | var x1 = balls[this.pt1].x; | |
53 | var x2 = balls[this.pt2].x; | |
54 | this.x = (x2 - x1) * p + x1; // + Math.random() * 30 - this.tendency; | |
55 | var y1 = balls[this.pt1].y; | |
56 | var y2 = balls[this.pt2].y; | |
57 | this.y = (y2 - y1) * p + y1; // + Math.random() * 30 - this.tendency; | |
58 | }; | |
59 | ||
60 | this.getPct = function(t) { | |
61 | return (Math.sin((t + this.phase) / this.rate) + 1) / 2; | |
62 | }; | |
63 | ||
64 | this.draw = function(ctx, t) { | |
65 | ctx.beginPath(); | |
66 | ctx.fillStyle = this.style; | |
67 | ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false); | |
68 | ctx.fill(); | |
69 | }; | |
70 | }; | |
71 | ||
72 | Chzrxl = function() { | |
73 | var ctx = undefined; | |
74 | var canvas = undefined; | |
75 | var numBalls = 200; | |
76 | var pctToHoldFixedCtrl; | |
77 | var options; | |
78 | var percentToHoldFixed; | |
79 | ||
80 | var t = 0; | |
81 | ||
82 | this.init = function(opts) { | |
83 | options = opts || {}; | |
84 | ||
85 | canvas = options.canvas; | |
86 | ctx = canvas.getContext("2d"); | |
87 | ||
88 | percentToHoldFixed = options.percentToHoldFixed || 10; | |
89 | ||
90 | this.restart(); | |
91 | this.animation = (new yoob.Animation()).init({ | |
92 | object: this | |
93 | }); | |
94 | this.animation.start(); | |
95 | }; | |
96 | ||
97 | this.restart = function() { | |
98 | balls = []; | |
99 | for (var i = 0; i < numBalls; i++) { | |
100 | var x = Math.random() * canvas.width; | |
101 | var y = Math.random() * canvas.height; | |
102 | var pt1 = i; | |
103 | var pt2; | |
104 | while (pt1 === i || pt2 === i || pt2 === pt1) { | |
105 | pt1 = Math.floor(Math.random() * numBalls); | |
106 | pt2 = Math.floor(Math.random() * numBalls); | |
107 | } | |
108 | var rate = Math.random() * 100 + 100; | |
109 | var phase = Math.floor(Math.random() * 110); | |
110 | var radius = Math.floor(Math.random() * 10) + 5; | |
111 | var style = "hsl(" + Math.floor(Math.random() * 256) + ",10%,50%)"; | |
112 | var ball = new Ball().init(x, y, pt1, pt2, rate, phase, radius, style); | |
113 | ball.tendency = 14 + Math.random() * 2; | |
114 | balls.push(ball); | |
115 | } | |
116 | }; | |
117 | ||
118 | this.draw = function() { | |
119 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
120 | ||
121 | for (var i = 0; i < balls.length; i++) { | |
122 | balls[i].draw(ctx, t); | |
123 | } | |
124 | }; | |
125 | ||
126 | this.update = function() { | |
127 | var numFixed = balls.length * (percentToHoldFixed / 100); | |
128 | for (var i = 0; i < balls.length; i++) { | |
129 | if (i < numFixed) continue; | |
130 | balls[i].updateXY(balls[i].getPct(t)); | |
131 | } | |
132 | t += 1; | |
133 | }; | |
134 | ||
135 | this.setPercentToHoldFixed = function(value) { | |
136 | percentToHoldFixed = value; | |
137 | }; | |
138 | }; |
16 | 16 | <div id="container"></div> |
17 | 17 | |
18 | 18 | </body> |
19 | <script src="chzrxl.js"></script> | |
19 | <script src="index.js"></script> | |
20 | 20 | <script> |
21 | 21 | launch('../common-yoob.js-0.11/', 'container'); |
22 | 22 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var t = new Chzrxl(); | |
13 | var canvas = yoob.makeCanvas(container, 500, 500); | |
14 | yoob.makeLineBreak(container); | |
15 | var button = yoob.makeButton(container, 'Restart', function() { | |
16 | t.restart(); | |
17 | }); | |
18 | container.appendChild(document.createTextNode("Percent to hold fixed:")); | |
19 | var slider = yoob.makeSlider(container, 0, 100, 10, function(v) { | |
20 | t.setPercentToHoldFixed(v); | |
21 | }); | |
22 | t.init({ | |
23 | 'canvas': canvas, | |
24 | 'percentToHoldFixed': 10 | |
25 | }); | |
26 | } | |
27 | }; | |
28 | document.body.appendChild(elem); | |
29 | } | |
30 | } | |
31 | ||
32 | var twopi = Math.PI * 2; | |
33 | var degrees = twopi / 360; | |
34 | ||
35 | var balls = []; | |
36 | ||
37 | Ball = function() { | |
38 | this.init = function(x, y, pt1, pt2, rate, phase, radius, style) { | |
39 | this.x = x; | |
40 | this.y = y; | |
41 | this.pt1 = pt1; | |
42 | this.pt2 = pt2; | |
43 | this.style = style; | |
44 | this.radius = radius; | |
45 | this.rate = rate; | |
46 | this.phase = phase; | |
47 | return this; | |
48 | }; | |
49 | ||
50 | this.updateXY = function(p) { | |
51 | // p is between 0.0 (at pt1) and 1.0 (at pt2) | |
52 | var x1 = balls[this.pt1].x; | |
53 | var x2 = balls[this.pt2].x; | |
54 | this.x = (x2 - x1) * p + x1; // + Math.random() * 30 - this.tendency; | |
55 | var y1 = balls[this.pt1].y; | |
56 | var y2 = balls[this.pt2].y; | |
57 | this.y = (y2 - y1) * p + y1; // + Math.random() * 30 - this.tendency; | |
58 | }; | |
59 | ||
60 | this.getPct = function(t) { | |
61 | return (Math.sin((t + this.phase) / this.rate) + 1) / 2; | |
62 | }; | |
63 | ||
64 | this.draw = function(ctx, t) { | |
65 | ctx.beginPath(); | |
66 | ctx.fillStyle = this.style; | |
67 | ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false); | |
68 | ctx.fill(); | |
69 | }; | |
70 | }; | |
71 | ||
72 | Chzrxl = function() { | |
73 | var ctx = undefined; | |
74 | var canvas = undefined; | |
75 | var numBalls = 200; | |
76 | var pctToHoldFixedCtrl; | |
77 | var options; | |
78 | var percentToHoldFixed; | |
79 | ||
80 | var t = 0; | |
81 | ||
82 | this.init = function(opts) { | |
83 | options = opts || {}; | |
84 | ||
85 | canvas = options.canvas; | |
86 | ctx = canvas.getContext("2d"); | |
87 | ||
88 | percentToHoldFixed = options.percentToHoldFixed || 10; | |
89 | ||
90 | this.restart(); | |
91 | this.animation = (new yoob.Animation()).init({ | |
92 | object: this | |
93 | }); | |
94 | this.animation.start(); | |
95 | }; | |
96 | ||
97 | this.restart = function() { | |
98 | balls = []; | |
99 | for (var i = 0; i < numBalls; i++) { | |
100 | var x = Math.random() * canvas.width; | |
101 | var y = Math.random() * canvas.height; | |
102 | var pt1 = i; | |
103 | var pt2; | |
104 | while (pt1 === i || pt2 === i || pt2 === pt1) { | |
105 | pt1 = Math.floor(Math.random() * numBalls); | |
106 | pt2 = Math.floor(Math.random() * numBalls); | |
107 | } | |
108 | var rate = Math.random() * 100 + 100; | |
109 | var phase = Math.floor(Math.random() * 110); | |
110 | var radius = Math.floor(Math.random() * 10) + 5; | |
111 | var style = "hsl(" + Math.floor(Math.random() * 256) + ",10%,50%)"; | |
112 | var ball = new Ball().init(x, y, pt1, pt2, rate, phase, radius, style); | |
113 | ball.tendency = 14 + Math.random() * 2; | |
114 | balls.push(ball); | |
115 | } | |
116 | }; | |
117 | ||
118 | this.draw = function() { | |
119 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
120 | ||
121 | for (var i = 0; i < balls.length; i++) { | |
122 | balls[i].draw(ctx, t); | |
123 | } | |
124 | }; | |
125 | ||
126 | this.update = function() { | |
127 | var numFixed = balls.length * (percentToHoldFixed / 100); | |
128 | for (var i = 0; i < balls.length; i++) { | |
129 | if (i < numFixed) continue; | |
130 | balls[i].updateXY(balls[i].getPct(t)); | |
131 | } | |
132 | t += 1; | |
133 | }; | |
134 | ||
135 | this.setPercentToHoldFixed = function(value) { | |
136 | percentToHoldFixed = value; | |
137 | }; | |
138 | }; |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var canvas = yoob.makeCanvas(container, 800, 400); | |
13 | yoob.makeLineBreak(container); | |
14 | var gewgaw = new CircusXamulus().init({ canvas: canvas }); | |
15 | yoob.makeButton(container, "Reset", function() { gewgaw.reset(); }); | |
16 | } | |
17 | }; | |
18 | document.body.appendChild(elem); | |
19 | } | |
20 | } | |
21 | ||
22 | ||
23 | var TWO_PI = Math.PI * 2; | |
24 | ||
25 | ||
26 | Circle = function() { | |
27 | this.init = function(x, y, r) { | |
28 | this.x = x; | |
29 | this.y = y; | |
30 | this.r = r; | |
31 | this.drawn = false; | |
32 | ||
33 | return this; | |
34 | }; | |
35 | ||
36 | this.draw = function(ctx) { | |
37 | ctx.beginPath(); | |
38 | ctx.lineWidth = 2; | |
39 | ctx.strokeStyle = "black"; | |
40 | ctx.arc(this.x, this.y, this.r, 0, TWO_PI, false); | |
41 | ctx.stroke(); | |
42 | this.drawn = true; | |
43 | ||
44 | if (false) { | |
45 | /* pick two points on the circle and draw a chord */ | |
46 | if (this.r > 30) { | |
47 | var th1 = Math.random() * TWO_PI; | |
48 | var x1 = this.x + Math.cos(th1) * this.r; | |
49 | var y1 = this.y + Math.sin(th1) * this.r; | |
50 | var th2 = Math.random() * TWO_PI; | |
51 | var x2 = this.x + Math.cos(th2) * this.r; | |
52 | var y2 = this.y + Math.sin(th2) * this.r; | |
53 | ctx.beginPath(); | |
54 | ctx.moveTo(x1, y1); | |
55 | ctx.lineTo(x2, y2); | |
56 | ctx.stroke(); | |
57 | } | |
58 | } | |
59 | }; | |
60 | }; | |
61 | ||
62 | ||
63 | CircusXamulus = function() { | |
64 | ||
65 | this.init = function(cfg) { | |
66 | this.canvas = cfg.canvas; | |
67 | this.ctx = this.canvas.getContext("2d"); | |
68 | this.reset(); | |
69 | this.animation = (new yoob.Animation()).init({ | |
70 | object: this, | |
71 | tickTime: 1000.0 / 50.0 | |
72 | }).start(); | |
73 | ||
74 | return this; | |
75 | }; | |
76 | ||
77 | this.reset = function() { | |
78 | this.ctx.fillStyle = "white"; | |
79 | this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); | |
80 | this.circles = []; | |
81 | }; | |
82 | ||
83 | this.draw = function() { | |
84 | for (var i = 0; i < this.circles.length; i++) { | |
85 | var circle = this.circles[i]; | |
86 | if (!circle.drawn) { | |
87 | circle.draw(this.ctx); | |
88 | } | |
89 | } | |
90 | }; | |
91 | ||
92 | this.update = function() { | |
93 | if (this.circles.length > 2000) return; | |
94 | var tries = 0; | |
95 | var done = false; | |
96 | while (!done && tries < 100) { | |
97 | tries++; | |
98 | done = true; | |
99 | var r = Math.floor(Math.random() * 50); | |
100 | var x = r + Math.random() * (this.canvas.width - r*2); | |
101 | var y = r + Math.random() * (this.canvas.height - r*2); | |
102 | for (var i = 0; i < this.circles.length; i++) { | |
103 | var circle = this.circles[i]; | |
104 | var dx = x - circle.x; | |
105 | var dy = y - circle.y; | |
106 | var d = Math.sqrt(dx * dx + dy * dy); | |
107 | if (d < circle.r) { | |
108 | done = false; | |
109 | break; | |
110 | } else if (r > (d - circle.r)) { | |
111 | r = (d - circle.r); | |
112 | } | |
113 | } | |
114 | } | |
115 | this.circles.push(new Circle().init(x, y, r)); | |
116 | }; | |
117 | }; |
9 | 9 | <div id="container"></div> |
10 | 10 | |
11 | 11 | </body> |
12 | <script src="circus-xamulus.js"></script> | |
12 | <script src="index.js"></script> | |
13 | 13 | <script> |
14 | 14 | launch('../common-yoob.js-0.11/', 'container'); |
15 | 15 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var canvas = yoob.makeCanvas(container, 800, 400); | |
13 | yoob.makeLineBreak(container); | |
14 | var gewgaw = new CircusXamulus().init({ canvas: canvas }); | |
15 | yoob.makeButton(container, "Reset", function() { gewgaw.reset(); }); | |
16 | } | |
17 | }; | |
18 | document.body.appendChild(elem); | |
19 | } | |
20 | } | |
21 | ||
22 | ||
23 | var TWO_PI = Math.PI * 2; | |
24 | ||
25 | ||
26 | Circle = function() { | |
27 | this.init = function(x, y, r) { | |
28 | this.x = x; | |
29 | this.y = y; | |
30 | this.r = r; | |
31 | this.drawn = false; | |
32 | ||
33 | return this; | |
34 | }; | |
35 | ||
36 | this.draw = function(ctx) { | |
37 | ctx.beginPath(); | |
38 | ctx.lineWidth = 2; | |
39 | ctx.strokeStyle = "black"; | |
40 | ctx.arc(this.x, this.y, this.r, 0, TWO_PI, false); | |
41 | ctx.stroke(); | |
42 | this.drawn = true; | |
43 | ||
44 | if (false) { | |
45 | /* pick two points on the circle and draw a chord */ | |
46 | if (this.r > 30) { | |
47 | var th1 = Math.random() * TWO_PI; | |
48 | var x1 = this.x + Math.cos(th1) * this.r; | |
49 | var y1 = this.y + Math.sin(th1) * this.r; | |
50 | var th2 = Math.random() * TWO_PI; | |
51 | var x2 = this.x + Math.cos(th2) * this.r; | |
52 | var y2 = this.y + Math.sin(th2) * this.r; | |
53 | ctx.beginPath(); | |
54 | ctx.moveTo(x1, y1); | |
55 | ctx.lineTo(x2, y2); | |
56 | ctx.stroke(); | |
57 | } | |
58 | } | |
59 | }; | |
60 | }; | |
61 | ||
62 | ||
63 | CircusXamulus = function() { | |
64 | ||
65 | this.init = function(cfg) { | |
66 | this.canvas = cfg.canvas; | |
67 | this.ctx = this.canvas.getContext("2d"); | |
68 | this.reset(); | |
69 | this.animation = (new yoob.Animation()).init({ | |
70 | object: this, | |
71 | tickTime: 1000.0 / 50.0 | |
72 | }).start(); | |
73 | ||
74 | return this; | |
75 | }; | |
76 | ||
77 | this.reset = function() { | |
78 | this.ctx.fillStyle = "white"; | |
79 | this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); | |
80 | this.circles = []; | |
81 | }; | |
82 | ||
83 | this.draw = function() { | |
84 | for (var i = 0; i < this.circles.length; i++) { | |
85 | var circle = this.circles[i]; | |
86 | if (!circle.drawn) { | |
87 | circle.draw(this.ctx); | |
88 | } | |
89 | } | |
90 | }; | |
91 | ||
92 | this.update = function() { | |
93 | if (this.circles.length > 2000) return; | |
94 | var tries = 0; | |
95 | var done = false; | |
96 | while (!done && tries < 100) { | |
97 | tries++; | |
98 | done = true; | |
99 | var r = Math.floor(Math.random() * 50); | |
100 | var x = r + Math.random() * (this.canvas.width - r*2); | |
101 | var y = r + Math.random() * (this.canvas.height - r*2); | |
102 | for (var i = 0; i < this.circles.length; i++) { | |
103 | var circle = this.circles[i]; | |
104 | var dx = x - circle.x; | |
105 | var dy = y - circle.y; | |
106 | var d = Math.sqrt(dx * dx + dy * dy); | |
107 | if (d < circle.r) { | |
108 | done = false; | |
109 | break; | |
110 | } else if (r > (d - circle.r)) { | |
111 | r = (d - circle.r); | |
112 | } | |
113 | } | |
114 | } | |
115 | this.circles.push(new Circle().init(x, y, r)); | |
116 | }; | |
117 | }; |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "animation.js", | |
5 | "full-screen-detector.js" | |
6 | ]; | |
7 | var loaded = 0; | |
8 | for (var i = 0; i < deps.length; i++) { | |
9 | var elem = document.createElement('script'); | |
10 | elem.src = prefix + deps[i]; | |
11 | elem.onload = function() { | |
12 | if (++loaded == deps.length) { | |
13 | var container = document.getElementById(containerId); | |
14 | ||
15 | var t = new Cyclobots(); | |
16 | var canvas = yoob.makeCanvas(container); | |
17 | ||
18 | if (config.width) canvas.width = config.width; | |
19 | if (config.height) canvas.height = config.height; | |
20 | ||
21 | var controlPanel = yoob.makeDiv(container); | |
22 | var showAngles = yoob.makeCheckbox( | |
23 | controlPanel, false, "show angles", t.setDrawAngles | |
24 | ); | |
25 | var button = yoob.makeButton( | |
26 | controlPanel, 'Revolution!', t.shuffle | |
27 | ); | |
28 | ||
29 | var resize = function() { | |
30 | canvas.width = canvas.clientWidth; | |
31 | canvas.height = canvas.clientHeight; | |
32 | }; | |
33 | ||
34 | window.onload = function() { | |
35 | resize(); | |
36 | t.init(canvas); | |
37 | }; | |
38 | window.onresize = resize; | |
39 | ||
40 | var header = document.getElementsByTagName('header')[0]; | |
41 | ||
42 | new yoob.FullScreenDetector({ | |
43 | onchange: function(fullScreen) { | |
44 | if (fullScreen) { | |
45 | canvas.style.width = "100%"; | |
46 | canvas.style.height = "100%"; | |
47 | if (header) header.style.display = "none"; | |
48 | controlPanel.style.display = "none"; | |
49 | resize(); | |
50 | } else { | |
51 | canvas.style.width = null; | |
52 | canvas.style.height = null; | |
53 | if (header) header.style.display = "block"; | |
54 | controlPanel.style.display = "block"; | |
55 | resize(); | |
56 | } | |
57 | } | |
58 | }); | |
59 | ||
60 | } | |
61 | }; | |
62 | document.body.appendChild(elem); | |
63 | } | |
64 | } | |
65 | ||
66 | var twopi = Math.PI * 2; | |
67 | var degrees = twopi / 360; | |
68 | ||
69 | Cyclobot = function() { | |
70 | this.init = function(x, y, theta, speed, dexterity, next) { | |
71 | this.x = x; | |
72 | this.y = y; | |
73 | this.theta = theta; // radians = (degrees / 360) * (Math.PI * 2); | |
74 | this.speed = speed; | |
75 | this.dexterity = dexterity; // radians | |
76 | this.next = next; | |
77 | this.radius = 10; | |
78 | this.style = "red"; | |
79 | }; | |
80 | ||
81 | this.move = function() { | |
82 | var dx = this.speed * Math.cos(this.theta); | |
83 | var dy = this.speed * Math.sin(this.theta); | |
84 | ||
85 | this.x += dx; | |
86 | this.y += dy; | |
87 | }; | |
88 | ||
89 | this.adjust = function() { | |
90 | var rho = Math.atan2(this.y - this.next.y, this.x - this.next.x) + Math.PI; | |
91 | this.rho_deg = Math.floor(rho / degrees); | |
92 | ||
93 | this.theta_deg = Math.floor(this.theta / degrees); | |
94 | ||
95 | // stolen from http://prog21.dadgum.com/96.html | |
96 | var angle_diff = (this.rho_deg - this.theta_deg + 540) % 360 - 180; | |
97 | if (angle_diff < 0) { | |
98 | this.theta -= this.dexterity; | |
99 | //this.style = "blue"; | |
100 | } else { | |
101 | this.theta += this.dexterity; | |
102 | //this.style = "red"; | |
103 | } | |
104 | if (this.theta <= 0) this.theta += twopi; | |
105 | if (this.theta > twopi) this.theta -= twopi; | |
106 | }; | |
107 | ||
108 | this.draw = function(ctx) { | |
109 | ctx.beginPath(); | |
110 | ctx.fillStyle = this.style; | |
111 | ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false); | |
112 | ctx.fill(); | |
113 | }; | |
114 | ||
115 | this.drawAngles = function(ctx) { | |
116 | ctx.beginPath(); | |
117 | ctx.lineWidth = 1; | |
118 | ctx.strokeStyle = "black"; | |
119 | ctx.moveTo(this.x, this.y); | |
120 | var dx = this.radius * Math.cos(this.theta); | |
121 | var dy = this.radius * Math.sin(this.theta); | |
122 | ctx.lineTo(this.x + dx, this.y + dy); | |
123 | ctx.stroke(); | |
124 | ||
125 | ctx.beginPath(); | |
126 | ctx.lineWidth = 1; | |
127 | ctx.strokeStyle = "rgba(0, 255, 0, 0.5)"; | |
128 | ctx.moveTo(this.x, this.y); | |
129 | ctx.lineTo(this.next.x, this.next.y); | |
130 | ctx.stroke(); | |
131 | }; | |
132 | }; | |
133 | ||
134 | Cyclobots = function() { | |
135 | var ctx = undefined; | |
136 | var canvas = undefined; | |
137 | var selected = undefined; | |
138 | ||
139 | var bots = []; | |
140 | var numbots = 50; | |
141 | var drawAngles = false; | |
142 | var dragging; | |
143 | var lastX = undefined; | |
144 | var lastY = undefined; | |
145 | ||
146 | this.init = function(c) { | |
147 | canvas = c; | |
148 | ctx = canvas.getContext("2d"); | |
149 | ||
150 | for (var i = 0; i < numbots; i++) { | |
151 | bots[i] = new Cyclobot(); | |
152 | bots[i].init( | |
153 | /*x*/50 + Math.random() * (canvas.width - 100), | |
154 | /*y*/50 + Math.random() * (canvas.height - 100), | |
155 | /*theta*/Math.random() * twopi, | |
156 | /*speed*/2, | |
157 | /*dexterity*/2 * degrees, null | |
158 | ); | |
159 | } | |
160 | for (var i = 0; i < numbots-1; i++) { | |
161 | bots[i].next = bots[i+1]; | |
162 | } | |
163 | bots[numbots-1].next = bots[0]; | |
164 | ||
165 | var self = this; | |
166 | canvas.addEventListener('mousedown', function(e) { | |
167 | dragging = true; | |
168 | lastX = e.pageX - canvas.offsetLeft; | |
169 | lastY = e.pageY - canvas.offsetTop; | |
170 | canvas.style.cursor = "move"; | |
171 | e.preventDefault(); | |
172 | }); | |
173 | canvas.addEventListener('mouseup', function(e) { | |
174 | dragging = false; | |
175 | canvas.style.cursor = "auto"; | |
176 | e.preventDefault(); | |
177 | }); | |
178 | canvas.addEventListener('mousemove', function(e) { | |
179 | if (dragging) { | |
180 | var newX = e.pageX - canvas.offsetLeft; | |
181 | var newY = e.pageY - canvas.offsetTop; | |
182 | var deltaX = newX - lastX; | |
183 | var deltaY = newY - lastY; | |
184 | self.scroll(deltaX, deltaY); | |
185 | lastX = newX; | |
186 | lastY = newY; | |
187 | } | |
188 | e.preventDefault(); | |
189 | }); | |
190 | ||
191 | canvas.addEventListener('touchstart', function(e) { | |
192 | var t = e.touches[0]; | |
193 | dragging = true; | |
194 | lastX = t.pageX - canvas.offsetLeft; | |
195 | lastY = t.pageY - canvas.offsetTop; | |
196 | canvas.style.cursor = "move"; | |
197 | e.preventDefault(); | |
198 | }); | |
199 | canvas.addEventListener('touchend', function(e) { | |
200 | dragging = false; | |
201 | canvas.style.cursor = "auto"; | |
202 | e.preventDefault(); | |
203 | }); | |
204 | canvas.addEventListener('touchmove', function(e) { | |
205 | if (dragging) { | |
206 | var t = e.touches[0]; | |
207 | var newX = t.pageX - canvas.offsetLeft; | |
208 | var newY = t.pageY - canvas.offsetTop; | |
209 | var deltaX = newX - lastX; | |
210 | var deltaY = newY - lastY; | |
211 | self.scroll(deltaX, deltaY); | |
212 | lastX = newX; | |
213 | lastY = newY; | |
214 | } | |
215 | e.preventDefault(); | |
216 | }); | |
217 | ||
218 | this.animation = (new yoob.Animation()).init({ | |
219 | object: this | |
220 | }); | |
221 | this.animation.start(); | |
222 | }; | |
223 | ||
224 | this.setDrawAngles = function(b) { | |
225 | drawAngles = b; | |
226 | }; | |
227 | ||
228 | this.selectABot = function(canvasX, canvasY) { | |
229 | var selected = undefined; | |
230 | for (var i = 0; i < numbots; i++) { | |
231 | if (Math.abs(canvasX - bots[i].x) < bots[i].radius && | |
232 | Math.abs(canvasY - bots[i].y) < bots[i].radius) { | |
233 | selected = i; | |
234 | break; | |
235 | } | |
236 | } | |
237 | if (selected !== undefined) { | |
238 | var bot = bots[selected]; | |
239 | alert("#" + selected + " x=" + bot.x + " y=" + bot.y + | |
240 | " theta=" + bot.theta_deg + " rho=" + | |
241 | bot.rho_deg + " adiff=" + bot.adiff / degrees); | |
242 | } | |
243 | }; | |
244 | ||
245 | this.draw = function() { | |
246 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
247 | ||
248 | for (var i = 0; i < bots.length; i++) { | |
249 | var bot = bots[i]; | |
250 | bot.draw(ctx); | |
251 | if (drawAngles) { | |
252 | bot.drawAngles(ctx); | |
253 | } | |
254 | } | |
255 | }; | |
256 | ||
257 | this.update = function() { | |
258 | for (var i = 0; i < bots.length; i++) { | |
259 | var bot = bots[i]; | |
260 | bot.move(); | |
261 | bot.adjust(); | |
262 | } | |
263 | }; | |
264 | ||
265 | this.scroll = function(dx, dy) { | |
266 | for (var i = 0; i < numbots; i++) { | |
267 | bots[i].x += dx; | |
268 | bots[i].y += dy; | |
269 | } | |
270 | }; | |
271 | ||
272 | this.massConfusion = function() { | |
273 | for (var i = 0; i < numbots-1; i++) { | |
274 | bots[i].theta = Math.random() * twopi; | |
275 | } | |
276 | }; | |
277 | ||
278 | this.shuffle = function() { | |
279 | var newBots = []; | |
280 | while (bots.length > 0) { | |
281 | newBots.push(bots.splice(Math.random() * bots.length, 1)[0]); | |
282 | } | |
283 | bots = newBots; | |
284 | for (var i = 0; i < numbots-1; i++) { | |
285 | bots[i].next = bots[i+1]; | |
286 | } | |
287 | bots[numbots-1].next = bots[0]; | |
288 | }; | |
289 | }; |
34 | 34 | </header> |
35 | 35 | |
36 | 36 | </body> |
37 | <script src="cyclobots.js"></script> | |
37 | <script src="index.js"></script> | |
38 | 38 | <script> |
39 | 39 | launch('../common-yoob.js-0.11/', 'container'); |
40 | 40 | </script> |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "animation.js", | |
5 | "full-screen-detector.js" | |
6 | ]; | |
7 | var loaded = 0; | |
8 | for (var i = 0; i < deps.length; i++) { | |
9 | var elem = document.createElement('script'); | |
10 | elem.src = prefix + deps[i]; | |
11 | elem.onload = function() { | |
12 | if (++loaded == deps.length) { | |
13 | var container = document.getElementById(containerId); | |
14 | ||
15 | var t = new Cyclobots(); | |
16 | var canvas = yoob.makeCanvas(container); | |
17 | ||
18 | if (config.width) canvas.width = config.width; | |
19 | if (config.height) canvas.height = config.height; | |
20 | ||
21 | var controlPanel = yoob.makeDiv(container); | |
22 | var showAngles = yoob.makeCheckbox( | |
23 | controlPanel, false, "show angles", t.setDrawAngles | |
24 | ); | |
25 | var button = yoob.makeButton( | |
26 | controlPanel, 'Revolution!', t.shuffle | |
27 | ); | |
28 | ||
29 | var resize = function() { | |
30 | canvas.width = canvas.clientWidth; | |
31 | canvas.height = canvas.clientHeight; | |
32 | }; | |
33 | ||
34 | window.onload = function() { | |
35 | resize(); | |
36 | t.init(canvas); | |
37 | }; | |
38 | window.onresize = resize; | |
39 | ||
40 | var header = document.getElementsByTagName('header')[0]; | |
41 | ||
42 | new yoob.FullScreenDetector({ | |
43 | onchange: function(fullScreen) { | |
44 | if (fullScreen) { | |
45 | canvas.style.width = "100%"; | |
46 | canvas.style.height = "100%"; | |
47 | if (header) header.style.display = "none"; | |
48 | controlPanel.style.display = "none"; | |
49 | resize(); | |
50 | } else { | |
51 | canvas.style.width = null; | |
52 | canvas.style.height = null; | |
53 | if (header) header.style.display = "block"; | |
54 | controlPanel.style.display = "block"; | |
55 | resize(); | |
56 | } | |
57 | } | |
58 | }); | |
59 | ||
60 | } | |
61 | }; | |
62 | document.body.appendChild(elem); | |
63 | } | |
64 | } | |
65 | ||
66 | var twopi = Math.PI * 2; | |
67 | var degrees = twopi / 360; | |
68 | ||
69 | Cyclobot = function() { | |
70 | this.init = function(x, y, theta, speed, dexterity, next) { | |
71 | this.x = x; | |
72 | this.y = y; | |
73 | this.theta = theta; // radians = (degrees / 360) * (Math.PI * 2); | |
74 | this.speed = speed; | |
75 | this.dexterity = dexterity; // radians | |
76 | this.next = next; | |
77 | this.radius = 10; | |
78 | this.style = "red"; | |
79 | }; | |
80 | ||
81 | this.move = function() { | |
82 | var dx = this.speed * Math.cos(this.theta); | |
83 | var dy = this.speed * Math.sin(this.theta); | |
84 | ||
85 | this.x += dx; | |
86 | this.y += dy; | |
87 | }; | |
88 | ||
89 | this.adjust = function() { | |
90 | var rho = Math.atan2(this.y - this.next.y, this.x - this.next.x) + Math.PI; | |
91 | this.rho_deg = Math.floor(rho / degrees); | |
92 | ||
93 | this.theta_deg = Math.floor(this.theta / degrees); | |
94 | ||
95 | // stolen from http://prog21.dadgum.com/96.html | |
96 | var angle_diff = (this.rho_deg - this.theta_deg + 540) % 360 - 180; | |
97 | if (angle_diff < 0) { | |
98 | this.theta -= this.dexterity; | |
99 | //this.style = "blue"; | |
100 | } else { | |
101 | this.theta += this.dexterity; | |
102 | //this.style = "red"; | |
103 | } | |
104 | if (this.theta <= 0) this.theta += twopi; | |
105 | if (this.theta > twopi) this.theta -= twopi; | |
106 | }; | |
107 | ||
108 | this.draw = function(ctx) { | |
109 | ctx.beginPath(); | |
110 | ctx.fillStyle = this.style; | |
111 | ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false); | |
112 | ctx.fill(); | |
113 | }; | |
114 | ||
115 | this.drawAngles = function(ctx) { | |
116 | ctx.beginPath(); | |
117 | ctx.lineWidth = 1; | |
118 | ctx.strokeStyle = "black"; | |
119 | ctx.moveTo(this.x, this.y); | |
120 | var dx = this.radius * Math.cos(this.theta); | |
121 | var dy = this.radius * Math.sin(this.theta); | |
122 | ctx.lineTo(this.x + dx, this.y + dy); | |
123 | ctx.stroke(); | |
124 | ||
125 | ctx.beginPath(); | |
126 | ctx.lineWidth = 1; | |
127 | ctx.strokeStyle = "rgba(0, 255, 0, 0.5)"; | |
128 | ctx.moveTo(this.x, this.y); | |
129 | ctx.lineTo(this.next.x, this.next.y); | |
130 | ctx.stroke(); | |
131 | }; | |
132 | }; | |
133 | ||
134 | Cyclobots = function() { | |
135 | var ctx = undefined; | |
136 | var canvas = undefined; | |
137 | var selected = undefined; | |
138 | ||
139 | var bots = []; | |
140 | var numbots = 50; | |
141 | var drawAngles = false; | |
142 | var dragging; | |
143 | var lastX = undefined; | |
144 | var lastY = undefined; | |
145 | ||
146 | this.init = function(c) { | |
147 | canvas = c; | |
148 | ctx = canvas.getContext("2d"); | |
149 | ||
150 | for (var i = 0; i < numbots; i++) { | |
151 | bots[i] = new Cyclobot(); | |
152 | bots[i].init( | |
153 | /*x*/50 + Math.random() * (canvas.width - 100), | |
154 | /*y*/50 + Math.random() * (canvas.height - 100), | |
155 | /*theta*/Math.random() * twopi, | |
156 | /*speed*/2, | |
157 | /*dexterity*/2 * degrees, null | |
158 | ); | |
159 | } | |
160 | for (var i = 0; i < numbots-1; i++) { | |
161 | bots[i].next = bots[i+1]; | |
162 | } | |
163 | bots[numbots-1].next = bots[0]; | |
164 | ||
165 | var self = this; | |
166 | canvas.addEventListener('mousedown', function(e) { | |
167 | dragging = true; | |
168 | lastX = e.pageX - canvas.offsetLeft; | |
169 | lastY = e.pageY - canvas.offsetTop; | |
170 | canvas.style.cursor = "move"; | |
171 | e.preventDefault(); | |
172 | }); | |
173 | canvas.addEventListener('mouseup', function(e) { | |
174 | dragging = false; | |
175 | canvas.style.cursor = "auto"; | |
176 | e.preventDefault(); | |
177 | }); | |
178 | canvas.addEventListener('mousemove', function(e) { | |
179 | if (dragging) { | |
180 | var newX = e.pageX - canvas.offsetLeft; | |
181 | var newY = e.pageY - canvas.offsetTop; | |
182 | var deltaX = newX - lastX; | |
183 | var deltaY = newY - lastY; | |
184 | self.scroll(deltaX, deltaY); | |
185 | lastX = newX; | |
186 | lastY = newY; | |
187 | } | |
188 | e.preventDefault(); | |
189 | }); | |
190 | ||
191 | canvas.addEventListener('touchstart', function(e) { | |
192 | var t = e.touches[0]; | |
193 | dragging = true; | |
194 | lastX = t.pageX - canvas.offsetLeft; | |
195 | lastY = t.pageY - canvas.offsetTop; | |
196 | canvas.style.cursor = "move"; | |
197 | e.preventDefault(); | |
198 | }); | |
199 | canvas.addEventListener('touchend', function(e) { | |
200 | dragging = false; | |
201 | canvas.style.cursor = "auto"; | |
202 | e.preventDefault(); | |
203 | }); | |
204 | canvas.addEventListener('touchmove', function(e) { | |
205 | if (dragging) { | |
206 | var t = e.touches[0]; | |
207 | var newX = t.pageX - canvas.offsetLeft; | |
208 | var newY = t.pageY - canvas.offsetTop; | |
209 | var deltaX = newX - lastX; | |
210 | var deltaY = newY - lastY; | |
211 | self.scroll(deltaX, deltaY); | |
212 | lastX = newX; | |
213 | lastY = newY; | |
214 | } | |
215 | e.preventDefault(); | |
216 | }); | |
217 | ||
218 | this.animation = (new yoob.Animation()).init({ | |
219 | object: this | |
220 | }); | |
221 | this.animation.start(); | |
222 | }; | |
223 | ||
224 | this.setDrawAngles = function(b) { | |
225 | drawAngles = b; | |
226 | }; | |
227 | ||
228 | this.selectABot = function(canvasX, canvasY) { | |
229 | var selected = undefined; | |
230 | for (var i = 0; i < numbots; i++) { | |
231 | if (Math.abs(canvasX - bots[i].x) < bots[i].radius && | |
232 | Math.abs(canvasY - bots[i].y) < bots[i].radius) { | |
233 | selected = i; | |
234 | break; | |
235 | } | |
236 | } | |
237 | if (selected !== undefined) { | |
238 | var bot = bots[selected]; | |
239 | alert("#" + selected + " x=" + bot.x + " y=" + bot.y + | |
240 | " theta=" + bot.theta_deg + " rho=" + | |
241 | bot.rho_deg + " adiff=" + bot.adiff / degrees); | |
242 | } | |
243 | }; | |
244 | ||
245 | this.draw = function() { | |
246 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
247 | ||
248 | for (var i = 0; i < bots.length; i++) { | |
249 | var bot = bots[i]; | |
250 | bot.draw(ctx); | |
251 | if (drawAngles) { | |
252 | bot.drawAngles(ctx); | |
253 | } | |
254 | } | |
255 | }; | |
256 | ||
257 | this.update = function() { | |
258 | for (var i = 0; i < bots.length; i++) { | |
259 | var bot = bots[i]; | |
260 | bot.move(); | |
261 | bot.adjust(); | |
262 | } | |
263 | }; | |
264 | ||
265 | this.scroll = function(dx, dy) { | |
266 | for (var i = 0; i < numbots; i++) { | |
267 | bots[i].x += dx; | |
268 | bots[i].y += dy; | |
269 | } | |
270 | }; | |
271 | ||
272 | this.massConfusion = function() { | |
273 | for (var i = 0; i < numbots-1; i++) { | |
274 | bots[i].theta = Math.random() * twopi; | |
275 | } | |
276 | }; | |
277 | ||
278 | this.shuffle = function() { | |
279 | var newBots = []; | |
280 | while (bots.length > 0) { | |
281 | newBots.push(bots.splice(Math.random() * bots.length, 1)[0]); | |
282 | } | |
283 | bots = newBots; | |
284 | for (var i = 0; i < numbots-1; i++) { | |
285 | bots[i].next = bots[i+1]; | |
286 | } | |
287 | bots[numbots-1].next = bots[0]; | |
288 | }; | |
289 | }; |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "animation.js", | |
5 | "preset-manager.js", | |
6 | "splash-screen.js" | |
7 | ]; | |
8 | var loaded = 0; | |
9 | for (var i = 0; i < deps.length; i++) { | |
10 | var elem = document.createElement('script'); | |
11 | elem.src = prefix + deps[i]; | |
12 | elem.onload = function() { | |
13 | if (++loaded < deps.length) return; | |
14 | var container = document.getElementById(containerId); | |
15 | ||
16 | var presetSelect = yoob.makeSelect(container, "MODE", []); | |
17 | yoob.makeLineBreak(container); | |
18 | ||
19 | var t = new FractalRectangles(); | |
20 | var canvas = yoob.makeCanvas(container, 500, 500); | |
21 | canvas.id = 'canvas'; // FIXME | |
22 | ||
23 | var p = new yoob.PresetManager(); | |
24 | p.init({ | |
25 | 'selectElem': presetSelect | |
26 | }); | |
27 | var presets = { | |
28 | "STATIC": function(n) { | |
29 | t.style = 1; | |
30 | }, | |
31 | "SYNC GLITCH": function(n) { | |
32 | t.style = 2; | |
33 | }, | |
34 | "SUPERSYNC GLITCH": function(n) { | |
35 | t.style = 3; | |
36 | }, | |
37 | "ASYNC GLITCH": function(n) { | |
38 | t.style = 4; | |
39 | } | |
40 | }; | |
41 | for (n in presets) { | |
42 | p.add(n, presets[n]); | |
43 | } | |
44 | ||
45 | yoob.showSplashScreen({ | |
46 | elementId: 'canvas', | |
47 | innerHTML: "<p>Warning: this application displays rapidly changing colours " + | |
48 | "and/or shapes and may be unsuitable for those sensitive to light or " + | |
49 | "prone to epileptic seizures.</p>", | |
50 | buttonText: "I understand -- Proceed", | |
51 | onproceed: function() { | |
52 | t.init({ | |
53 | 'canvas': canvas | |
54 | }); | |
55 | }, | |
56 | background: '#a0a0d0' | |
57 | }); | |
58 | ||
59 | }; | |
60 | document.body.appendChild(elem); | |
61 | } | |
62 | } | |
63 | ||
64 | ||
65 | FractalRectangles = function() { | |
66 | var ctx = undefined; | |
67 | var canvas = undefined; | |
68 | var info; | |
69 | var padding = 8; | |
70 | var cdelta = 40; | |
71 | ||
72 | var t = 0; | |
73 | ||
74 | this.init = function(cfg) { | |
75 | canvas = cfg.canvas; | |
76 | ctx = canvas.getContext("2d"); | |
77 | this.style = 1; | |
78 | this.animation = (new yoob.Animation()).init({'object': this }); | |
79 | this.animation.start(); | |
80 | }; | |
81 | ||
82 | this.update = function() { | |
83 | t += 1; | |
84 | }; | |
85 | ||
86 | this.draw = function() { | |
87 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
88 | this.globalWidthFactor = (1.5 + Math.random()); | |
89 | this.globalHeightFactor = (1.5 + Math.random()); | |
90 | this.drawRectangle(canvas.width / 2, canvas.height / 2, | |
91 | canvas.width / 2, canvas.height / 2, 0, 0, 0, 0); | |
92 | }; | |
93 | ||
94 | this.drawRectangle = function(x, y, width, height, r, g, b, level) { | |
95 | // x and y are coords of the centre; | |
96 | // width and height are the distance from the centre to the edge | |
97 | if (level > 3) return; | |
98 | ||
99 | ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")"; | |
100 | ctx.fillRect(x - width, y - height, width * 2, height * 2); | |
101 | ||
102 | var newwidth, newheight; | |
103 | if (this.style === 1) { | |
104 | var neww = width / 2.0 - padding; | |
105 | var newh = height / 2.0 - padding; | |
106 | newwidth = function() { return neww; }; | |
107 | newheight = function() { return newh; }; | |
108 | } else if (this.style === 2) { | |
109 | var neww, newh; | |
110 | neww = width / (1.5 + Math.random()) - padding; | |
111 | newh = height / (1.5 + Math.random()) - padding; | |
112 | newwidth = function() { return neww; }; | |
113 | newheight = function() { return newh; }; | |
114 | } else if (this.style === 3) { | |
115 | var $this = this; | |
116 | newwidth = function() { return width / $this.globalWidthFactor - padding; }; | |
117 | newheight = function() { return height / $this.globalHeightFactor - padding; }; | |
118 | } else if (this.style === 4) { | |
119 | newwidth = function() { return width / (1.5 + Math.random()) - padding; }; | |
120 | newheight = function() { return height / (1.5 + Math.random()) - padding; }; | |
121 | } | |
122 | ||
123 | this.drawRectangle(x - width / 2 , y - height / 2, newwidth(), newheight(), | |
124 | r + cdelta, g, b, level + 1); | |
125 | this.drawRectangle(x + width / 2, y - height / 2, newwidth(), newheight(), | |
126 | r, g + cdelta, b, level + 1); | |
127 | this.drawRectangle(x - width / 2, y + height / 2, newwidth(), newheight(), | |
128 | r, g, b + cdelta, level + 1); | |
129 | this.drawRectangle(x + width / 2, y + height / 2, newwidth(), newheight(), | |
130 | r + cdelta, g + cdelta, b + cdelta, level + 1); | |
131 | }; | |
132 | }; |
9 | 9 | <div id="container"></div> |
10 | 10 | |
11 | 11 | </body> |
12 | <script src="eine-kleine-glitchfraktal.js"></script> | |
12 | <script src="index.js"></script> | |
13 | 13 | <script> |
14 | 14 | launch('../common-yoob.js-0.11/', 'container'); |
15 | 15 | </script> |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "animation.js", | |
5 | "preset-manager.js", | |
6 | "splash-screen.js" | |
7 | ]; | |
8 | var loaded = 0; | |
9 | for (var i = 0; i < deps.length; i++) { | |
10 | var elem = document.createElement('script'); | |
11 | elem.src = prefix + deps[i]; | |
12 | elem.onload = function() { | |
13 | if (++loaded < deps.length) return; | |
14 | var container = document.getElementById(containerId); | |
15 | ||
16 | var presetSelect = yoob.makeSelect(container, "MODE", []); | |
17 | yoob.makeLineBreak(container); | |
18 | ||
19 | var t = new FractalRectangles(); | |
20 | var canvas = yoob.makeCanvas(container, 500, 500); | |
21 | canvas.id = 'canvas'; // FIXME | |
22 | ||
23 | var p = new yoob.PresetManager(); | |
24 | p.init({ | |
25 | 'selectElem': presetSelect | |
26 | }); | |
27 | var presets = { | |
28 | "STATIC": function(n) { | |
29 | t.style = 1; | |
30 | }, | |
31 | "SYNC GLITCH": function(n) { | |
32 | t.style = 2; | |
33 | }, | |
34 | "SUPERSYNC GLITCH": function(n) { | |
35 | t.style = 3; | |
36 | }, | |
37 | "ASYNC GLITCH": function(n) { | |
38 | t.style = 4; | |
39 | } | |
40 | }; | |
41 | for (n in presets) { | |
42 | p.add(n, presets[n]); | |
43 | } | |
44 | ||
45 | yoob.showSplashScreen({ | |
46 | elementId: 'canvas', | |
47 | innerHTML: "<p>Warning: this application displays rapidly changing colours " + | |
48 | "and/or shapes and may be unsuitable for those sensitive to light or " + | |
49 | "prone to epileptic seizures.</p>", | |
50 | buttonText: "I understand -- Proceed", | |
51 | onproceed: function() { | |
52 | t.init({ | |
53 | 'canvas': canvas | |
54 | }); | |
55 | }, | |
56 | background: '#a0a0d0' | |
57 | }); | |
58 | ||
59 | }; | |
60 | document.body.appendChild(elem); | |
61 | } | |
62 | } | |
63 | ||
64 | ||
65 | FractalRectangles = function() { | |
66 | var ctx = undefined; | |
67 | var canvas = undefined; | |
68 | var info; | |
69 | var padding = 8; | |
70 | var cdelta = 40; | |
71 | ||
72 | var t = 0; | |
73 | ||
74 | this.init = function(cfg) { | |
75 | canvas = cfg.canvas; | |
76 | ctx = canvas.getContext("2d"); | |
77 | this.style = 1; | |
78 | this.animation = (new yoob.Animation()).init({'object': this }); | |
79 | this.animation.start(); | |
80 | }; | |
81 | ||
82 | this.update = function() { | |
83 | t += 1; | |
84 | }; | |
85 | ||
86 | this.draw = function() { | |
87 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
88 | this.globalWidthFactor = (1.5 + Math.random()); | |
89 | this.globalHeightFactor = (1.5 + Math.random()); | |
90 | this.drawRectangle(canvas.width / 2, canvas.height / 2, | |
91 | canvas.width / 2, canvas.height / 2, 0, 0, 0, 0); | |
92 | }; | |
93 | ||
94 | this.drawRectangle = function(x, y, width, height, r, g, b, level) { | |
95 | // x and y are coords of the centre; | |
96 | // width and height are the distance from the centre to the edge | |
97 | if (level > 3) return; | |
98 | ||
99 | ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")"; | |
100 | ctx.fillRect(x - width, y - height, width * 2, height * 2); | |
101 | ||
102 | var newwidth, newheight; | |
103 | if (this.style === 1) { | |
104 | var neww = width / 2.0 - padding; | |
105 | var newh = height / 2.0 - padding; | |
106 | newwidth = function() { return neww; }; | |
107 | newheight = function() { return newh; }; | |
108 | } else if (this.style === 2) { | |
109 | var neww, newh; | |
110 | neww = width / (1.5 + Math.random()) - padding; | |
111 | newh = height / (1.5 + Math.random()) - padding; | |
112 | newwidth = function() { return neww; }; | |
113 | newheight = function() { return newh; }; | |
114 | } else if (this.style === 3) { | |
115 | var $this = this; | |
116 | newwidth = function() { return width / $this.globalWidthFactor - padding; }; | |
117 | newheight = function() { return height / $this.globalHeightFactor - padding; }; | |
118 | } else if (this.style === 4) { | |
119 | newwidth = function() { return width / (1.5 + Math.random()) - padding; }; | |
120 | newheight = function() { return height / (1.5 + Math.random()) - padding; }; | |
121 | } | |
122 | ||
123 | this.drawRectangle(x - width / 2 , y - height / 2, newwidth(), newheight(), | |
124 | r + cdelta, g, b, level + 1); | |
125 | this.drawRectangle(x + width / 2, y - height / 2, newwidth(), newheight(), | |
126 | r, g + cdelta, b, level + 1); | |
127 | this.drawRectangle(x - width / 2, y + height / 2, newwidth(), newheight(), | |
128 | r, g, b + cdelta, level + 1); | |
129 | this.drawRectangle(x + width / 2, y + height / 2, newwidth(), newheight(), | |
130 | r + cdelta, g + cdelta, b + cdelta, level + 1); | |
131 | }; | |
132 | }; |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var canvas = yoob.makeCanvas(container, 1000, 500); | |
13 | var t = new FibonacciSpiral(); | |
14 | t.init(canvas); | |
15 | } | |
16 | }; | |
17 | document.body.appendChild(elem); | |
18 | } | |
19 | } | |
20 | ||
21 | var twopi = Math.PI * 2; | |
22 | var degrees = twopi / 360; | |
23 | var fib = [1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946]; | |
24 | ||
25 | var triangle = function(low, high, span, v) { | |
26 | var k = v / span; | |
27 | var phase = Math.floor(k); | |
28 | var residue = k - phase; | |
29 | if (phase % 2 === 0) { | |
30 | return low + (residue * (high - low)); | |
31 | } else { | |
32 | return high - (residue * (high - low)); | |
33 | } | |
34 | }; | |
35 | ||
36 | FibonacciSpiral = function() { | |
37 | var info = undefined; // TODO: some better way to inject this, maybe | |
38 | var ctx = undefined; | |
39 | var canvas = undefined; | |
40 | var factor = 10; // 0; | |
41 | var rate = 0; // 0.001 | |
42 | var counter = 0; | |
43 | ||
44 | this.init = function(c) { | |
45 | canvas = c; | |
46 | ctx = canvas.getContext("2d"); | |
47 | this.animation = (new yoob.Animation()).init({ | |
48 | object: this | |
49 | }); | |
50 | this.animation.start(); | |
51 | }; | |
52 | ||
53 | this.draw = function() { | |
54 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
55 | ||
56 | var sign = -1; | |
57 | var x = canvas.width / 2; | |
58 | var y = canvas.height / 2; | |
59 | //var alpha = (Math.sin(counter / 10) + 1) * 0.05; | |
60 | //alpha = Math.floor(alpha * 1000) / 1000; | |
61 | var alpha = 0.05; | |
62 | var colours = [ | |
63 | '255,0,0', | |
64 | '0,255,0', | |
65 | '0,0,255' | |
66 | ]; | |
67 | var linecolours = [ | |
68 | '#000000', | |
69 | '#800000', | |
70 | '#707070' | |
71 | ]; | |
72 | ||
73 | ctx.save(); | |
74 | ctx.translate(x, y + 1); | |
75 | ctx.scale(factor, factor); | |
76 | ctx.translate(-x, -y - 1); | |
77 | ctx.lineWidth = 2 / factor; | |
78 | for (var i = 0; i < 20; i++) { | |
79 | var f = fib[i]; | |
80 | ||
81 | ctx.beginPath(); | |
82 | var a1; var a2; | |
83 | if (sign > 0) { | |
84 | a1 = Math.PI * 0.5; | |
85 | a2 = Math.PI * 1.5; | |
86 | ctx.fillStyle = "rgba(" + colours[i % colours.length] + "," + alpha + ")"; | |
87 | } else { | |
88 | a1 = Math.PI * 1.5; | |
89 | a2 = Math.PI * 2.5; | |
90 | ctx.fillStyle = "rgba(" + colours[i % colours.length] + "," + alpha + ")"; | |
91 | } | |
92 | ctx.strokeStyle = linecolours[i % linecolours.length]; | |
93 | var radius = f; // * factor; | |
94 | y -= sign * radius; // remove for different effect | |
95 | ctx.arc(x, y, Math.abs(radius), a1, a2, false); | |
96 | ctx.fill(); | |
97 | ctx.stroke(); | |
98 | ||
99 | sign *= -1; | |
100 | y += sign * radius; | |
101 | } | |
102 | ctx.restore(); | |
103 | if (info) { | |
104 | info.innerHTML = "Factor: " + factor + ", alpha=" + alpha; | |
105 | } | |
106 | }; | |
107 | ||
108 | this.update = function() { | |
109 | factor -= 0.01; // rate; | |
110 | //rate += 0.0001; | |
111 | //factor = triangle(1, 10, 100, counter); | |
112 | factor = 20 * (Math.cos(counter / 100) + 1.001); | |
113 | counter += 0.3; | |
114 | //counter += factor < 2 ? 0.3 : 1; | |
115 | }; | |
116 | }; |
16 | 16 | <div id="container"></div> |
17 | 17 | |
18 | 18 | </body> |
19 | <script src="fibonacci-spiral.js"></script> | |
19 | <script src="index.js"></script> | |
20 | 20 | <script> |
21 | 21 | launch('../common-yoob.js-0.11/', 'container'); |
22 | 22 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var canvas = yoob.makeCanvas(container, 1000, 500); | |
13 | var t = new FibonacciSpiral(); | |
14 | t.init(canvas); | |
15 | } | |
16 | }; | |
17 | document.body.appendChild(elem); | |
18 | } | |
19 | } | |
20 | ||
21 | var twopi = Math.PI * 2; | |
22 | var degrees = twopi / 360; | |
23 | var fib = [1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946]; | |
24 | ||
25 | var triangle = function(low, high, span, v) { | |
26 | var k = v / span; | |
27 | var phase = Math.floor(k); | |
28 | var residue = k - phase; | |
29 | if (phase % 2 === 0) { | |
30 | return low + (residue * (high - low)); | |
31 | } else { | |
32 | return high - (residue * (high - low)); | |
33 | } | |
34 | }; | |
35 | ||
36 | FibonacciSpiral = function() { | |
37 | var info = undefined; // TODO: some better way to inject this, maybe | |
38 | var ctx = undefined; | |
39 | var canvas = undefined; | |
40 | var factor = 10; // 0; | |
41 | var rate = 0; // 0.001 | |
42 | var counter = 0; | |
43 | ||
44 | this.init = function(c) { | |
45 | canvas = c; | |
46 | ctx = canvas.getContext("2d"); | |
47 | this.animation = (new yoob.Animation()).init({ | |
48 | object: this | |
49 | }); | |
50 | this.animation.start(); | |
51 | }; | |
52 | ||
53 | this.draw = function() { | |
54 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
55 | ||
56 | var sign = -1; | |
57 | var x = canvas.width / 2; | |
58 | var y = canvas.height / 2; | |
59 | //var alpha = (Math.sin(counter / 10) + 1) * 0.05; | |
60 | //alpha = Math.floor(alpha * 1000) / 1000; | |
61 | var alpha = 0.05; | |
62 | var colours = [ | |
63 | '255,0,0', | |
64 | '0,255,0', | |
65 | '0,0,255' | |
66 | ]; | |
67 | var linecolours = [ | |
68 | '#000000', | |
69 | '#800000', | |
70 | '#707070' | |
71 | ]; | |
72 | ||
73 | ctx.save(); | |
74 | ctx.translate(x, y + 1); | |
75 | ctx.scale(factor, factor); | |
76 | ctx.translate(-x, -y - 1); | |
77 | ctx.lineWidth = 2 / factor; | |
78 | for (var i = 0; i < 20; i++) { | |
79 | var f = fib[i]; | |
80 | ||
81 | ctx.beginPath(); | |
82 | var a1; var a2; | |
83 | if (sign > 0) { | |
84 | a1 = Math.PI * 0.5; | |
85 | a2 = Math.PI * 1.5; | |
86 | ctx.fillStyle = "rgba(" + colours[i % colours.length] + "," + alpha + ")"; | |
87 | } else { | |
88 | a1 = Math.PI * 1.5; | |
89 | a2 = Math.PI * 2.5; | |
90 | ctx.fillStyle = "rgba(" + colours[i % colours.length] + "," + alpha + ")"; | |
91 | } | |
92 | ctx.strokeStyle = linecolours[i % linecolours.length]; | |
93 | var radius = f; // * factor; | |
94 | y -= sign * radius; // remove for different effect | |
95 | ctx.arc(x, y, Math.abs(radius), a1, a2, false); | |
96 | ctx.fill(); | |
97 | ctx.stroke(); | |
98 | ||
99 | sign *= -1; | |
100 | y += sign * radius; | |
101 | } | |
102 | ctx.restore(); | |
103 | if (info) { | |
104 | info.innerHTML = "Factor: " + factor + ", alpha=" + alpha; | |
105 | } | |
106 | }; | |
107 | ||
108 | this.update = function() { | |
109 | factor -= 0.01; // rate; | |
110 | //rate += 0.0001; | |
111 | //factor = triangle(1, 10, 100, counter); | |
112 | factor = 20 * (Math.cos(counter / 100) + 1.001); | |
113 | counter += 0.3; | |
114 | //counter += factor < 2 ? 0.3 : 1; | |
115 | }; | |
116 | }; |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId) { | |
3 | var deps = [ | |
4 | "element-factory.js", | |
5 | "animation.js", | |
6 | "canvas-resizer.js" | |
7 | ]; | |
8 | var loaded = 0; | |
9 | for (var i = 0; i < deps.length; i++) { | |
10 | var elem = document.createElement('script'); | |
11 | elem.src = prefix + deps[i]; | |
12 | elem.onload = function() { | |
13 | if (++loaded < deps.length) return; | |
14 | ||
15 | var container = document.getElementById(containerId); | |
16 | var gewgaw = new Fingerspelling(); | |
17 | var canvas = yoob.makeCanvas(container); | |
18 | ||
19 | canvas.style.display = "none"; | |
20 | canvas.style.background = "#ccaacc"; | |
21 | for (var elem = canvas; elem; elem = elem.parentElement) { | |
22 | elem.style.border = "none"; | |
23 | elem.style.margin = "0"; | |
24 | elem.style.padding = "0"; | |
25 | elem.style.lineHeight = "0"; | |
26 | } | |
27 | ||
28 | var initialized = false; | |
29 | var cr = (new yoob.CanvasResizer()).init({ | |
30 | canvas: canvas, | |
31 | onResizeEnd: function() { | |
32 | if (!initialized) { | |
33 | gewgaw.init(canvas); | |
34 | initialized = true; | |
35 | } | |
36 | }, | |
37 | desiredWidth: 100, // doesn't really matter | |
38 | desiredHeight: 100, // doesn't really matter | |
39 | preserveAspectRatio: false, | |
40 | allowExpansion: true | |
41 | }).register(); | |
42 | }; | |
43 | document.body.appendChild(elem); | |
44 | } | |
45 | } | |
46 | ||
47 | var Thing = function() { | |
48 | this.init = function(x, y, w, h, str, intensity, r, g, b) { | |
49 | this.x = x; | |
50 | this.y = y; | |
51 | this.w = w; | |
52 | this.h = h; | |
53 | this.str = str; | |
54 | this.intensity = intensity; | |
55 | this.r = r || 0; | |
56 | this.g = g || 0; | |
57 | this.b = b || 0; | |
58 | return this; | |
59 | }; | |
60 | ||
61 | this.draw = function(ctx) { | |
62 | ctx.fillStyle = "rgba(" + this.r + ", " + this.g + "," + this. b + "," + 1.0 * this.intensity + ")"; | |
63 | ctx.fillText(this.str, this.x, this.y); | |
64 | }; | |
65 | }; | |
66 | ||
67 | var Queue = function() { | |
68 | this.init = function() { | |
69 | this.queue = []; | |
70 | return this; | |
71 | }; | |
72 | ||
73 | this.enqueue = function(obj) { | |
74 | this.queue.push(obj); | |
75 | }; | |
76 | ||
77 | this.dequeue = function() { | |
78 | return this.queue.shift(); | |
79 | }; | |
80 | ||
81 | this.draw = function(ctx) { | |
82 | for (var i = 0; i < this.queue.length; i++) { | |
83 | this.queue[i].draw(ctx); | |
84 | } | |
85 | }; | |
86 | ||
87 | this.fade = function(amount) { | |
88 | for (var i = 0; i < this.queue.length; i++) { | |
89 | this.queue[i].intensity -= amount; | |
90 | this.queue[i].y += 1; | |
91 | } | |
92 | while (this.queue.length > 0 && this.queue[0].intensity <= 0) { | |
93 | this.queue.shift(); | |
94 | } | |
95 | }; | |
96 | }; | |
97 | ||
98 | var Fingerspelling = function() { | |
99 | var options; | |
100 | ||
101 | var canvas; | |
102 | var ctx; | |
103 | var queues = [new Queue().init(), new Queue().init()]; | |
104 | var touches = [undefined, undefined]; | |
105 | ||
106 | this.update = function() { | |
107 | for (var touchNum = 0; touchNum <= 1; touchNum++) { | |
108 | var touch = touches[touchNum]; | |
109 | if (touch === undefined) continue; | |
110 | ||
111 | for (var i = 0; i <= 1; i++) { | |
112 | var range = 32; | |
113 | var offX = Math.random() * (range*2) - range; | |
114 | var offY = Math.random() * (range*2) - range; | |
115 | var thing = new Thing(); | |
116 | var val; | |
117 | if (touchNum == 0) { | |
118 | val = Math.floor(Math.random() * 26 + 65); | |
119 | } else { | |
120 | val = Math.floor(Math.random() * 26 + 97); | |
121 | } | |
122 | var letter = String.fromCharCode(val); | |
123 | thing.init(touch.canvasX + offX, | |
124 | touch.canvasY + offY, 0, 0, letter, 1.0, | |
125 | options.red, options.green, options.blue); | |
126 | queues[touchNum].enqueue(thing); | |
127 | } | |
128 | } | |
129 | for (var touchNum = 0; touchNum <= 1; touchNum++) { | |
130 | queues[touchNum].fade(0.05); | |
131 | } | |
132 | }; | |
133 | ||
134 | this.draw = function() { | |
135 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
136 | ctx.textBaseline = "top"; | |
137 | ctx.font = "24px Serif"; | |
138 | for (var touchNum = 0; touchNum <= 1; touchNum++) { | |
139 | queues[touchNum].draw(ctx); | |
140 | } | |
141 | var e = document.getElementById('status'); | |
142 | if (e) { | |
143 | e.innerHTML = 'Letters: ' + queue.queue.length; | |
144 | } | |
145 | }; | |
146 | ||
147 | this.init = function(c, opts) { | |
148 | canvas = c; | |
149 | ctx = canvas.getContext("2d"); | |
150 | options = opts || {}; | |
151 | options.red = options.red || 0; | |
152 | options.green = options.green || 0; | |
153 | options.blue = options.blue || 0; | |
154 | ||
155 | var mouseTN = 0; | |
156 | canvas.addEventListener('mousedown', function(e) { | |
157 | touches[mouseTN] = {}; | |
158 | touches[mouseTN].canvasX = e.pageX - canvas.offsetLeft; | |
159 | touches[mouseTN].canvasY = e.pageY - canvas.offsetTop; | |
160 | e.preventDefault(); | |
161 | }); | |
162 | canvas.addEventListener('mouseup', function(e) { | |
163 | touches[mouseTN] = undefined; | |
164 | e.preventDefault(); | |
165 | }); | |
166 | canvas.addEventListener('mousemove', function(e) { | |
167 | if (touches[mouseTN] !== undefined) { | |
168 | touches[mouseTN].canvasX = e.pageX - canvas.offsetLeft; | |
169 | touches[mouseTN].canvasY = e.pageY - canvas.offsetTop; | |
170 | } | |
171 | e.preventDefault(); | |
172 | }); | |
173 | ||
174 | canvas.addEventListener('touchstart', function(e) { | |
175 | for (var touchNum = 0; touchNum <= 1; touchNum++) { | |
176 | var touch = e.touches[touchNum]; | |
177 | if (touch === undefined) continue; | |
178 | touches[touchNum] = {}; | |
179 | touches[touchNum].canvasX = touch.pageX - canvas.offsetLeft; | |
180 | touches[touchNum].canvasY = touch.pageY - canvas.offsetTop; | |
181 | } | |
182 | e.preventDefault(); | |
183 | }); | |
184 | canvas.addEventListener('touchend', function(e) { | |
185 | // not great, but ehh. | |
186 | touches = [undefined, undefined]; | |
187 | e.preventDefault(); | |
188 | }); | |
189 | canvas.addEventListener('touchmove', function(e) { | |
190 | for (var touchNum = 0; touchNum <= 1; touchNum++) { | |
191 | var touch = e.touches[touchNum]; | |
192 | if (touch === undefined) continue; | |
193 | touches[touchNum].canvasX = touch.pageX - canvas.offsetLeft; | |
194 | touches[touchNum].canvasY = touch.pageY - canvas.offsetTop; | |
195 | } | |
196 | e.preventDefault(); | |
197 | }); | |
198 | ||
199 | this.animation = (new yoob.Animation()).init({ object: this }); | |
200 | this.animation.start(); | |
201 | }; | |
202 | }; |
10 | 10 | <div id="container"></div> |
11 | 11 | |
12 | 12 | </body> |
13 | <script src="fingerspelling.js"></script> | |
13 | <script src="index.js"></script> | |
14 | 14 | <script> |
15 | 15 | launch('../common-yoob.js-0.11/', 'container'); |
16 | 16 | </script> |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId) { | |
3 | var deps = [ | |
4 | "element-factory.js", | |
5 | "animation.js", | |
6 | "canvas-resizer.js" | |
7 | ]; | |
8 | var loaded = 0; | |
9 | for (var i = 0; i < deps.length; i++) { | |
10 | var elem = document.createElement('script'); | |
11 | elem.src = prefix + deps[i]; | |
12 | elem.onload = function() { | |
13 | if (++loaded < deps.length) return; | |
14 | ||
15 | var container = document.getElementById(containerId); | |
16 | var gewgaw = new Fingerspelling(); | |
17 | var canvas = yoob.makeCanvas(container); | |
18 | ||
19 | canvas.style.display = "none"; | |
20 | canvas.style.background = "#ccaacc"; | |
21 | for (var elem = canvas; elem; elem = elem.parentElement) { | |
22 | elem.style.border = "none"; | |
23 | elem.style.margin = "0"; | |
24 | elem.style.padding = "0"; | |
25 | elem.style.lineHeight = "0"; | |
26 | } | |
27 | ||
28 | var initialized = false; | |
29 | var cr = (new yoob.CanvasResizer()).init({ | |
30 | canvas: canvas, | |
31 | onResizeEnd: function() { | |
32 | if (!initialized) { | |
33 | gewgaw.init(canvas); | |
34 | initialized = true; | |
35 | } | |
36 | }, | |
37 | desiredWidth: 100, // doesn't really matter | |
38 | desiredHeight: 100, // doesn't really matter | |
39 | preserveAspectRatio: false, | |
40 | allowExpansion: true | |
41 | }).register(); | |
42 | }; | |
43 | document.body.appendChild(elem); | |
44 | } | |
45 | } | |
46 | ||
47 | var Thing = function() { | |
48 | this.init = function(x, y, w, h, str, intensity, r, g, b) { | |
49 | this.x = x; | |
50 | this.y = y; | |
51 | this.w = w; | |
52 | this.h = h; | |
53 | this.str = str; | |
54 | this.intensity = intensity; | |
55 | this.r = r || 0; | |
56 | this.g = g || 0; | |
57 | this.b = b || 0; | |
58 | return this; | |
59 | }; | |
60 | ||
61 | this.draw = function(ctx) { | |
62 | ctx.fillStyle = "rgba(" + this.r + ", " + this.g + "," + this. b + "," + 1.0 * this.intensity + ")"; | |
63 | ctx.fillText(this.str, this.x, this.y); | |
64 | }; | |
65 | }; | |
66 | ||
67 | var Queue = function() { | |
68 | this.init = function() { | |
69 | this.queue = []; | |
70 | return this; | |
71 | }; | |
72 | ||
73 | this.enqueue = function(obj) { | |
74 | this.queue.push(obj); | |
75 | }; | |
76 | ||
77 | this.dequeue = function() { | |
78 | return this.queue.shift(); | |
79 | }; | |
80 | ||
81 | this.draw = function(ctx) { | |
82 | for (var i = 0; i < this.queue.length; i++) { | |
83 | this.queue[i].draw(ctx); | |
84 | } | |
85 | }; | |
86 | ||
87 | this.fade = function(amount) { | |
88 | for (var i = 0; i < this.queue.length; i++) { | |
89 | this.queue[i].intensity -= amount; | |
90 | this.queue[i].y += 1; | |
91 | } | |
92 | while (this.queue.length > 0 && this.queue[0].intensity <= 0) { | |
93 | this.queue.shift(); | |
94 | } | |
95 | }; | |
96 | }; | |
97 | ||
98 | var Fingerspelling = function() { | |
99 | var options; | |
100 | ||
101 | var canvas; | |
102 | var ctx; | |
103 | var queues = [new Queue().init(), new Queue().init()]; | |
104 | var touches = [undefined, undefined]; | |
105 | ||
106 | this.update = function() { | |
107 | for (var touchNum = 0; touchNum <= 1; touchNum++) { | |
108 | var touch = touches[touchNum]; | |
109 | if (touch === undefined) continue; | |
110 | ||
111 | for (var i = 0; i <= 1; i++) { | |
112 | var range = 32; | |
113 | var offX = Math.random() * (range*2) - range; | |
114 | var offY = Math.random() * (range*2) - range; | |
115 | var thing = new Thing(); | |
116 | var val; | |
117 | if (touchNum == 0) { | |
118 | val = Math.floor(Math.random() * 26 + 65); | |
119 | } else { | |
120 | val = Math.floor(Math.random() * 26 + 97); | |
121 | } | |
122 | var letter = String.fromCharCode(val); | |
123 | thing.init(touch.canvasX + offX, | |
124 | touch.canvasY + offY, 0, 0, letter, 1.0, | |
125 | options.red, options.green, options.blue); | |
126 | queues[touchNum].enqueue(thing); | |
127 | } | |
128 | } | |
129 | for (var touchNum = 0; touchNum <= 1; touchNum++) { | |
130 | queues[touchNum].fade(0.05); | |
131 | } | |
132 | }; | |
133 | ||
134 | this.draw = function() { | |
135 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
136 | ctx.textBaseline = "top"; | |
137 | ctx.font = "24px Serif"; | |
138 | for (var touchNum = 0; touchNum <= 1; touchNum++) { | |
139 | queues[touchNum].draw(ctx); | |
140 | } | |
141 | var e = document.getElementById('status'); | |
142 | if (e) { | |
143 | e.innerHTML = 'Letters: ' + queue.queue.length; | |
144 | } | |
145 | }; | |
146 | ||
147 | this.init = function(c, opts) { | |
148 | canvas = c; | |
149 | ctx = canvas.getContext("2d"); | |
150 | options = opts || {}; | |
151 | options.red = options.red || 0; | |
152 | options.green = options.green || 0; | |
153 | options.blue = options.blue || 0; | |
154 | ||
155 | var mouseTN = 0; | |
156 | canvas.addEventListener('mousedown', function(e) { | |
157 | touches[mouseTN] = {}; | |
158 | touches[mouseTN].canvasX = e.pageX - canvas.offsetLeft; | |
159 | touches[mouseTN].canvasY = e.pageY - canvas.offsetTop; | |
160 | e.preventDefault(); | |
161 | }); | |
162 | canvas.addEventListener('mouseup', function(e) { | |
163 | touches[mouseTN] = undefined; | |
164 | e.preventDefault(); | |
165 | }); | |
166 | canvas.addEventListener('mousemove', function(e) { | |
167 | if (touches[mouseTN] !== undefined) { | |
168 | touches[mouseTN].canvasX = e.pageX - canvas.offsetLeft; | |
169 | touches[mouseTN].canvasY = e.pageY - canvas.offsetTop; | |
170 | } | |
171 | e.preventDefault(); | |
172 | }); | |
173 | ||
174 | canvas.addEventListener('touchstart', function(e) { | |
175 | for (var touchNum = 0; touchNum <= 1; touchNum++) { | |
176 | var touch = e.touches[touchNum]; | |
177 | if (touch === undefined) continue; | |
178 | touches[touchNum] = {}; | |
179 | touches[touchNum].canvasX = touch.pageX - canvas.offsetLeft; | |
180 | touches[touchNum].canvasY = touch.pageY - canvas.offsetTop; | |
181 | } | |
182 | e.preventDefault(); | |
183 | }); | |
184 | canvas.addEventListener('touchend', function(e) { | |
185 | // not great, but ehh. | |
186 | touches = [undefined, undefined]; | |
187 | e.preventDefault(); | |
188 | }); | |
189 | canvas.addEventListener('touchmove', function(e) { | |
190 | for (var touchNum = 0; touchNum <= 1; touchNum++) { | |
191 | var touch = e.touches[touchNum]; | |
192 | if (touch === undefined) continue; | |
193 | touches[touchNum].canvasX = touch.pageX - canvas.offsetLeft; | |
194 | touches[touchNum].canvasY = touch.pageY - canvas.offsetTop; | |
195 | } | |
196 | e.preventDefault(); | |
197 | }); | |
198 | ||
199 | this.animation = (new yoob.Animation()).init({ object: this }); | |
200 | this.animation.start(); | |
201 | }; | |
202 | }; |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | "sprite-manager.js", | |
5 | "canvas-resizer.js" | |
6 | ]; | |
7 | var loaded = 0; | |
8 | for (var i = 0; i < deps.length; i++) { | |
9 | var elem = document.createElement('script'); | |
10 | elem.src = prefix + deps[i]; | |
11 | elem.onload = function() { | |
12 | if (++loaded < deps.length) return; | |
13 | ||
14 | var container = document.getElementById(containerId); | |
15 | var canvas = yoob.makeCanvas(container, 1200, 400); | |
16 | canvas.style.border = "2px solid black"; | |
17 | var p = yoob.makeParagraph(container, | |
18 | "PLATE I. THE ORGANIZATION OF COLLAPSED CLARKSON'S " + | |
19 | "ENTITIES (<i>Heronsis hermnonicii</i>) INTO " + | |
20 | "PROTO-COHORTS AS A RUDIMENTARY METHOD OF PHYSIOGNOMETRIC " + | |
21 | "DEFENCE"); | |
22 | var gewgaw = new HeronsisHermnonicii(); | |
23 | var initialized = false; | |
24 | var cr = (new yoob.CanvasResizer()).init({ | |
25 | canvas: canvas, | |
26 | onResizeEnd: function() { | |
27 | if (!initialized) { | |
28 | gewgaw.init(canvas); | |
29 | initialized = true; | |
30 | } | |
31 | }, | |
32 | desiredWidth: 1200, | |
33 | desiredHeight: 400, | |
34 | centerVertically: false | |
35 | }).register(); | |
36 | }; | |
37 | document.body.appendChild(elem); | |
38 | } | |
39 | } | |
40 | ||
41 | ||
42 | Floater = function(proto) { | |
43 | this.init = function(cfg) { | |
44 | // call superclass'es init() method | |
45 | Floater.prototype.init.apply(this, [cfg]); | |
46 | this.isClickable = true; | |
47 | this.counter = 0; | |
48 | this.rate = 0.07; | |
49 | this.maxRate = 2; | |
50 | return this; | |
51 | }; | |
52 | ||
53 | this.getX = function() { | |
54 | var range = this.getWidth(); | |
55 | if (this.rate > this.maxRate * 0.75) { | |
56 | range *= 2; | |
57 | } | |
58 | return this.x + Math.cos(this.counter) * range; | |
59 | }; | |
60 | ||
61 | this.draw = function(ctx) { | |
62 | ctx.strokeStyle = "black"; | |
63 | ctx.lineWidth = this.getWidth() / 20; | |
64 | ||
65 | ctx.beginPath(); | |
66 | var anchorDist = 500; | |
67 | ctx.moveTo(this.x, this.getY() - anchorDist); | |
68 | ctx.lineTo(this.getX(), this.getY()); | |
69 | ctx.lineTo(this.x, this.getY() + anchorDist); | |
70 | ctx.stroke(); | |
71 | ||
72 | ctx.beginPath(); | |
73 | var red = 255; | |
74 | var blue = Math.floor(this.rate * 500); | |
75 | var green = 0; | |
76 | if (blue < 0) blue = 0; | |
77 | if (blue > 255) { | |
78 | blue = 0; | |
79 | green = Math.floor(this.rate * 150); | |
80 | if (green > 255) { | |
81 | red = 255; | |
82 | green = 255; | |
83 | blue = 255; | |
84 | } | |
85 | } | |
86 | if (this.rate > this.maxRate) { | |
87 | red = 0; | |
88 | green = 0; | |
89 | blue = 0; | |
90 | } | |
91 | s = "rgba(" + red + ", " + green + ", " + blue + ", 1.0)"; | |
92 | ctx.fillStyle = s; | |
93 | ctx.arc(this.getX(), this.getY(), | |
94 | this.getWidth() / 2, 0, 2 * Math.PI, false); | |
95 | ctx.closePath(); | |
96 | ctx.fill(); | |
97 | ctx.stroke(); | |
98 | ||
99 | ctx.beginPath(); | |
100 | ctx.fillStyle = "rgba(255, 255, 255, " + ((100-this.getWidth()) / 200) + ")"; | |
101 | ctx.arc(this.getX(), this.getY(), | |
102 | this.getWidth() / 2, 0, 2 * Math.PI, false); | |
103 | ctx.closePath(); | |
104 | ctx.fill(); | |
105 | }; | |
106 | ||
107 | this.move = function() { | |
108 | this.counter += this.rate * 0.66; | |
109 | if (this.rate > 0.07) this.rate -= 0.01; | |
110 | }; | |
111 | ||
112 | this.onclick = function() { | |
113 | this.rate *= 3; | |
114 | if (this.rate > this.maxRate) { | |
115 | this.rate = this.maxRate; | |
116 | } | |
117 | }; | |
118 | ||
119 | this.containsPoint = function(x, y) { | |
120 | var r = this.getWidth() / 2; | |
121 | var dx = x - this.getX(); | |
122 | var dy = y - this.getY(); | |
123 | var dist = dx * dx + dy * dy; | |
124 | return dist < r * r; | |
125 | }; | |
126 | }; | |
127 | ||
128 | HeronsisHermnonicii = function() { | |
129 | var ctx; | |
130 | var request; | |
131 | ||
132 | var manager; | |
133 | var landscape = []; | |
134 | var treescape = []; | |
135 | ||
136 | this.draw = function() { | |
137 | ctx.fillStyle = "#ddccff"; | |
138 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
139 | ||
140 | ctx.fillStyle = "#ffdd66"; | |
141 | var s = canvas.width / (landscape.length - 1); | |
142 | for (var i = 0; i < landscape.length - 1; i++) { | |
143 | ctx.beginPath(); | |
144 | ctx.moveTo(i * s - 1, landscape[i]); | |
145 | ctx.lineTo(i * s - 1, canvas.height); | |
146 | ctx.lineTo((i+1) * s, canvas.height); | |
147 | ctx.lineTo((i+1) * s, landscape[i+1]); | |
148 | ctx.closePath(); | |
149 | ctx.fill(); | |
150 | } | |
151 | ||
152 | ctx.fillStyle = "#88ffaa"; | |
153 | var s = canvas.width / (treescape.length - 1); | |
154 | for (var i = 0; i < treescape.length - 1; i++) { | |
155 | ctx.beginPath(); | |
156 | ctx.moveTo(i * s - 1, treescape[i]); | |
157 | ctx.lineTo(i * s - 1, canvas.height); | |
158 | ctx.lineTo((i+1) * s, canvas.height); | |
159 | ctx.lineTo((i+1) * s, treescape[i+1]); | |
160 | ctx.closePath(); | |
161 | ctx.fill(); | |
162 | } | |
163 | ||
164 | // draw sprites | |
165 | manager.draw(ctx); | |
166 | }; | |
167 | ||
168 | this.update = function() { | |
169 | manager.move(); | |
170 | }; | |
171 | ||
172 | this.init = function(c) { | |
173 | Floater.prototype = new yoob.Sprite(); | |
174 | ||
175 | canvas = c; | |
176 | ctx = canvas.getContext('2d'); | |
177 | ||
178 | manager = new yoob.SpriteManager(); | |
179 | manager.init({ | |
180 | canvas: canvas | |
181 | }); | |
182 | ||
183 | var closeness = 5; | |
184 | for (var i = 1; i < 30; i++) { | |
185 | var f = new Floater(); | |
186 | var w = closeness; | |
187 | var x = Math.random() * (canvas.width - w * 2); | |
188 | var y = Math.random() * (canvas.height - w * 2); | |
189 | f.init({ | |
190 | x: x, | |
191 | y: y, | |
192 | width: w, | |
193 | height: w | |
194 | }); | |
195 | f.counter = Math.random() * Math.PI * 2; | |
196 | manager.addSprite(f); | |
197 | manager.moveToBack(f); | |
198 | closeness *= 1.1; | |
199 | } | |
200 | ||
201 | for (var i = 0; i < 10; i += 1) { | |
202 | landscape[i] = canvas.height / 2 + (Math.random() * 60 - 30); | |
203 | } | |
204 | ||
205 | for (var i = 0; i < 30; i += 1) { | |
206 | treescape[i] = canvas.height * 0.75 + (Math.random() * 60 - 30); | |
207 | } | |
208 | ||
209 | // TODO might be better with a ProportionalAnimationFrame, | |
210 | // but yoob.Sprite needs to support that better first | |
211 | this.animation = (new yoob.Animation()).init({ | |
212 | object: this | |
213 | }); | |
214 | this.animation.start(); | |
215 | }; | |
216 | } |
16 | 16 | <div id="container"></div> |
17 | 17 | |
18 | 18 | </body> |
19 | <script src="heronsis-hermnonicii.js"></script> | |
19 | <script src="index.js"></script> | |
20 | 20 | <script> |
21 | 21 | launch('../common-yoob.js-0.11/', 'container'); |
22 | 22 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | "sprite-manager.js", | |
5 | "canvas-resizer.js" | |
6 | ]; | |
7 | var loaded = 0; | |
8 | for (var i = 0; i < deps.length; i++) { | |
9 | var elem = document.createElement('script'); | |
10 | elem.src = prefix + deps[i]; | |
11 | elem.onload = function() { | |
12 | if (++loaded < deps.length) return; | |
13 | ||
14 | var container = document.getElementById(containerId); | |
15 | var canvas = yoob.makeCanvas(container, 1200, 400); | |
16 | canvas.style.border = "2px solid black"; | |
17 | var p = yoob.makeParagraph(container, | |
18 | "PLATE I. THE ORGANIZATION OF COLLAPSED CLARKSON'S " + | |
19 | "ENTITIES (<i>Heronsis hermnonicii</i>) INTO " + | |
20 | "PROTO-COHORTS AS A RUDIMENTARY METHOD OF PHYSIOGNOMETRIC " + | |
21 | "DEFENCE"); | |
22 | var gewgaw = new HeronsisHermnonicii(); | |
23 | var initialized = false; | |
24 | var cr = (new yoob.CanvasResizer()).init({ | |
25 | canvas: canvas, | |
26 | onResizeEnd: function() { | |
27 | if (!initialized) { | |
28 | gewgaw.init(canvas); | |
29 | initialized = true; | |
30 | } | |
31 | }, | |
32 | desiredWidth: 1200, | |
33 | desiredHeight: 400, | |
34 | centerVertically: false | |
35 | }).register(); | |
36 | }; | |
37 | document.body.appendChild(elem); | |
38 | } | |
39 | } | |
40 | ||
41 | ||
42 | Floater = function(proto) { | |
43 | this.init = function(cfg) { | |
44 | // call superclass'es init() method | |
45 | Floater.prototype.init.apply(this, [cfg]); | |
46 | this.isClickable = true; | |
47 | this.counter = 0; | |
48 | this.rate = 0.07; | |
49 | this.maxRate = 2; | |
50 | return this; | |
51 | }; | |
52 | ||
53 | this.getX = function() { | |
54 | var range = this.getWidth(); | |
55 | if (this.rate > this.maxRate * 0.75) { | |
56 | range *= 2; | |
57 | } | |
58 | return this.x + Math.cos(this.counter) * range; | |
59 | }; | |
60 | ||
61 | this.draw = function(ctx) { | |
62 | ctx.strokeStyle = "black"; | |
63 | ctx.lineWidth = this.getWidth() / 20; | |
64 | ||
65 | ctx.beginPath(); | |
66 | var anchorDist = 500; | |
67 | ctx.moveTo(this.x, this.getY() - anchorDist); | |
68 | ctx.lineTo(this.getX(), this.getY()); | |
69 | ctx.lineTo(this.x, this.getY() + anchorDist); | |
70 | ctx.stroke(); | |
71 | ||
72 | ctx.beginPath(); | |
73 | var red = 255; | |
74 | var blue = Math.floor(this.rate * 500); | |
75 | var green = 0; | |
76 | if (blue < 0) blue = 0; | |
77 | if (blue > 255) { | |
78 | blue = 0; | |
79 | green = Math.floor(this.rate * 150); | |
80 | if (green > 255) { | |
81 | red = 255; | |
82 | green = 255; | |
83 | blue = 255; | |
84 | } | |
85 | } | |
86 | if (this.rate > this.maxRate) { | |
87 | red = 0; | |
88 | green = 0; | |
89 | blue = 0; | |
90 | } | |
91 | s = "rgba(" + red + ", " + green + ", " + blue + ", 1.0)"; | |
92 | ctx.fillStyle = s; | |
93 | ctx.arc(this.getX(), this.getY(), | |
94 | this.getWidth() / 2, 0, 2 * Math.PI, false); | |
95 | ctx.closePath(); | |
96 | ctx.fill(); | |
97 | ctx.stroke(); | |
98 | ||
99 | ctx.beginPath(); | |
100 | ctx.fillStyle = "rgba(255, 255, 255, " + ((100-this.getWidth()) / 200) + ")"; | |
101 | ctx.arc(this.getX(), this.getY(), | |
102 | this.getWidth() / 2, 0, 2 * Math.PI, false); | |
103 | ctx.closePath(); | |
104 | ctx.fill(); | |
105 | }; | |
106 | ||
107 | this.move = function() { | |
108 | this.counter += this.rate * 0.66; | |
109 | if (this.rate > 0.07) this.rate -= 0.01; | |
110 | }; | |
111 | ||
112 | this.onclick = function() { | |
113 | this.rate *= 3; | |
114 | if (this.rate > this.maxRate) { | |
115 | this.rate = this.maxRate; | |
116 | } | |
117 | }; | |
118 | ||
119 | this.containsPoint = function(x, y) { | |
120 | var r = this.getWidth() / 2; | |
121 | var dx = x - this.getX(); | |
122 | var dy = y - this.getY(); | |
123 | var dist = dx * dx + dy * dy; | |
124 | return dist < r * r; | |
125 | }; | |
126 | }; | |
127 | ||
128 | HeronsisHermnonicii = function() { | |
129 | var ctx; | |
130 | var request; | |
131 | ||
132 | var manager; | |
133 | var landscape = []; | |
134 | var treescape = []; | |
135 | ||
136 | this.draw = function() { | |
137 | ctx.fillStyle = "#ddccff"; | |
138 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
139 | ||
140 | ctx.fillStyle = "#ffdd66"; | |
141 | var s = canvas.width / (landscape.length - 1); | |
142 | for (var i = 0; i < landscape.length - 1; i++) { | |
143 | ctx.beginPath(); | |
144 | ctx.moveTo(i * s - 1, landscape[i]); | |
145 | ctx.lineTo(i * s - 1, canvas.height); | |
146 | ctx.lineTo((i+1) * s, canvas.height); | |
147 | ctx.lineTo((i+1) * s, landscape[i+1]); | |
148 | ctx.closePath(); | |
149 | ctx.fill(); | |
150 | } | |
151 | ||
152 | ctx.fillStyle = "#88ffaa"; | |
153 | var s = canvas.width / (treescape.length - 1); | |
154 | for (var i = 0; i < treescape.length - 1; i++) { | |
155 | ctx.beginPath(); | |
156 | ctx.moveTo(i * s - 1, treescape[i]); | |
157 | ctx.lineTo(i * s - 1, canvas.height); | |
158 | ctx.lineTo((i+1) * s, canvas.height); | |
159 | ctx.lineTo((i+1) * s, treescape[i+1]); | |
160 | ctx.closePath(); | |
161 | ctx.fill(); | |
162 | } | |
163 | ||
164 | // draw sprites | |
165 | manager.draw(ctx); | |
166 | }; | |
167 | ||
168 | this.update = function() { | |
169 | manager.move(); | |
170 | }; | |
171 | ||
172 | this.init = function(c) { | |
173 | Floater.prototype = new yoob.Sprite(); | |
174 | ||
175 | canvas = c; | |
176 | ctx = canvas.getContext('2d'); | |
177 | ||
178 | manager = new yoob.SpriteManager(); | |
179 | manager.init({ | |
180 | canvas: canvas | |
181 | }); | |
182 | ||
183 | var closeness = 5; | |
184 | for (var i = 1; i < 30; i++) { | |
185 | var f = new Floater(); | |
186 | var w = closeness; | |
187 | var x = Math.random() * (canvas.width - w * 2); | |
188 | var y = Math.random() * (canvas.height - w * 2); | |
189 | f.init({ | |
190 | x: x, | |
191 | y: y, | |
192 | width: w, | |
193 | height: w | |
194 | }); | |
195 | f.counter = Math.random() * Math.PI * 2; | |
196 | manager.addSprite(f); | |
197 | manager.moveToBack(f); | |
198 | closeness *= 1.1; | |
199 | } | |
200 | ||
201 | for (var i = 0; i < 10; i += 1) { | |
202 | landscape[i] = canvas.height / 2 + (Math.random() * 60 - 30); | |
203 | } | |
204 | ||
205 | for (var i = 0; i < 30; i += 1) { | |
206 | treescape[i] = canvas.height * 0.75 + (Math.random() * 60 - 30); | |
207 | } | |
208 | ||
209 | // TODO might be better with a ProportionalAnimationFrame, | |
210 | // but yoob.Sprite needs to support that better first | |
211 | this.animation = (new yoob.Animation()).init({ | |
212 | object: this | |
213 | }); | |
214 | this.animation.start(); | |
215 | }; | |
216 | } |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var t = new HirsuteMiasma(); | |
13 | var canvas = yoob.makeCanvas(container, 400, 400); | |
14 | container.appendChild(document.createElement('br')); | |
15 | var choleric = yoob.makeCheckbox( | |
16 | container, false, "choleric", t.setCholeric | |
17 | ); | |
18 | var terminal = yoob.makeCheckbox( | |
19 | container, false, "terminal", t.setTerminal | |
20 | ); | |
21 | t.init(canvas); | |
22 | } | |
23 | }; | |
24 | document.body.appendChild(elem); | |
25 | } | |
26 | } | |
27 | ||
28 | HirsuteMiasma = function() { | |
29 | var canvas; | |
30 | var ctx; | |
31 | var request; | |
32 | ||
33 | var x; | |
34 | var y; | |
35 | var v = 255; // darkness | |
36 | var theta = 0; // in degrees | |
37 | var dist = 5; | |
38 | var tick = 0; | |
39 | var grab = 0; | |
40 | var flickMode = 0; | |
41 | var terminal = false; | |
42 | ||
43 | this.setCholeric = function(b) { | |
44 | flickMode = b; | |
45 | }; | |
46 | ||
47 | this.setTerminal = function(b) { | |
48 | terminal = b; | |
49 | }; | |
50 | ||
51 | this.draw = function() { | |
52 | x = canvas.width / 2; | |
53 | y = canvas.height / 2; | |
54 | ||
55 | ctx.beginPath(); | |
56 | ctx.lineWidth = 2; | |
57 | ctx.strokeStyle = "rgb(" + v +"," + v + "," + v + ")"; | |
58 | ctx.moveTo(x, y); | |
59 | while (!(x < 0 || x > canvas.width || y < 0 || y > canvas.height)) { | |
60 | var rad = (theta / 360) * (Math.PI * 2); | |
61 | ||
62 | var dx = dist * Math.cos(rad); | |
63 | var dy = dist * Math.sin(rad); | |
64 | ||
65 | var newX = x + dx; | |
66 | var newY = y + dy; | |
67 | ||
68 | ctx.lineTo(newX, newY); | |
69 | ||
70 | x = newX; | |
71 | y = newY; | |
72 | ||
73 | if (Math.random() > 0.5) { | |
74 | theta += 22.5; | |
75 | } else { | |
76 | theta -= 22.5; | |
77 | } | |
78 | } | |
79 | ctx.stroke(); | |
80 | }; | |
81 | ||
82 | this.update = function() { | |
83 | var prevV = v; | |
84 | v = Math.floor((Math.cos(tick / 250) + 1) * 128); | |
85 | ||
86 | if ((prevV === 1 && v === 0) || (prevV === 254 && v === 255)) { | |
87 | grab = 350; | |
88 | } | |
89 | ||
90 | if (flickMode) { | |
91 | if (prevV === 255) v = 0; else v = 255; | |
92 | } | |
93 | ||
94 | if (!flickMode) { | |
95 | if (!grab) { | |
96 | tick++; | |
97 | } else { | |
98 | if (terminal && v === 0) { | |
99 | // nop | |
100 | } else { | |
101 | grab--; | |
102 | } | |
103 | } | |
104 | } | |
105 | }; | |
106 | ||
107 | this.init = function(c) { | |
108 | canvas = c; | |
109 | ctx = canvas.getContext('2d'); | |
110 | this.animation = (new yoob.Animation()).init({ object: this }); | |
111 | this.animation.start(); | |
112 | }; | |
113 | }; |
16 | 16 | <div id="container"></div> |
17 | 17 | |
18 | 18 | </body> |
19 | <script src="hirsute-miasma.js"></script> | |
19 | <script src="index.js"></script> | |
20 | 20 | <script> |
21 | 21 | launch('../common-yoob.js-0.11/', 'container'); |
22 | 22 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var t = new HirsuteMiasma(); | |
13 | var canvas = yoob.makeCanvas(container, 400, 400); | |
14 | container.appendChild(document.createElement('br')); | |
15 | var choleric = yoob.makeCheckbox( | |
16 | container, false, "choleric", t.setCholeric | |
17 | ); | |
18 | var terminal = yoob.makeCheckbox( | |
19 | container, false, "terminal", t.setTerminal | |
20 | ); | |
21 | t.init(canvas); | |
22 | } | |
23 | }; | |
24 | document.body.appendChild(elem); | |
25 | } | |
26 | } | |
27 | ||
28 | HirsuteMiasma = function() { | |
29 | var canvas; | |
30 | var ctx; | |
31 | var request; | |
32 | ||
33 | var x; | |
34 | var y; | |
35 | var v = 255; // darkness | |
36 | var theta = 0; // in degrees | |
37 | var dist = 5; | |
38 | var tick = 0; | |
39 | var grab = 0; | |
40 | var flickMode = 0; | |
41 | var terminal = false; | |
42 | ||
43 | this.setCholeric = function(b) { | |
44 | flickMode = b; | |
45 | }; | |
46 | ||
47 | this.setTerminal = function(b) { | |
48 | terminal = b; | |
49 | }; | |
50 | ||
51 | this.draw = function() { | |
52 | x = canvas.width / 2; | |
53 | y = canvas.height / 2; | |
54 | ||
55 | ctx.beginPath(); | |
56 | ctx.lineWidth = 2; | |
57 | ctx.strokeStyle = "rgb(" + v +"," + v + "," + v + ")"; | |
58 | ctx.moveTo(x, y); | |
59 | while (!(x < 0 || x > canvas.width || y < 0 || y > canvas.height)) { | |
60 | var rad = (theta / 360) * (Math.PI * 2); | |
61 | ||
62 | var dx = dist * Math.cos(rad); | |
63 | var dy = dist * Math.sin(rad); | |
64 | ||
65 | var newX = x + dx; | |
66 | var newY = y + dy; | |
67 | ||
68 | ctx.lineTo(newX, newY); | |
69 | ||
70 | x = newX; | |
71 | y = newY; | |
72 | ||
73 | if (Math.random() > 0.5) { | |
74 | theta += 22.5; | |
75 | } else { | |
76 | theta -= 22.5; | |
77 | } | |
78 | } | |
79 | ctx.stroke(); | |
80 | }; | |
81 | ||
82 | this.update = function() { | |
83 | var prevV = v; | |
84 | v = Math.floor((Math.cos(tick / 250) + 1) * 128); | |
85 | ||
86 | if ((prevV === 1 && v === 0) || (prevV === 254 && v === 255)) { | |
87 | grab = 350; | |
88 | } | |
89 | ||
90 | if (flickMode) { | |
91 | if (prevV === 255) v = 0; else v = 255; | |
92 | } | |
93 | ||
94 | if (!flickMode) { | |
95 | if (!grab) { | |
96 | tick++; | |
97 | } else { | |
98 | if (terminal && v === 0) { | |
99 | // nop | |
100 | } else { | |
101 | grab--; | |
102 | } | |
103 | } | |
104 | } | |
105 | }; | |
106 | ||
107 | this.init = function(c) { | |
108 | canvas = c; | |
109 | ctx = canvas.getContext('2d'); | |
110 | this.animation = (new yoob.Animation()).init({ object: this }); | |
111 | this.animation.start(); | |
112 | }; | |
113 | }; |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | "sprite-manager.js" | |
5 | ]; | |
6 | var loaded = 0; | |
7 | for (var i = 0; i < deps.length; i++) { | |
8 | var elem = document.createElement('script'); | |
9 | elem.src = prefix + deps[i]; | |
10 | elem.onload = function() { | |
11 | if (++loaded == deps.length) { | |
12 | var container = document.getElementById(containerId); | |
13 | ||
14 | var t = new Hypongtrochoid(); | |
15 | ||
16 | var overlayCanvas = yoob.makeCanvas(container, 600, 400); | |
17 | overlayCanvas.style.position = 'absolute'; | |
18 | overlayCanvas.style.zIndex = "100"; | |
19 | overlayCanvas.style.background = 'transparent'; | |
20 | ||
21 | var canvas = yoob.makeCanvas(container, 600, 400); | |
22 | canvas.style.zIndex = "0"; | |
23 | ||
24 | yoob.makeLineBreak(container); | |
25 | var show_blue = yoob.makeCheckbox( | |
26 | container, true, "blue", t.setShowBlue | |
27 | ); | |
28 | var show_red = yoob.makeCheckbox( | |
29 | container, true, "red", t.setShowRed | |
30 | ); | |
31 | var show_yellow = yoob.makeCheckbox( | |
32 | container, true, "yellow", t.setShowYellow | |
33 | ); | |
34 | var show_path = yoob.makeCheckbox( | |
35 | container, true, "path", function(b) { | |
36 | overlayCanvas.style.display = b ? "block" : "none"; | |
37 | } | |
38 | ); | |
39 | var turbo = yoob.makeCheckbox( | |
40 | container, false, "turbo", t.setTurbo | |
41 | ); | |
42 | t.init(canvas, overlayCanvas); | |
43 | } | |
44 | }; | |
45 | document.body.appendChild(elem); | |
46 | } | |
47 | } | |
48 | ||
49 | // this still knows maybe a little too much about the internals of yoob.Sprite | |
50 | Rectangle = function() { | |
51 | this.init = function(x, y, dx, dy, w, h, style, relativeTo) { | |
52 | Rectangle.prototype.init.apply(this, [{ | |
53 | x: x, | |
54 | y: y, | |
55 | dx: dx, | |
56 | dy: dy, | |
57 | width: w, | |
58 | height: h, | |
59 | fillStyle: style | |
60 | }]); | |
61 | this.relativeTo = relativeTo; | |
62 | return this; | |
63 | }; | |
64 | ||
65 | this.onmove = function() { | |
66 | var x = this.x; | |
67 | var y = this.y; | |
68 | if (this.scrawlOn !== undefined) { | |
69 | if (this.lastX !== undefined) { | |
70 | var ctx = this.scrawlOn; | |
71 | ctx.beginPath(); | |
72 | ctx.strokeStyle = "rgba(0, 0, 0, 0.5)"; | |
73 | ctx.lineWidth = 2; | |
74 | ctx.moveTo(this.lastX, this.lastY); | |
75 | ctx.lineTo(this.getCenterX(), this.getCenterY()); | |
76 | ctx.stroke(); | |
77 | } | |
78 | this.lastX = this.getCenterX(); | |
79 | this.lastY = this.getCenterY(); | |
80 | } | |
81 | if (x < 0 || x + this.getWidth() > this.relativeTo.getWidth()) { | |
82 | this.dx *= -1; | |
83 | } | |
84 | if (y < 0 || y + this.getHeight() > this.relativeTo.getHeight()) { | |
85 | this.dy *= -1; | |
86 | } | |
87 | }; | |
88 | ||
89 | this.getX = function() { | |
90 | if (this.relativeTo !== null) { | |
91 | return this.x + this.relativeTo.getX(); | |
92 | } else { | |
93 | return this.x; | |
94 | } | |
95 | }; | |
96 | ||
97 | this.getCenterX = function() { | |
98 | return this.getX() + this.getWidth() / 2; | |
99 | }; | |
100 | ||
101 | this.getY = function() { | |
102 | if (this.relativeTo !== null) { | |
103 | return this.y + this.relativeTo.getY(); | |
104 | } else { | |
105 | return this.y; | |
106 | } | |
107 | }; | |
108 | ||
109 | this.getCenterY = function() { | |
110 | return this.getY() + this.getHeight() / 2; | |
111 | }; | |
112 | ||
113 | this.draw = function(ctx) { | |
114 | if (this.visible) { | |
115 | ctx.fillStyle = this.fillStyle; | |
116 | ctx.fillRect( | |
117 | this.getX(), this.getY(), this.getWidth(), this.getHeight() | |
118 | ); | |
119 | } | |
120 | }; | |
121 | }; | |
122 | ||
123 | Hypongtrochoid = function() { | |
124 | var canvas; | |
125 | var overlayCanvas; | |
126 | var ctx; | |
127 | var overlayCtx; | |
128 | var turbo = false; | |
129 | ||
130 | var manager; | |
131 | ||
132 | var blueRectangle; | |
133 | var redRectangle; | |
134 | var yellowRectangle; | |
135 | ||
136 | this.setShowBlue = function(b) { | |
137 | blueRectangle.visible = b; | |
138 | }; | |
139 | ||
140 | this.setShowRed = function(b) { | |
141 | redRectangle.visible = b; | |
142 | }; | |
143 | ||
144 | this.setShowYellow = function(b) { | |
145 | yellowRectangle.visible = b; | |
146 | }; | |
147 | ||
148 | this.setTurbo = function(b) { | |
149 | turbo = b; | |
150 | }; | |
151 | ||
152 | this.draw = function() { | |
153 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
154 | manager.draw(ctx); | |
155 | }; | |
156 | ||
157 | this.update = function() { | |
158 | var n = turbo ? 10 : 1; | |
159 | for (var i = 0; i < n; i++) { | |
160 | manager.move(); | |
161 | } | |
162 | }; | |
163 | ||
164 | this.init = function(c, oc) { | |
165 | Rectangle.prototype = new yoob.Sprite(); | |
166 | ||
167 | canvas = c; | |
168 | overlayCanvas = oc; | |
169 | manager = (new yoob.SpriteManager()).init({ | |
170 | canvas: canvas | |
171 | }); | |
172 | ctx = canvas.getContext('2d'); | |
173 | overlayCtx = overlayCanvas.getContext('2d'); | |
174 | ||
175 | var outside = new Rectangle(); | |
176 | outside.init( | |
177 | 0, 0, 0, 0, canvas.width, canvas.height, '', null | |
178 | ); | |
179 | ||
180 | blueRectangle = new Rectangle(); | |
181 | blueRectangle.init( | |
182 | 50, 50, -1, 1, 200, 200, 'blue', outside | |
183 | ); | |
184 | ||
185 | redRectangle = new Rectangle(); | |
186 | redRectangle.init( | |
187 | 50, 50, -0.75, 0.75, 50, 50, 'red', blueRectangle | |
188 | ); | |
189 | ||
190 | yellowRectangle = new Rectangle(); | |
191 | yellowRectangle.init( | |
192 | 10, 10, 0.5, -0.5, 10, 10, 'yellow', redRectangle | |
193 | ); | |
194 | yellowRectangle.scrawlOn = overlayCtx; | |
195 | ||
196 | manager.addSprite(yellowRectangle); | |
197 | manager.addSprite(redRectangle); | |
198 | manager.addSprite(blueRectangle); | |
199 | ||
200 | this.animation = (new yoob.Animation()).init({ | |
201 | object: this | |
202 | }); | |
203 | this.animation.start(); | |
204 | }; | |
205 | } |
18 | 18 | <div id="container"></div> |
19 | 19 | |
20 | 20 | </body> |
21 | <script src="hypongtrochoid.js"></script> | |
21 | <script src="index.js"></script> | |
22 | 22 | <script> |
23 | 23 | launch('../common-yoob.js-0.11/', 'container'); |
24 | 24 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | "sprite-manager.js" | |
5 | ]; | |
6 | var loaded = 0; | |
7 | for (var i = 0; i < deps.length; i++) { | |
8 | var elem = document.createElement('script'); | |
9 | elem.src = prefix + deps[i]; | |
10 | elem.onload = function() { | |
11 | if (++loaded == deps.length) { | |
12 | var container = document.getElementById(containerId); | |
13 | ||
14 | var t = new Hypongtrochoid(); | |
15 | ||
16 | var overlayCanvas = yoob.makeCanvas(container, 600, 400); | |
17 | overlayCanvas.style.position = 'absolute'; | |
18 | overlayCanvas.style.zIndex = "100"; | |
19 | overlayCanvas.style.background = 'transparent'; | |
20 | ||
21 | var canvas = yoob.makeCanvas(container, 600, 400); | |
22 | canvas.style.zIndex = "0"; | |
23 | ||
24 | yoob.makeLineBreak(container); | |
25 | var show_blue = yoob.makeCheckbox( | |
26 | container, true, "blue", t.setShowBlue | |
27 | ); | |
28 | var show_red = yoob.makeCheckbox( | |
29 | container, true, "red", t.setShowRed | |
30 | ); | |
31 | var show_yellow = yoob.makeCheckbox( | |
32 | container, true, "yellow", t.setShowYellow | |
33 | ); | |
34 | var show_path = yoob.makeCheckbox( | |
35 | container, true, "path", function(b) { | |
36 | overlayCanvas.style.display = b ? "block" : "none"; | |
37 | } | |
38 | ); | |
39 | var turbo = yoob.makeCheckbox( | |
40 | container, false, "turbo", t.setTurbo | |
41 | ); | |
42 | t.init(canvas, overlayCanvas); | |
43 | } | |
44 | }; | |
45 | document.body.appendChild(elem); | |
46 | } | |
47 | } | |
48 | ||
49 | // this still knows maybe a little too much about the internals of yoob.Sprite | |
50 | Rectangle = function() { | |
51 | this.init = function(x, y, dx, dy, w, h, style, relativeTo) { | |
52 | Rectangle.prototype.init.apply(this, [{ | |
53 | x: x, | |
54 | y: y, | |
55 | dx: dx, | |
56 | dy: dy, | |
57 | width: w, | |
58 | height: h, | |
59 | fillStyle: style | |
60 | }]); | |
61 | this.relativeTo = relativeTo; | |
62 | return this; | |
63 | }; | |
64 | ||
65 | this.onmove = function() { | |
66 | var x = this.x; | |
67 | var y = this.y; | |
68 | if (this.scrawlOn !== undefined) { | |
69 | if (this.lastX !== undefined) { | |
70 | var ctx = this.scrawlOn; | |
71 | ctx.beginPath(); | |
72 | ctx.strokeStyle = "rgba(0, 0, 0, 0.5)"; | |
73 | ctx.lineWidth = 2; | |
74 | ctx.moveTo(this.lastX, this.lastY); | |
75 | ctx.lineTo(this.getCenterX(), this.getCenterY()); | |
76 | ctx.stroke(); | |
77 | } | |
78 | this.lastX = this.getCenterX(); | |
79 | this.lastY = this.getCenterY(); | |
80 | } | |
81 | if (x < 0 || x + this.getWidth() > this.relativeTo.getWidth()) { | |
82 | this.dx *= -1; | |
83 | } | |
84 | if (y < 0 || y + this.getHeight() > this.relativeTo.getHeight()) { | |
85 | this.dy *= -1; | |
86 | } | |
87 | }; | |
88 | ||
89 | this.getX = function() { | |
90 | if (this.relativeTo !== null) { | |
91 | return this.x + this.relativeTo.getX(); | |
92 | } else { | |
93 | return this.x; | |
94 | } | |
95 | }; | |
96 | ||
97 | this.getCenterX = function() { | |
98 | return this.getX() + this.getWidth() / 2; | |
99 | }; | |
100 | ||
101 | this.getY = function() { | |
102 | if (this.relativeTo !== null) { | |
103 | return this.y + this.relativeTo.getY(); | |
104 | } else { | |
105 | return this.y; | |
106 | } | |
107 | }; | |
108 | ||
109 | this.getCenterY = function() { | |
110 | return this.getY() + this.getHeight() / 2; | |
111 | }; | |
112 | ||
113 | this.draw = function(ctx) { | |
114 | if (this.visible) { | |
115 | ctx.fillStyle = this.fillStyle; | |
116 | ctx.fillRect( | |
117 | this.getX(), this.getY(), this.getWidth(), this.getHeight() | |
118 | ); | |
119 | } | |
120 | }; | |
121 | }; | |
122 | ||
123 | Hypongtrochoid = function() { | |
124 | var canvas; | |
125 | var overlayCanvas; | |
126 | var ctx; | |
127 | var overlayCtx; | |
128 | var turbo = false; | |
129 | ||
130 | var manager; | |
131 | ||
132 | var blueRectangle; | |
133 | var redRectangle; | |
134 | var yellowRectangle; | |
135 | ||
136 | this.setShowBlue = function(b) { | |
137 | blueRectangle.visible = b; | |
138 | }; | |
139 | ||
140 | this.setShowRed = function(b) { | |
141 | redRectangle.visible = b; | |
142 | }; | |
143 | ||
144 | this.setShowYellow = function(b) { | |
145 | yellowRectangle.visible = b; | |
146 | }; | |
147 | ||
148 | this.setTurbo = function(b) { | |
149 | turbo = b; | |
150 | }; | |
151 | ||
152 | this.draw = function() { | |
153 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
154 | manager.draw(ctx); | |
155 | }; | |
156 | ||
157 | this.update = function() { | |
158 | var n = turbo ? 10 : 1; | |
159 | for (var i = 0; i < n; i++) { | |
160 | manager.move(); | |
161 | } | |
162 | }; | |
163 | ||
164 | this.init = function(c, oc) { | |
165 | Rectangle.prototype = new yoob.Sprite(); | |
166 | ||
167 | canvas = c; | |
168 | overlayCanvas = oc; | |
169 | manager = (new yoob.SpriteManager()).init({ | |
170 | canvas: canvas | |
171 | }); | |
172 | ctx = canvas.getContext('2d'); | |
173 | overlayCtx = overlayCanvas.getContext('2d'); | |
174 | ||
175 | var outside = new Rectangle(); | |
176 | outside.init( | |
177 | 0, 0, 0, 0, canvas.width, canvas.height, '', null | |
178 | ); | |
179 | ||
180 | blueRectangle = new Rectangle(); | |
181 | blueRectangle.init( | |
182 | 50, 50, -1, 1, 200, 200, 'blue', outside | |
183 | ); | |
184 | ||
185 | redRectangle = new Rectangle(); | |
186 | redRectangle.init( | |
187 | 50, 50, -0.75, 0.75, 50, 50, 'red', blueRectangle | |
188 | ); | |
189 | ||
190 | yellowRectangle = new Rectangle(); | |
191 | yellowRectangle.init( | |
192 | 10, 10, 0.5, -0.5, 10, 10, 'yellow', redRectangle | |
193 | ); | |
194 | yellowRectangle.scrawlOn = overlayCtx; | |
195 | ||
196 | manager.addSprite(yellowRectangle); | |
197 | manager.addSprite(redRectangle); | |
198 | manager.addSprite(blueRectangle); | |
199 | ||
200 | this.animation = (new yoob.Animation()).init({ | |
201 | object: this | |
202 | }); | |
203 | this.animation.start(); | |
204 | }; | |
205 | } |
16 | 16 | <div id="container"></div> |
17 | 17 | |
18 | 18 | </body> |
19 | <script src="kolakoski-kurve.js"></script> | |
19 | <script src="index.js"></script> | |
20 | 20 | <script> |
21 | 21 | launch('../common-yoob.js-0.11/', 'container'); |
22 | 22 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var gewgaw = new KolakoskiKurve(); | |
13 | ||
14 | var canvas = yoob.makeCanvas(container, 800, 600); | |
15 | yoob.makeLineBreak(container); | |
16 | yoob.makeSliderPlusTextInput(container, "Segment length:", 2, 25, (2), 5, function(v) { | |
17 | gewgaw.dist = v; | |
18 | }); | |
19 | yoob.makeLineBreak(container); | |
20 | yoob.makeSliderPlusTextInput(container, "Start index", 1, 10000, 5, 1, function(v) { | |
21 | gewgaw.startIndex = v - 1; | |
22 | gewgaw.reset(); | |
23 | }); | |
24 | yoob.makeLineBreak(container); | |
25 | yoob.makeSliderPlusTextInput(container, "End index", 1, 10000, 5, 10000, function(v) { | |
26 | gewgaw.endIndex = v - 1; | |
27 | gewgaw.reset(); | |
28 | }); | |
29 | yoob.makeLineBreak(container); | |
30 | yoob.makeCheckbox( | |
31 | container, true, "opaque", function(bool) { | |
32 | gewgaw.ctx.strokeStyle = bool ? "black" : "rgba(0,0,0,0.1)"; | |
33 | } | |
34 | ); | |
35 | yoob.makeCheckbox( | |
36 | container, false, "xor", function(bool) { | |
37 | gewgaw.ctx.globalCompositeOperation = bool ? "xor" : "source-over"; | |
38 | gewgaw.reset(); | |
39 | } | |
40 | ); | |
41 | yoob.makeLineBreak(container); | |
42 | var button = yoob.makeButton(container, 'Reset', function() { | |
43 | gewgaw.reset(); | |
44 | }); | |
45 | gewgaw.init(canvas); | |
46 | } | |
47 | }; | |
48 | document.body.appendChild(elem); | |
49 | } | |
50 | } | |
51 | ||
52 | ||
53 | KolakoskiKurve = function() { | |
54 | this.init = function(canvas) { | |
55 | this.canvas = canvas; | |
56 | this.ctx = this.canvas.getContext('2d'); | |
57 | ||
58 | this.ctx.lineWidth = 2; | |
59 | this.ctx.strokeStyle = "black"; | |
60 | this.ctx.globalCompositeOperation = 'source-over'; | |
61 | this.dist = 5; | |
62 | ||
63 | this.startIndex = 0; | |
64 | this.endIndex = 10000; | |
65 | this.stepSize = 10; | |
66 | this.reset(); | |
67 | }; | |
68 | ||
69 | this.reset = function() { | |
70 | this.ctx.fillStyle = 'white'; | |
71 | this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); | |
72 | ||
73 | this.x = this.canvas.width / 2; | |
74 | this.y = this.canvas.height - 10; | |
75 | this.y = this.canvas.height / 2; | |
76 | this.theta = 0; | |
77 | ||
78 | this.index = this.startIndex; | |
79 | ||
80 | this.generate(this.endIndex); // sets this.sequence and this.genIndex | |
81 | ||
82 | if (this.animation) this.animation.stop(); | |
83 | this.animation = (new yoob.Animation()).init({ object: this }); | |
84 | this.animation.start(); | |
85 | }; | |
86 | ||
87 | this.step = function() { | |
88 | if (this.index >= this.endIndex) return; | |
89 | ||
90 | var num = this.sequence[this.index]; | |
91 | ||
92 | if (num === 1) { | |
93 | // FD 10 | |
94 | var rad = (this.theta / 360) * (Math.PI * 2); | |
95 | ||
96 | var dx = this.dist * Math.cos(rad); | |
97 | var dy = this.dist * Math.sin(rad); | |
98 | ||
99 | var newX = this.x + dx; | |
100 | var newY = this.y + dy; | |
101 | ||
102 | this.ctx.beginPath(); | |
103 | this.ctx.moveTo(this.x, this.y); | |
104 | this.ctx.lineTo(newX, newY); | |
105 | this.ctx.stroke(); | |
106 | ||
107 | this.x = newX; | |
108 | this.y = newY; | |
109 | } else if (num === 2) { | |
110 | // RT 90 | |
111 | this.theta += 90; | |
112 | while (this.theta >= 360) this.theta -= 360; | |
113 | } else { | |
114 | alert('wtf'); | |
115 | } | |
116 | ||
117 | this.index++; | |
118 | }; | |
119 | ||
120 | this.draw = function() { | |
121 | if (this.index >= this.endIndex) { | |
122 | this.animation.stop(); | |
123 | return; | |
124 | } | |
125 | ||
126 | for (var j = 0; j < this.stepSize; j++) { | |
127 | this.step(); | |
128 | } | |
129 | }; | |
130 | ||
131 | this.update = function() { | |
132 | }; | |
133 | ||
134 | /* | |
135 | * Generate at least n values of the Kolakoski sequence, starting at where-ever we | |
136 | * last left off (or the beginning, if we were never called before.) | |
137 | */ | |
138 | this.generate = function(n) { | |
139 | if (this.sequence === undefined || this.sequence === null || this.sequence.length < 3) { | |
140 | this.sequence = [1, 2, 2]; | |
141 | } | |
142 | if (this.genIndex === undefined || this.genIndex === null) { | |
143 | this.genIndex = 3; | |
144 | } | |
145 | for (; this.sequence.length < n; this.genIndex++) { | |
146 | var newValue = this.genIndex % 2 === 1 ? 1 : 2; | |
147 | this.sequence.push(newValue); | |
148 | if (this.sequence[this.genIndex - 1] === 2) { | |
149 | this.sequence.push(newValue); | |
150 | } | |
151 | } | |
152 | }; | |
153 | }; |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var gewgaw = new KolakoskiKurve(); | |
13 | ||
14 | var canvas = yoob.makeCanvas(container, 800, 600); | |
15 | yoob.makeLineBreak(container); | |
16 | yoob.makeSliderPlusTextInput(container, "Segment length:", 2, 25, (2), 5, function(v) { | |
17 | gewgaw.dist = v; | |
18 | }); | |
19 | yoob.makeLineBreak(container); | |
20 | yoob.makeSliderPlusTextInput(container, "Start index", 1, 10000, 5, 1, function(v) { | |
21 | gewgaw.startIndex = v - 1; | |
22 | gewgaw.reset(); | |
23 | }); | |
24 | yoob.makeLineBreak(container); | |
25 | yoob.makeSliderPlusTextInput(container, "End index", 1, 10000, 5, 10000, function(v) { | |
26 | gewgaw.endIndex = v - 1; | |
27 | gewgaw.reset(); | |
28 | }); | |
29 | yoob.makeLineBreak(container); | |
30 | yoob.makeCheckbox( | |
31 | container, true, "opaque", function(bool) { | |
32 | gewgaw.ctx.strokeStyle = bool ? "black" : "rgba(0,0,0,0.1)"; | |
33 | } | |
34 | ); | |
35 | yoob.makeCheckbox( | |
36 | container, false, "xor", function(bool) { | |
37 | gewgaw.ctx.globalCompositeOperation = bool ? "xor" : "source-over"; | |
38 | gewgaw.reset(); | |
39 | } | |
40 | ); | |
41 | yoob.makeLineBreak(container); | |
42 | var button = yoob.makeButton(container, 'Reset', function() { | |
43 | gewgaw.reset(); | |
44 | }); | |
45 | gewgaw.init(canvas); | |
46 | } | |
47 | }; | |
48 | document.body.appendChild(elem); | |
49 | } | |
50 | } | |
51 | ||
52 | ||
53 | KolakoskiKurve = function() { | |
54 | this.init = function(canvas) { | |
55 | this.canvas = canvas; | |
56 | this.ctx = this.canvas.getContext('2d'); | |
57 | ||
58 | this.ctx.lineWidth = 2; | |
59 | this.ctx.strokeStyle = "black"; | |
60 | this.ctx.globalCompositeOperation = 'source-over'; | |
61 | this.dist = 5; | |
62 | ||
63 | this.startIndex = 0; | |
64 | this.endIndex = 10000; | |
65 | this.stepSize = 10; | |
66 | this.reset(); | |
67 | }; | |
68 | ||
69 | this.reset = function() { | |
70 | this.ctx.fillStyle = 'white'; | |
71 | this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); | |
72 | ||
73 | this.x = this.canvas.width / 2; | |
74 | this.y = this.canvas.height - 10; | |
75 | this.y = this.canvas.height / 2; | |
76 | this.theta = 0; | |
77 | ||
78 | this.index = this.startIndex; | |
79 | ||
80 | this.generate(this.endIndex); // sets this.sequence and this.genIndex | |
81 | ||
82 | if (this.animation) this.animation.stop(); | |
83 | this.animation = (new yoob.Animation()).init({ object: this }); | |
84 | this.animation.start(); | |
85 | }; | |
86 | ||
87 | this.step = function() { | |
88 | if (this.index >= this.endIndex) return; | |
89 | ||
90 | var num = this.sequence[this.index]; | |
91 | ||
92 | if (num === 1) { | |
93 | // FD 10 | |
94 | var rad = (this.theta / 360) * (Math.PI * 2); | |
95 | ||
96 | var dx = this.dist * Math.cos(rad); | |
97 | var dy = this.dist * Math.sin(rad); | |
98 | ||
99 | var newX = this.x + dx; | |
100 | var newY = this.y + dy; | |
101 | ||
102 | this.ctx.beginPath(); | |
103 | this.ctx.moveTo(this.x, this.y); | |
104 | this.ctx.lineTo(newX, newY); | |
105 | this.ctx.stroke(); | |
106 | ||
107 | this.x = newX; | |
108 | this.y = newY; | |
109 | } else if (num === 2) { | |
110 | // RT 90 | |
111 | this.theta += 90; | |
112 | while (this.theta >= 360) this.theta -= 360; | |
113 | } else { | |
114 | alert('wtf'); | |
115 | } | |
116 | ||
117 | this.index++; | |
118 | }; | |
119 | ||
120 | this.draw = function() { | |
121 | if (this.index >= this.endIndex) { | |
122 | this.animation.stop(); | |
123 | return; | |
124 | } | |
125 | ||
126 | for (var j = 0; j < this.stepSize; j++) { | |
127 | this.step(); | |
128 | } | |
129 | }; | |
130 | ||
131 | this.update = function() { | |
132 | }; | |
133 | ||
134 | /* | |
135 | * Generate at least n values of the Kolakoski sequence, starting at where-ever we | |
136 | * last left off (or the beginning, if we were never called before.) | |
137 | */ | |
138 | this.generate = function(n) { | |
139 | if (this.sequence === undefined || this.sequence === null || this.sequence.length < 3) { | |
140 | this.sequence = [1, 2, 2]; | |
141 | } | |
142 | if (this.genIndex === undefined || this.genIndex === null) { | |
143 | this.genIndex = 3; | |
144 | } | |
145 | for (; this.sequence.length < n; this.genIndex++) { | |
146 | var newValue = this.genIndex % 2 === 1 ? 1 : 2; | |
147 | this.sequence.push(newValue); | |
148 | if (this.sequence[this.genIndex - 1] === 2) { | |
149 | this.sequence.push(newValue); | |
150 | } | |
151 | } | |
152 | }; | |
153 | }; |
21 | 21 | </div> |
22 | 22 | |
23 | 23 | </body> |
24 | <script src="markov-font.js"></script> | |
24 | <script src="index.js"></script> | |
25 | 25 | <script> |
26 | 26 | launch('../common-yoob.js-0.11/', 'container', { |
27 | 27 | // to not have to mess with cross-domain security whatever |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId, config) { | |
3 | var config = config || {}; | |
4 | var deps = [ | |
5 | "element-factory.js", | |
6 | "chargen.js", | |
7 | "animation.js" | |
8 | ]; | |
9 | var loaded = 0; | |
10 | for (var i = 0; i < deps.length; i++) { | |
11 | var elem = document.createElement('script'); | |
12 | elem.src = prefix + deps[i]; | |
13 | elem.onload = function() { | |
14 | if (++loaded < deps.length) return; | |
15 | var container = document.getElementById(containerId); | |
16 | ||
17 | var gewgaw = (new MarkovFont()); | |
18 | ||
19 | var peepHole = yoob.makeDiv(container); | |
20 | var canvas = yoob.makeCanvas(peepHole); | |
21 | canvas.width = 9; | |
22 | canvas.height = 9; | |
23 | ||
24 | var bucket = yoob.makeDiv(container); | |
25 | bucket.style.width = "512px"; | |
26 | bucket.style.marginLeft = "auto"; | |
27 | bucket.style.marginRight = "auto"; | |
28 | bucket.style.background = "#a0a0a0"; | |
29 | ||
30 | gewgaw.init({ | |
31 | canvas: canvas, | |
32 | bucket: bucket, | |
33 | imgUrl: config.imgUrl | |
34 | }); | |
35 | }; | |
36 | document.body.appendChild(elem); | |
37 | } | |
38 | } | |
39 | ||
40 | ||
41 | var MarkovFont = function() { | |
42 | this.init = function(cfg) { | |
43 | this.canvas = cfg.canvas; | |
44 | this.bucket = cfg.bucket; | |
45 | this.ctx = this.canvas.getContext('2d'); | |
46 | this.charHeight = 8; | |
47 | this.charWidth = 8; | |
48 | ||
49 | this.palette = [[0, 0, 0], [255, 255, 255]]; | |
50 | ||
51 | var $this = this; | |
52 | this.chargen = (new yoob.Chargen()).init({ | |
53 | charsPerRow: 32, | |
54 | rows: 8, | |
55 | imageSrc: cfg.imgUrl, | |
56 | colorTriples: this.palette, | |
57 | colorToAlpha: this.palette[1], | |
58 | onLoad: function() { | |
59 | $this.start(); | |
60 | } | |
61 | }); | |
62 | ||
63 | return this; | |
64 | }; | |
65 | ||
66 | this.start = function() { | |
67 | this.charIndex = 0; | |
68 | this.table = { | |
69 | '0': {}, | |
70 | '1': {} | |
71 | }; | |
72 | var $this = this; | |
73 | this.intervalId = setInterval( | |
74 | function() { $this.examineChar(); }, | |
75 | 10 | |
76 | ); | |
77 | }; | |
78 | ||
79 | this.examineChar = function() { | |
80 | if (this.charIndex > 255) { | |
81 | console.log(uneval(this.table)); | |
82 | clearInterval(this.intervalId); | |
83 | this.canvas.parentElement.style.display = 'none'; | |
84 | this.generated = 0; | |
85 | var $this = this; | |
86 | this.intervalId = setInterval( | |
87 | function() { $this.generateChar($this.table); }, | |
88 | 64 | |
89 | ); | |
90 | return; | |
91 | } | |
92 | this.ctx.fillStyle = 'white'; | |
93 | this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); | |
94 | this.chargen.blitChar(this.charIndex, 0, this.ctx, 1, 1, 8, 8); | |
95 | this.surveyPixels(this.table); | |
96 | this.charIndex++; | |
97 | }; | |
98 | ||
99 | this.findColorInPalette = function(r, g, b) { | |
100 | for (var i = 0; i < this.palette.length; i++) { | |
101 | var t = this.palette[i]; | |
102 | if (r == t[0] && g == t[1] && b == t[2]) { | |
103 | return i; | |
104 | } | |
105 | } | |
106 | return null; | |
107 | }; | |
108 | ||
109 | this.pixelAt = function(imageData, x, y) { | |
110 | var w = this.canvas.width; | |
111 | var h = this.canvas.height; | |
112 | ||
113 | var index = (y * w + x) * 4; | |
114 | ||
115 | var r = imageData.data[index]; | |
116 | var g = imageData.data[index + 1]; | |
117 | var b = imageData.data[index + 2]; | |
118 | var a = imageData.data[index + 3]; | |
119 | ||
120 | return this.findColorInPalette(r, g, b); | |
121 | }; | |
122 | ||
123 | this.putPixel = function(imageData, x, y, color) { | |
124 | var w = this.canvas.width; | |
125 | var h = this.canvas.height; | |
126 | ||
127 | var index = (y * w + x) * 4; | |
128 | ||
129 | var t = this.palette[color]; | |
130 | imageData.data[index] = t[0]; | |
131 | imageData.data[index + 1] = t[1]; | |
132 | imageData.data[index + 2] = t[2]; | |
133 | // and leave alpha (data[index + 3]) unchanged */ | |
134 | }; | |
135 | ||
136 | this.surveyPixels = function(table) { | |
137 | var w = this.canvas.width; | |
138 | var h = this.canvas.height; | |
139 | var srcImageData = this.ctx.getImageData(0, 0, w, h); | |
140 | ||
141 | for (var x = 1; x < w; x++) { | |
142 | for (var y = 1; y < h; y++) { | |
143 | var color = this.pixelAt(srcImageData, x, y); | |
144 | var left = this.pixelAt(srcImageData, x-1, y); | |
145 | var above = this.pixelAt(srcImageData, x, y-1); | |
146 | var leftAbove = this.pixelAt(srcImageData, x-1, y-1); | |
147 | var key = left + ',' + leftAbove + ',' + above; | |
148 | if (table[color][key] === undefined) { | |
149 | table[color][key] = 1; | |
150 | } else { | |
151 | table[color][key]++; | |
152 | } | |
153 | } | |
154 | } | |
155 | }; | |
156 | ||
157 | this.generateChar = function(table) { | |
158 | if (this.generated >= 130) return; | |
159 | ||
160 | var canvas = yoob.makeCanvas(this.bucket); | |
161 | var ctx = canvas.getContext('2d'); | |
162 | canvas.width = 9; | |
163 | canvas.height = 9; | |
164 | ||
165 | canvas.style.margin = "10px"; | |
166 | ||
167 | var w = canvas.width; | |
168 | var h = canvas.height; | |
169 | ||
170 | ctx.fillStyle = 'white'; | |
171 | ctx.fillRect(0, 0, w, h); | |
172 | ||
173 | for (var x = 1; x < w; x++) { | |
174 | for (var y = 1; y < h; y++) { | |
175 | var srcImageData = ctx.getImageData(0, 0, w, h); | |
176 | ||
177 | var left = this.pixelAt(srcImageData, x-1, y); | |
178 | var above = this.pixelAt(srcImageData, x, y-1); | |
179 | var leftAbove = this.pixelAt(srcImageData, x-1, y-1); | |
180 | var key = left + ',' + leftAbove + ',' + above; | |
181 | ||
182 | var c0 = table['0'][key]; | |
183 | var c1 = table['1'][key]; | |
184 | var tot = c0 + c1; | |
185 | ||
186 | var pick = Math.floor(Math.random() * tot) + 1; | |
187 | var color = pick <= c0 ? 0 : 1; | |
188 | ||
189 | this.putPixel(srcImageData, x, y, color); | |
190 | ctx.putImageData(srcImageData, 0, 0); | |
191 | } | |
192 | } | |
193 | ||
194 | this.generated++; | |
195 | }; | |
196 | ||
197 | }; |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId, config) { | |
3 | var config = config || {}; | |
4 | var deps = [ | |
5 | "element-factory.js", | |
6 | "chargen.js", | |
7 | "animation.js" | |
8 | ]; | |
9 | var loaded = 0; | |
10 | for (var i = 0; i < deps.length; i++) { | |
11 | var elem = document.createElement('script'); | |
12 | elem.src = prefix + deps[i]; | |
13 | elem.onload = function() { | |
14 | if (++loaded < deps.length) return; | |
15 | var container = document.getElementById(containerId); | |
16 | ||
17 | var gewgaw = (new MarkovFont()); | |
18 | ||
19 | var peepHole = yoob.makeDiv(container); | |
20 | var canvas = yoob.makeCanvas(peepHole); | |
21 | canvas.width = 9; | |
22 | canvas.height = 9; | |
23 | ||
24 | var bucket = yoob.makeDiv(container); | |
25 | bucket.style.width = "512px"; | |
26 | bucket.style.marginLeft = "auto"; | |
27 | bucket.style.marginRight = "auto"; | |
28 | bucket.style.background = "#a0a0a0"; | |
29 | ||
30 | gewgaw.init({ | |
31 | canvas: canvas, | |
32 | bucket: bucket, | |
33 | imgUrl: config.imgUrl | |
34 | }); | |
35 | }; | |
36 | document.body.appendChild(elem); | |
37 | } | |
38 | } | |
39 | ||
40 | ||
41 | var MarkovFont = function() { | |
42 | this.init = function(cfg) { | |
43 | this.canvas = cfg.canvas; | |
44 | this.bucket = cfg.bucket; | |
45 | this.ctx = this.canvas.getContext('2d'); | |
46 | this.charHeight = 8; | |
47 | this.charWidth = 8; | |
48 | ||
49 | this.palette = [[0, 0, 0], [255, 255, 255]]; | |
50 | ||
51 | var $this = this; | |
52 | this.chargen = (new yoob.Chargen()).init({ | |
53 | charsPerRow: 32, | |
54 | rows: 8, | |
55 | imageSrc: cfg.imgUrl, | |
56 | colorTriples: this.palette, | |
57 | colorToAlpha: this.palette[1], | |
58 | onLoad: function() { | |
59 | $this.start(); | |
60 | } | |
61 | }); | |
62 | ||
63 | return this; | |
64 | }; | |
65 | ||
66 | this.start = function() { | |
67 | this.charIndex = 0; | |
68 | this.table = { | |
69 | '0': {}, | |
70 | '1': {} | |
71 | }; | |
72 | var $this = this; | |
73 | this.intervalId = setInterval( | |
74 | function() { $this.examineChar(); }, | |
75 | 10 | |
76 | ); | |
77 | }; | |
78 | ||
79 | this.examineChar = function() { | |
80 | if (this.charIndex > 255) { | |
81 | console.log(uneval(this.table)); | |
82 | clearInterval(this.intervalId); | |
83 | this.canvas.parentElement.style.display = 'none'; | |
84 | this.generated = 0; | |
85 | var $this = this; | |
86 | this.intervalId = setInterval( | |
87 | function() { $this.generateChar($this.table); }, | |
88 | 64 | |
89 | ); | |
90 | return; | |
91 | } | |
92 | this.ctx.fillStyle = 'white'; | |
93 | this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); | |
94 | this.chargen.blitChar(this.charIndex, 0, this.ctx, 1, 1, 8, 8); | |
95 | this.surveyPixels(this.table); | |
96 | this.charIndex++; | |
97 | }; | |
98 | ||
99 | this.findColorInPalette = function(r, g, b) { | |
100 | for (var i = 0; i < this.palette.length; i++) { | |
101 | var t = this.palette[i]; | |
102 | if (r == t[0] && g == t[1] && b == t[2]) { | |
103 | return i; | |
104 | } | |
105 | } | |
106 | return null; | |
107 | }; | |
108 | ||
109 | this.pixelAt = function(imageData, x, y) { | |
110 | var w = this.canvas.width; | |
111 | var h = this.canvas.height; | |
112 | ||
113 | var index = (y * w + x) * 4; | |
114 | ||
115 | var r = imageData.data[index]; | |
116 | var g = imageData.data[index + 1]; | |
117 | var b = imageData.data[index + 2]; | |
118 | var a = imageData.data[index + 3]; | |
119 | ||
120 | return this.findColorInPalette(r, g, b); | |
121 | }; | |
122 | ||
123 | this.putPixel = function(imageData, x, y, color) { | |
124 | var w = this.canvas.width; | |
125 | var h = this.canvas.height; | |
126 | ||
127 | var index = (y * w + x) * 4; | |
128 | ||
129 | var t = this.palette[color]; | |
130 | imageData.data[index] = t[0]; | |
131 | imageData.data[index + 1] = t[1]; | |
132 | imageData.data[index + 2] = t[2]; | |
133 | // and leave alpha (data[index + 3]) unchanged */ | |
134 | }; | |
135 | ||
136 | this.surveyPixels = function(table) { | |
137 | var w = this.canvas.width; | |
138 | var h = this.canvas.height; | |
139 | var srcImageData = this.ctx.getImageData(0, 0, w, h); | |
140 | ||
141 | for (var x = 1; x < w; x++) { | |
142 | for (var y = 1; y < h; y++) { | |
143 | var color = this.pixelAt(srcImageData, x, y); | |
144 | var left = this.pixelAt(srcImageData, x-1, y); | |
145 | var above = this.pixelAt(srcImageData, x, y-1); | |
146 | var leftAbove = this.pixelAt(srcImageData, x-1, y-1); | |
147 | var key = left + ',' + leftAbove + ',' + above; | |
148 | if (table[color][key] === undefined) { | |
149 | table[color][key] = 1; | |
150 | } else { | |
151 | table[color][key]++; | |
152 | } | |
153 | } | |
154 | } | |
155 | }; | |
156 | ||
157 | this.generateChar = function(table) { | |
158 | if (this.generated >= 130) return; | |
159 | ||
160 | var canvas = yoob.makeCanvas(this.bucket); | |
161 | var ctx = canvas.getContext('2d'); | |
162 | canvas.width = 9; | |
163 | canvas.height = 9; | |
164 | ||
165 | canvas.style.margin = "10px"; | |
166 | ||
167 | var w = canvas.width; | |
168 | var h = canvas.height; | |
169 | ||
170 | ctx.fillStyle = 'white'; | |
171 | ctx.fillRect(0, 0, w, h); | |
172 | ||
173 | for (var x = 1; x < w; x++) { | |
174 | for (var y = 1; y < h; y++) { | |
175 | var srcImageData = ctx.getImageData(0, 0, w, h); | |
176 | ||
177 | var left = this.pixelAt(srcImageData, x-1, y); | |
178 | var above = this.pixelAt(srcImageData, x, y-1); | |
179 | var leftAbove = this.pixelAt(srcImageData, x-1, y-1); | |
180 | var key = left + ',' + leftAbove + ',' + above; | |
181 | ||
182 | var c0 = table['0'][key]; | |
183 | var c1 = table['1'][key]; | |
184 | var tot = c0 + c1; | |
185 | ||
186 | var pick = Math.floor(Math.random() * tot) + 1; | |
187 | var color = pick <= c0 ? 0 : 1; | |
188 | ||
189 | this.putPixel(srcImageData, x, y, color); | |
190 | ctx.putImageData(srcImageData, 0, 0); | |
191 | } | |
192 | } | |
193 | ||
194 | this.generated++; | |
195 | }; | |
196 | ||
197 | }; |
18 | 18 | <div id="container"></div> |
19 | 19 | |
20 | 20 | </body> |
21 | <script src="multicolouralism.js"></script> | |
21 | <script src="index.js"></script> | |
22 | 22 | <script> |
23 | 23 | launch('../common-yoob.js-0.11/', 'container'); |
24 | 24 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | "splash-screen.js" | |
5 | ]; | |
6 | var loaded = 0; | |
7 | for (var i = 0; i < deps.length; i++) { | |
8 | var elem = document.createElement('script'); | |
9 | elem.src = prefix + deps[i]; | |
10 | elem.onload = function() { | |
11 | if (++loaded == deps.length) { | |
12 | var container = document.getElementById(containerId); | |
13 | ||
14 | var t = new Multicolouralism(); | |
15 | ||
16 | var canvas = yoob.makeCanvas(container, 400, 400); | |
17 | canvas.id = 'canvas'; | |
18 | ||
19 | container.appendChild(document.createElement('br')); | |
20 | container.appendChild(document.createTextNode("Field strength:")); | |
21 | var slider = yoob.makeSlider(container, 0, 50, 5); | |
22 | slider.oninput = function(e) { | |
23 | t.setFieldStrength(slider.value); | |
24 | }; | |
25 | container.appendChild(document.createElement('br')); | |
26 | var asCircles = yoob.makeCheckbox( | |
27 | container, false, "circles", t.setAsCircles | |
28 | ); | |
29 | ||
30 | yoob.showSplashScreen({ | |
31 | elementId: 'canvas', | |
32 | innerHTML: "<p>Warning: this application displays rapidly changing colours " + | |
33 | "and/or shapes and may be unsuitable for those sensitive to light or " + | |
34 | "prone to epileptic seizures.</p>", | |
35 | buttonText: "I understand -- Proceed", | |
36 | onproceed: function() { | |
37 | t.init(canvas, 25, 25); | |
38 | }, | |
39 | background: '#a0a0d0' | |
40 | }); | |
41 | } | |
42 | }; | |
43 | document.body.appendChild(elem); | |
44 | } | |
45 | } | |
46 | ||
47 | Multicolouralism = function() { | |
48 | var canvas; | |
49 | var ctx; | |
50 | var request; | |
51 | var rows; | |
52 | var cols; | |
53 | var radius; | |
54 | var fieldStrength = 5; | |
55 | var asCircles = false; | |
56 | ||
57 | var dist = function(x1, y1, x2, y2) { | |
58 | var dx = x2 - x1; | |
59 | var dy = y2 - y1; | |
60 | return Math.sqrt(dx*dx + dy*dy); | |
61 | }; | |
62 | ||
63 | this.setAsCircles = function(b) { | |
64 | asCircles = b; | |
65 | }; | |
66 | ||
67 | this.setFieldStrength = function(s) { | |
68 | fieldStrength = s; | |
69 | }; | |
70 | ||
71 | this.getFillStyle = function(x, y) { | |
72 | var diag = dist(0, 0, cols-1, rows-1); | |
73 | var d1 = diag - dist(x, y, 0, 0); | |
74 | var d2 = diag - dist(x, y, cols-1, 0); | |
75 | var d3 = diag - dist(x, y, cols-1, rows-1); | |
76 | var d4 = diag - dist(x, y, 0, rows-1); | |
77 | ||
78 | d1 = Math.pow(d1, fieldStrength); | |
79 | d2 = Math.pow(d2, fieldStrength); | |
80 | d3 = Math.pow(d3, fieldStrength); | |
81 | d4 = Math.pow(d4, fieldStrength); | |
82 | ||
83 | // pick a rational number between 0 and sum of all distances | |
84 | var r = Math.random() * (d1+d2+d3+d4); | |
85 | ||
86 | if (r < d1) return "#00ffff"; | |
87 | if (r < d1 + d2) return "#ff00ff"; | |
88 | if (r < d1 + d2 + d3) return "#ffff00"; | |
89 | return "#ffffff"; | |
90 | }; | |
91 | ||
92 | this.draw = function() { | |
93 | ctx.fillStyle = "#000000"; | |
94 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
95 | ||
96 | for (var y = 0; y < rows; y++) { | |
97 | for (var x = 0; x < cols; x++) { | |
98 | if (asCircles) { | |
99 | var cx = x * (radius * 2) + radius; | |
100 | var cy = y * (radius * 2) + radius; | |
101 | ctx.beginPath(); | |
102 | ctx.fillStyle = this.getFillStyle(x, y); | |
103 | ctx.arc(cx, cy, radius, 0, 2 * Math.PI, false); | |
104 | ctx.closePath(); | |
105 | ctx.fill(); | |
106 | } else { | |
107 | ctx.fillStyle = this.getFillStyle(x, y); | |
108 | var cx = x * (radius * 2); | |
109 | var cy = y * (radius * 2); | |
110 | ctx.fillRect(cx, cy, radius * 2, radius * 2); | |
111 | } | |
112 | } | |
113 | } | |
114 | }; | |
115 | ||
116 | this.init = function(c, gRows, gCols) { | |
117 | canvas = c; | |
118 | ctx = canvas.getContext('2d'); | |
119 | rows = gRows; | |
120 | cols = gCols; | |
121 | var $this = this; | |
122 | ||
123 | radius = (canvas.height / rows) / 2; | |
124 | ||
125 | // we request each successive animation frame AS FAST AS POSSIBLE | |
126 | var animFrame = function(time) { | |
127 | $this.draw(); | |
128 | request = requestAnimationFrame(animFrame); | |
129 | }; | |
130 | request = requestAnimationFrame(animFrame); | |
131 | }; | |
132 | } |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | "splash-screen.js" | |
5 | ]; | |
6 | var loaded = 0; | |
7 | for (var i = 0; i < deps.length; i++) { | |
8 | var elem = document.createElement('script'); | |
9 | elem.src = prefix + deps[i]; | |
10 | elem.onload = function() { | |
11 | if (++loaded == deps.length) { | |
12 | var container = document.getElementById(containerId); | |
13 | ||
14 | var t = new Multicolouralism(); | |
15 | ||
16 | var canvas = yoob.makeCanvas(container, 400, 400); | |
17 | canvas.id = 'canvas'; | |
18 | ||
19 | container.appendChild(document.createElement('br')); | |
20 | container.appendChild(document.createTextNode("Field strength:")); | |
21 | var slider = yoob.makeSlider(container, 0, 50, 5); | |
22 | slider.oninput = function(e) { | |
23 | t.setFieldStrength(slider.value); | |
24 | }; | |
25 | container.appendChild(document.createElement('br')); | |
26 | var asCircles = yoob.makeCheckbox( | |
27 | container, false, "circles", t.setAsCircles | |
28 | ); | |
29 | ||
30 | yoob.showSplashScreen({ | |
31 | elementId: 'canvas', | |
32 | innerHTML: "<p>Warning: this application displays rapidly changing colours " + | |
33 | "and/or shapes and may be unsuitable for those sensitive to light or " + | |
34 | "prone to epileptic seizures.</p>", | |
35 | buttonText: "I understand -- Proceed", | |
36 | onproceed: function() { | |
37 | t.init(canvas, 25, 25); | |
38 | }, | |
39 | background: '#a0a0d0' | |
40 | }); | |
41 | } | |
42 | }; | |
43 | document.body.appendChild(elem); | |
44 | } | |
45 | } | |
46 | ||
47 | Multicolouralism = function() { | |
48 | var canvas; | |
49 | var ctx; | |
50 | var request; | |
51 | var rows; | |
52 | var cols; | |
53 | var radius; | |
54 | var fieldStrength = 5; | |
55 | var asCircles = false; | |
56 | ||
57 | var dist = function(x1, y1, x2, y2) { | |
58 | var dx = x2 - x1; | |
59 | var dy = y2 - y1; | |
60 | return Math.sqrt(dx*dx + dy*dy); | |
61 | }; | |
62 | ||
63 | this.setAsCircles = function(b) { | |
64 | asCircles = b; | |
65 | }; | |
66 | ||
67 | this.setFieldStrength = function(s) { | |
68 | fieldStrength = s; | |
69 | }; | |
70 | ||
71 | this.getFillStyle = function(x, y) { | |
72 | var diag = dist(0, 0, cols-1, rows-1); | |
73 | var d1 = diag - dist(x, y, 0, 0); | |
74 | var d2 = diag - dist(x, y, cols-1, 0); | |
75 | var d3 = diag - dist(x, y, cols-1, rows-1); | |
76 | var d4 = diag - dist(x, y, 0, rows-1); | |
77 | ||
78 | d1 = Math.pow(d1, fieldStrength); | |
79 | d2 = Math.pow(d2, fieldStrength); | |
80 | d3 = Math.pow(d3, fieldStrength); | |
81 | d4 = Math.pow(d4, fieldStrength); | |
82 | ||
83 | // pick a rational number between 0 and sum of all distances | |
84 | var r = Math.random() * (d1+d2+d3+d4); | |
85 | ||
86 | if (r < d1) return "#00ffff"; | |
87 | if (r < d1 + d2) return "#ff00ff"; | |
88 | if (r < d1 + d2 + d3) return "#ffff00"; | |
89 | return "#ffffff"; | |
90 | }; | |
91 | ||
92 | this.draw = function() { | |
93 | ctx.fillStyle = "#000000"; | |
94 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
95 | ||
96 | for (var y = 0; y < rows; y++) { | |
97 | for (var x = 0; x < cols; x++) { | |
98 | if (asCircles) { | |
99 | var cx = x * (radius * 2) + radius; | |
100 | var cy = y * (radius * 2) + radius; | |
101 | ctx.beginPath(); | |
102 | ctx.fillStyle = this.getFillStyle(x, y); | |
103 | ctx.arc(cx, cy, radius, 0, 2 * Math.PI, false); | |
104 | ctx.closePath(); | |
105 | ctx.fill(); | |
106 | } else { | |
107 | ctx.fillStyle = this.getFillStyle(x, y); | |
108 | var cx = x * (radius * 2); | |
109 | var cy = y * (radius * 2); | |
110 | ctx.fillRect(cx, cy, radius * 2, radius * 2); | |
111 | } | |
112 | } | |
113 | } | |
114 | }; | |
115 | ||
116 | this.init = function(c, gRows, gCols) { | |
117 | canvas = c; | |
118 | ctx = canvas.getContext('2d'); | |
119 | rows = gRows; | |
120 | cols = gCols; | |
121 | var $this = this; | |
122 | ||
123 | radius = (canvas.height / rows) / 2; | |
124 | ||
125 | // we request each successive animation frame AS FAST AS POSSIBLE | |
126 | var animFrame = function(time) { | |
127 | $this.draw(); | |
128 | request = requestAnimationFrame(animFrame); | |
129 | }; | |
130 | request = requestAnimationFrame(animFrame); | |
131 | }; | |
132 | } |
13 | 13 | <div id="container"></div> |
14 | 14 | |
15 | 15 | </body> |
16 | <script src="noise-to-signal-1.js"></script> | |
16 | <script src="index.js"></script> | |
17 | 17 | <script> |
18 | 18 | launch('../common-yoob.js-0.11/', 'container'); |
19 | 19 | </script> |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId, config) { | |
3 | var config = config || {}; | |
4 | var deps = [ | |
5 | "element-factory.js", | |
6 | "animation.js" | |
7 | ]; | |
8 | var loaded = 0; | |
9 | for (var i = 0; i < deps.length; i++) { | |
10 | var elem = document.createElement('script'); | |
11 | elem.src = prefix + deps[i]; | |
12 | elem.onload = function() { | |
13 | if (++loaded < deps.length) return; | |
14 | var container = document.getElementById(containerId); | |
15 | ||
16 | var canvas = yoob.makeCanvas(container, 600, 200); | |
17 | ||
18 | var gewgaw = (new NoiseToSignal1()).init({ canvas: canvas }); | |
19 | }; | |
20 | document.body.appendChild(elem); | |
21 | } | |
22 | } | |
23 | ||
24 | var NoiseToSignal1 = function() { | |
25 | this.init = function(cfg) { | |
26 | this.canvas = cfg.canvas; | |
27 | this.ctx = this.canvas.getContext('2d'); | |
28 | this.counter = 0.0; | |
29 | ||
30 | this.zn = 1; | |
31 | var source = document.createElement('canvas'); | |
32 | source.width = 200 / this.zn; | |
33 | source.height = 200 / this.zn; | |
34 | this.source = source; | |
35 | this.parts = [ | |
36 | document.createElement('canvas'), | |
37 | document.createElement('canvas') | |
38 | ]; | |
39 | this.drawInitial(source); | |
40 | this.split(source, this.parts); | |
41 | ||
42 | this.animation = (new yoob.Animation()).init({'object': this}); | |
43 | this.animation.start(); | |
44 | }; | |
45 | ||
46 | this.draw = function() { | |
47 | var canvas = this.canvas; | |
48 | var ctx = this.ctx; | |
49 | var scale; | |
50 | ||
51 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
52 | ||
53 | var spd = 100; | |
54 | scale = Math.sin((this.counter / spd) - Math.PI); | |
55 | if (Math.abs(scale) >= 0.00001) { | |
56 | ctx.save(); | |
57 | ctx.translate(canvas.width * (1/3), 0); | |
58 | ctx.scale(scale, 1); | |
59 | ctx.drawImage( | |
60 | this.parts[0], 0, 0, | |
61 | this.parts[0].width * this.zn, this.parts[0].height * this.zn | |
62 | ); | |
63 | ctx.restore(); | |
64 | } | |
65 | ||
66 | scale = Math.sin(this.counter / spd); | |
67 | if (Math.abs(scale) > 0.00001) { | |
68 | ctx.save(); | |
69 | ctx.translate(canvas.width * (2/3), 0); | |
70 | ctx.scale(scale, 1); | |
71 | ctx.drawImage( | |
72 | this.parts[1], 0, 0, | |
73 | this.parts[1].width * this.zn, this.parts[1].height * this.zn | |
74 | ); | |
75 | ctx.restore(); | |
76 | } | |
77 | }; | |
78 | ||
79 | this.update = function() { | |
80 | this.counter += 1; | |
81 | }; | |
82 | ||
83 | this.drawInitial = function(canvas) { | |
84 | var ctx = canvas.getContext('2d'); | |
85 | ||
86 | ctx.fillStyle = "black"; | |
87 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
88 | ||
89 | ctx.beginPath(); | |
90 | ctx.strokeStyle = "white"; | |
91 | ctx.lineWidth = 0.5; | |
92 | ctx.arc(canvas.width/2, canvas.height/2, (canvas.height/2) * 0.8, 0, 2 * Math.PI, false); | |
93 | ctx.stroke(); | |
94 | }; | |
95 | ||
96 | this.split = function(source, dests) { | |
97 | var srcCtx = source.getContext('2d'); | |
98 | var w = source.width; | |
99 | var h = source.height; | |
100 | var srcImageData = srcCtx.getImageData(0, 0, w, h); | |
101 | ||
102 | var destCtxs = []; | |
103 | var destImageDatas = []; | |
104 | for (var i = 0; i < dests.length; i++) { | |
105 | dests[i].width = w; | |
106 | dests[i].height = h; | |
107 | var destCtx = dests[i].getContext('2d'); | |
108 | destCtx.clearRect(0, 0, w, h); | |
109 | destCtxs.push(destCtx); | |
110 | destImageDatas.push(destCtx.getImageData(0, 0, w, h)); | |
111 | } | |
112 | ||
113 | var destfuncs = [ | |
114 | function(x, y) { return (y * w + x); }, | |
115 | function(x, y) { return (y * w + ((w-1) - x)); } | |
116 | ]; | |
117 | ||
118 | for (var x = 0; x < w; x++) { | |
119 | for (var y = 0; y < h; y++) { | |
120 | var destNum = Math.trunc(Math.random() * dests.length); | |
121 | var index = (y * w + x) * 4; | |
122 | var destIndex = destfuncs[destNum](x, y) * 4; | |
123 | ||
124 | // interesting glitch variation: | |
125 | // try using destIndex as the SOURCE index... | |
126 | ||
127 | destImageDatas[destNum].data[destIndex] = srcImageData.data[index]; | |
128 | destImageDatas[destNum].data[destIndex + 1] = srcImageData.data[index + 1]; | |
129 | destImageDatas[destNum].data[destIndex + 2] = srcImageData.data[index + 2]; | |
130 | destImageDatas[destNum].data[destIndex + 3] = srcImageData.data[index + 3]; | |
131 | } | |
132 | } | |
133 | ||
134 | for (var i = 0; i < dests.length; i++) { | |
135 | destCtxs[i].putImageData(destImageDatas[i], 0, 0); | |
136 | } | |
137 | }; | |
138 | }; |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId, config) { | |
3 | var config = config || {}; | |
4 | var deps = [ | |
5 | "element-factory.js", | |
6 | "animation.js" | |
7 | ]; | |
8 | var loaded = 0; | |
9 | for (var i = 0; i < deps.length; i++) { | |
10 | var elem = document.createElement('script'); | |
11 | elem.src = prefix + deps[i]; | |
12 | elem.onload = function() { | |
13 | if (++loaded < deps.length) return; | |
14 | var container = document.getElementById(containerId); | |
15 | ||
16 | var canvas = yoob.makeCanvas(container, 600, 200); | |
17 | ||
18 | var gewgaw = (new NoiseToSignal1()).init({ canvas: canvas }); | |
19 | }; | |
20 | document.body.appendChild(elem); | |
21 | } | |
22 | } | |
23 | ||
24 | var NoiseToSignal1 = function() { | |
25 | this.init = function(cfg) { | |
26 | this.canvas = cfg.canvas; | |
27 | this.ctx = this.canvas.getContext('2d'); | |
28 | this.counter = 0.0; | |
29 | ||
30 | this.zn = 1; | |
31 | var source = document.createElement('canvas'); | |
32 | source.width = 200 / this.zn; | |
33 | source.height = 200 / this.zn; | |
34 | this.source = source; | |
35 | this.parts = [ | |
36 | document.createElement('canvas'), | |
37 | document.createElement('canvas') | |
38 | ]; | |
39 | this.drawInitial(source); | |
40 | this.split(source, this.parts); | |
41 | ||
42 | this.animation = (new yoob.Animation()).init({'object': this}); | |
43 | this.animation.start(); | |
44 | }; | |
45 | ||
46 | this.draw = function() { | |
47 | var canvas = this.canvas; | |
48 | var ctx = this.ctx; | |
49 | var scale; | |
50 | ||
51 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
52 | ||
53 | var spd = 100; | |
54 | scale = Math.sin((this.counter / spd) - Math.PI); | |
55 | if (Math.abs(scale) >= 0.00001) { | |
56 | ctx.save(); | |
57 | ctx.translate(canvas.width * (1/3), 0); | |
58 | ctx.scale(scale, 1); | |
59 | ctx.drawImage( | |
60 | this.parts[0], 0, 0, | |
61 | this.parts[0].width * this.zn, this.parts[0].height * this.zn | |
62 | ); | |
63 | ctx.restore(); | |
64 | } | |
65 | ||
66 | scale = Math.sin(this.counter / spd); | |
67 | if (Math.abs(scale) > 0.00001) { | |
68 | ctx.save(); | |
69 | ctx.translate(canvas.width * (2/3), 0); | |
70 | ctx.scale(scale, 1); | |
71 | ctx.drawImage( | |
72 | this.parts[1], 0, 0, | |
73 | this.parts[1].width * this.zn, this.parts[1].height * this.zn | |
74 | ); | |
75 | ctx.restore(); | |
76 | } | |
77 | }; | |
78 | ||
79 | this.update = function() { | |
80 | this.counter += 1; | |
81 | }; | |
82 | ||
83 | this.drawInitial = function(canvas) { | |
84 | var ctx = canvas.getContext('2d'); | |
85 | ||
86 | ctx.fillStyle = "black"; | |
87 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
88 | ||
89 | ctx.beginPath(); | |
90 | ctx.strokeStyle = "white"; | |
91 | ctx.lineWidth = 0.5; | |
92 | ctx.arc(canvas.width/2, canvas.height/2, (canvas.height/2) * 0.8, 0, 2 * Math.PI, false); | |
93 | ctx.stroke(); | |
94 | }; | |
95 | ||
96 | this.split = function(source, dests) { | |
97 | var srcCtx = source.getContext('2d'); | |
98 | var w = source.width; | |
99 | var h = source.height; | |
100 | var srcImageData = srcCtx.getImageData(0, 0, w, h); | |
101 | ||
102 | var destCtxs = []; | |
103 | var destImageDatas = []; | |
104 | for (var i = 0; i < dests.length; i++) { | |
105 | dests[i].width = w; | |
106 | dests[i].height = h; | |
107 | var destCtx = dests[i].getContext('2d'); | |
108 | destCtx.clearRect(0, 0, w, h); | |
109 | destCtxs.push(destCtx); | |
110 | destImageDatas.push(destCtx.getImageData(0, 0, w, h)); | |
111 | } | |
112 | ||
113 | var destfuncs = [ | |
114 | function(x, y) { return (y * w + x); }, | |
115 | function(x, y) { return (y * w + ((w-1) - x)); } | |
116 | ]; | |
117 | ||
118 | for (var x = 0; x < w; x++) { | |
119 | for (var y = 0; y < h; y++) { | |
120 | var destNum = Math.trunc(Math.random() * dests.length); | |
121 | var index = (y * w + x) * 4; | |
122 | var destIndex = destfuncs[destNum](x, y) * 4; | |
123 | ||
124 | // interesting glitch variation: | |
125 | // try using destIndex as the SOURCE index... | |
126 | ||
127 | destImageDatas[destNum].data[destIndex] = srcImageData.data[index]; | |
128 | destImageDatas[destNum].data[destIndex + 1] = srcImageData.data[index + 1]; | |
129 | destImageDatas[destNum].data[destIndex + 2] = srcImageData.data[index + 2]; | |
130 | destImageDatas[destNum].data[destIndex + 3] = srcImageData.data[index + 3]; | |
131 | } | |
132 | } | |
133 | ||
134 | for (var i = 0; i < dests.length; i++) { | |
135 | destCtxs[i].putImageData(destImageDatas[i], 0, 0); | |
136 | } | |
137 | }; | |
138 | }; |
18 | 18 | <div id="container"></div> |
19 | 19 | |
20 | 20 | </body> |
21 | <script src="prairie.js"></script> | |
21 | <script src="index.js"></script> | |
22 | 22 | <script> |
23 | 23 | launch('../common-yoob.js-0.11/', 'container', { |
24 | 24 | 'imgURL': 'Elevator_1_(PSF).png' |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "animation.js", | |
5 | ]; | |
6 | var loaded = 0; | |
7 | for (var i = 0; i < deps.length; i++) { | |
8 | var elem = document.createElement('script'); | |
9 | elem.src = prefix + deps[i]; | |
10 | elem.onload = function() { | |
11 | if (++loaded == deps.length) { | |
12 | var container = document.getElementById(containerId); | |
13 | var t = new Prairie(); | |
14 | config.canvas = ( | |
15 | config.canvas || yoob.makeCanvas(container, 640, 390) | |
16 | ); | |
17 | t.init(config); | |
18 | } | |
19 | }; | |
20 | document.body.appendChild(elem); | |
21 | } | |
22 | } | |
23 | ||
24 | Prairie = function() { | |
25 | var canvas; | |
26 | var ctx; | |
27 | var animCfg = {}; | |
28 | ||
29 | var img = new Image(); | |
30 | var shapes = new Array(); | |
31 | var NUM_SHAPES = 100; | |
32 | ||
33 | var new_shape = function(i) { | |
34 | var size = Math.floor(Math.random() * 80) + 20; | |
35 | shapes[i].w = size; | |
36 | shapes[i].x = 0 - size; | |
37 | shapes[i].y = Math.floor(Math.random() * (canvas.height - size)); | |
38 | shapes[i].v = Math.random() * 8 + 1; | |
39 | shapes[i].alpha = Math.random() * 0.66; | |
40 | }; | |
41 | ||
42 | this.draw = function(timeElapsed) { | |
43 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
44 | ctx.drawImage(img, 0, 0); | |
45 | ||
46 | for (var i = 0; i < NUM_SHAPES; i++) { | |
47 | ctx.beginPath(); | |
48 | ctx.fillStyle="rgba(255, 255, 0, " + shapes[i].alpha + ")"; | |
49 | ctx.moveTo(shapes[i].x, shapes[i].y); | |
50 | ctx.lineTo(shapes[i].x + shapes[i].w, shapes[i].y + shapes[i].w / 2); | |
51 | ctx.lineTo(shapes[i].x, shapes[i].y + shapes[i].w); | |
52 | ctx.closePath(); | |
53 | ctx.fill(); | |
54 | shapes[i].x += shapes[i].v * (timeElapsed / (1000.0 / 60.0)); | |
55 | if (shapes[i].x > canvas.width) { | |
56 | new_shape(i); | |
57 | } | |
58 | } | |
59 | }; | |
60 | ||
61 | this.init = function(config) { | |
62 | canvas = config.canvas; | |
63 | ctx = canvas.getContext('2d'); | |
64 | for (var i = 0; i < NUM_SHAPES; i++) { | |
65 | shapes[i] = {}; | |
66 | new_shape(i); | |
67 | } | |
68 | this.animation = (new yoob.Animation()).init({ | |
69 | object: this, | |
70 | mode: 'proportional' | |
71 | }); | |
72 | var $this = this; | |
73 | img.onload = function() { | |
74 | $this.animation.start(); | |
75 | }; | |
76 | img.src = config.imgURL; | |
77 | }; | |
78 | } |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "animation.js", | |
5 | ]; | |
6 | var loaded = 0; | |
7 | for (var i = 0; i < deps.length; i++) { | |
8 | var elem = document.createElement('script'); | |
9 | elem.src = prefix + deps[i]; | |
10 | elem.onload = function() { | |
11 | if (++loaded == deps.length) { | |
12 | var container = document.getElementById(containerId); | |
13 | var t = new Prairie(); | |
14 | config.canvas = ( | |
15 | config.canvas || yoob.makeCanvas(container, 640, 390) | |
16 | ); | |
17 | t.init(config); | |
18 | } | |
19 | }; | |
20 | document.body.appendChild(elem); | |
21 | } | |
22 | } | |
23 | ||
24 | Prairie = function() { | |
25 | var canvas; | |
26 | var ctx; | |
27 | var animCfg = {}; | |
28 | ||
29 | var img = new Image(); | |
30 | var shapes = new Array(); | |
31 | var NUM_SHAPES = 100; | |
32 | ||
33 | var new_shape = function(i) { | |
34 | var size = Math.floor(Math.random() * 80) + 20; | |
35 | shapes[i].w = size; | |
36 | shapes[i].x = 0 - size; | |
37 | shapes[i].y = Math.floor(Math.random() * (canvas.height - size)); | |
38 | shapes[i].v = Math.random() * 8 + 1; | |
39 | shapes[i].alpha = Math.random() * 0.66; | |
40 | }; | |
41 | ||
42 | this.draw = function(timeElapsed) { | |
43 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
44 | ctx.drawImage(img, 0, 0); | |
45 | ||
46 | for (var i = 0; i < NUM_SHAPES; i++) { | |
47 | ctx.beginPath(); | |
48 | ctx.fillStyle="rgba(255, 255, 0, " + shapes[i].alpha + ")"; | |
49 | ctx.moveTo(shapes[i].x, shapes[i].y); | |
50 | ctx.lineTo(shapes[i].x + shapes[i].w, shapes[i].y + shapes[i].w / 2); | |
51 | ctx.lineTo(shapes[i].x, shapes[i].y + shapes[i].w); | |
52 | ctx.closePath(); | |
53 | ctx.fill(); | |
54 | shapes[i].x += shapes[i].v * (timeElapsed / (1000.0 / 60.0)); | |
55 | if (shapes[i].x > canvas.width) { | |
56 | new_shape(i); | |
57 | } | |
58 | } | |
59 | }; | |
60 | ||
61 | this.init = function(config) { | |
62 | canvas = config.canvas; | |
63 | ctx = canvas.getContext('2d'); | |
64 | for (var i = 0; i < NUM_SHAPES; i++) { | |
65 | shapes[i] = {}; | |
66 | new_shape(i); | |
67 | } | |
68 | this.animation = (new yoob.Animation()).init({ | |
69 | object: this, | |
70 | mode: 'proportional' | |
71 | }); | |
72 | var $this = this; | |
73 | img.onload = function() { | |
74 | $this.animation.start(); | |
75 | }; | |
76 | img.src = config.imgURL; | |
77 | }; | |
78 | } |
18 | 18 | <div id="container"></div> |
19 | 19 | |
20 | 20 | </body> |
21 | <script src="progression.js"></script> | |
21 | <script src="index.js"></script> | |
22 | 22 | <script> |
23 | 23 | launch('../common-yoob.js-0.11/', 'container'); |
24 | 24 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var t = new Progression(); | |
13 | var canvas = yoob.makeCanvas(container, 800, 200); | |
14 | var counterElem = yoob.makeParagraph(container); | |
15 | t.init(canvas, counterElem); | |
16 | } | |
17 | }; | |
18 | document.body.appendChild(elem); | |
19 | } | |
20 | } | |
21 | ||
22 | function Progression() { | |
23 | var counter; | |
24 | var canvas; | |
25 | var ctx; | |
26 | ||
27 | this.draw = function(timeElapsed) { | |
28 | if (this.counter_elem) { | |
29 | this.counter_elem.innerHTML = Math.floor(counter); | |
30 | } | |
31 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
32 | ctx.beginPath(); | |
33 | ctx.lineWidth = 1; | |
34 | ctx.strokeStyle = "black"; | |
35 | ctx.moveTo(0, 0); | |
36 | var y = 200; | |
37 | var w = (canvas.width / counter); | |
38 | for (var i = 1; i <= counter; i++) { | |
39 | ctx.lineTo(w * i, y); | |
40 | y = (y == 200 ? 0 : 200); | |
41 | } | |
42 | ctx.lineTo(canvas.width, 0); | |
43 | ctx.stroke(); | |
44 | counter += timeElapsed / 60.0; | |
45 | }; | |
46 | ||
47 | this.init = function(c, counter_elem) { | |
48 | canvas = c; | |
49 | this.counter_elem = counter_elem; | |
50 | ctx = canvas.getContext('2d'); | |
51 | counter = 1; | |
52 | this.animation = (new yoob.Animation()).init({ | |
53 | object: this, | |
54 | mode: 'proportional' | |
55 | }); | |
56 | this.animation.start(); | |
57 | }; | |
58 | } |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js", | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var t = new Progression(); | |
13 | var canvas = yoob.makeCanvas(container, 800, 200); | |
14 | var counterElem = yoob.makeParagraph(container); | |
15 | t.init(canvas, counterElem); | |
16 | } | |
17 | }; | |
18 | document.body.appendChild(elem); | |
19 | } | |
20 | } | |
21 | ||
22 | function Progression() { | |
23 | var counter; | |
24 | var canvas; | |
25 | var ctx; | |
26 | ||
27 | this.draw = function(timeElapsed) { | |
28 | if (this.counter_elem) { | |
29 | this.counter_elem.innerHTML = Math.floor(counter); | |
30 | } | |
31 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
32 | ctx.beginPath(); | |
33 | ctx.lineWidth = 1; | |
34 | ctx.strokeStyle = "black"; | |
35 | ctx.moveTo(0, 0); | |
36 | var y = 200; | |
37 | var w = (canvas.width / counter); | |
38 | for (var i = 1; i <= counter; i++) { | |
39 | ctx.lineTo(w * i, y); | |
40 | y = (y == 200 ? 0 : 200); | |
41 | } | |
42 | ctx.lineTo(canvas.width, 0); | |
43 | ctx.stroke(); | |
44 | counter += timeElapsed / 60.0; | |
45 | }; | |
46 | ||
47 | this.init = function(c, counter_elem) { | |
48 | canvas = c; | |
49 | this.counter_elem = counter_elem; | |
50 | ctx = canvas.getContext('2d'); | |
51 | counter = 1; | |
52 | this.animation = (new yoob.Animation()).init({ | |
53 | object: this, | |
54 | mode: 'proportional' | |
55 | }); | |
56 | this.animation.start(); | |
57 | }; | |
58 | } |
12 | 12 | <div id="container"></div> |
13 | 13 | |
14 | 14 | </body> |
15 | <script src="radialjective.js"></script> | |
15 | <script src="index.js"></script> | |
16 | 16 | <script> |
17 | 17 | launch('../common-yoob.js-0.11/', 'container'); |
18 | 18 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var canvas = yoob.makeCanvas(container, 500, 500); | |
13 | (new Radialjective()).init(canvas); | |
14 | } | |
15 | }; | |
16 | document.body.appendChild(elem); | |
17 | } | |
18 | } | |
19 | ||
20 | var twopi = Math.PI * 2; | |
21 | var degrees = twopi / 360; | |
22 | ||
23 | Radialjective = function() { | |
24 | var ctx = undefined; | |
25 | var canvas = undefined; | |
26 | var info; | |
27 | ||
28 | var t = 0; | |
29 | ||
30 | this.init = function(c) { | |
31 | canvas = c; | |
32 | ctx = canvas.getContext("2d"); | |
33 | ||
34 | this.animation = (new yoob.Animation).init({ | |
35 | object: this | |
36 | }); | |
37 | this.animation.start(); | |
38 | }; | |
39 | ||
40 | this.update = function() { | |
41 | t += 1; | |
42 | }; | |
43 | ||
44 | this.draw = function() { | |
45 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
46 | var cx = canvas.width / 2; | |
47 | var cy = canvas.height / 2; | |
48 | ||
49 | var f = function(a, t) { | |
50 | return Math.sin(Math.sin(a / 20) + t / 20) * 20 * Math.sin(a / 10) * Math.cos(t / 100); | |
51 | }; | |
52 | ||
53 | // LINE 1: theta is a function of r. | |
54 | ctx.beginPath(); | |
55 | for (var r = 0; r <= cx; r++) { | |
56 | var theta = f(r, t) / 8; | |
57 | var x = cx + r * Math.cos(theta); | |
58 | var y = cy + r * Math.sin(theta); | |
59 | ctx.lineTo(x, y); | |
60 | } | |
61 | ctx.lineWidth = 2; | |
62 | ctx.strokeStyle = "black"; | |
63 | ctx.stroke(); | |
64 | ||
65 | // LINE 2: r is a function of theta. | |
66 | ctx.beginPath(); | |
67 | for (var theta = 0; theta <= twopi; theta += (twopi / cx)) { | |
68 | var r = f(theta * (cx / twopi), t); | |
69 | var x = cx + r * Math.cos(theta); | |
70 | var y = cy + r * Math.sin(theta); | |
71 | ctx.lineTo(x, y); | |
72 | } | |
73 | ctx.lineWidth = 2; | |
74 | ctx.strokeStyle = "green"; | |
75 | ctx.stroke(); | |
76 | ||
77 | // LINE 2a: r is a function of theta. | |
78 | ctx.beginPath(); | |
79 | for (var theta = 0; theta <= twopi; theta += (twopi / cx)) { | |
80 | var r = f(theta * (cx / twopi), t) * 10; | |
81 | var x = cx + r * Math.cos(theta); | |
82 | var y = cy + r * Math.sin(theta); | |
83 | ctx.lineTo(x, y); | |
84 | } | |
85 | ctx.lineWidth = 2; | |
86 | ctx.strokeStyle = "#00ff30"; | |
87 | ctx.stroke(); | |
88 | ||
89 | // LINE 3: y is a function of x. | |
90 | ctx.beginPath(); | |
91 | for (var x = 0; x <= cx; x++) { | |
92 | var y = cy - f(x, t); | |
93 | ctx.lineTo(cx + x, y); | |
94 | } | |
95 | ctx.lineWidth = 2; | |
96 | ctx.strokeStyle = "blue"; | |
97 | ctx.stroke(); | |
98 | ||
99 | // LINE 4: theta is a function of r, but projected onto a cone. | |
100 | ctx.beginPath(); | |
101 | for (var r = 0; r <= cx; r++) { | |
102 | var theta = f(r, t) / 8; | |
103 | var x = cx + r * Math.cos(theta); | |
104 | var y = cy + r; | |
105 | ctx.lineTo(x, y); | |
106 | } | |
107 | ctx.lineWidth = 2; | |
108 | ctx.strokeStyle = "red"; | |
109 | ctx.stroke(); | |
110 | ||
111 | }; | |
112 | }; |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var canvas = yoob.makeCanvas(container, 500, 500); | |
13 | (new Radialjective()).init(canvas); | |
14 | } | |
15 | }; | |
16 | document.body.appendChild(elem); | |
17 | } | |
18 | } | |
19 | ||
20 | var twopi = Math.PI * 2; | |
21 | var degrees = twopi / 360; | |
22 | ||
23 | Radialjective = function() { | |
24 | var ctx = undefined; | |
25 | var canvas = undefined; | |
26 | var info; | |
27 | ||
28 | var t = 0; | |
29 | ||
30 | this.init = function(c) { | |
31 | canvas = c; | |
32 | ctx = canvas.getContext("2d"); | |
33 | ||
34 | this.animation = (new yoob.Animation).init({ | |
35 | object: this | |
36 | }); | |
37 | this.animation.start(); | |
38 | }; | |
39 | ||
40 | this.update = function() { | |
41 | t += 1; | |
42 | }; | |
43 | ||
44 | this.draw = function() { | |
45 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
46 | var cx = canvas.width / 2; | |
47 | var cy = canvas.height / 2; | |
48 | ||
49 | var f = function(a, t) { | |
50 | return Math.sin(Math.sin(a / 20) + t / 20) * 20 * Math.sin(a / 10) * Math.cos(t / 100); | |
51 | }; | |
52 | ||
53 | // LINE 1: theta is a function of r. | |
54 | ctx.beginPath(); | |
55 | for (var r = 0; r <= cx; r++) { | |
56 | var theta = f(r, t) / 8; | |
57 | var x = cx + r * Math.cos(theta); | |
58 | var y = cy + r * Math.sin(theta); | |
59 | ctx.lineTo(x, y); | |
60 | } | |
61 | ctx.lineWidth = 2; | |
62 | ctx.strokeStyle = "black"; | |
63 | ctx.stroke(); | |
64 | ||
65 | // LINE 2: r is a function of theta. | |
66 | ctx.beginPath(); | |
67 | for (var theta = 0; theta <= twopi; theta += (twopi / cx)) { | |
68 | var r = f(theta * (cx / twopi), t); | |
69 | var x = cx + r * Math.cos(theta); | |
70 | var y = cy + r * Math.sin(theta); | |
71 | ctx.lineTo(x, y); | |
72 | } | |
73 | ctx.lineWidth = 2; | |
74 | ctx.strokeStyle = "green"; | |
75 | ctx.stroke(); | |
76 | ||
77 | // LINE 2a: r is a function of theta. | |
78 | ctx.beginPath(); | |
79 | for (var theta = 0; theta <= twopi; theta += (twopi / cx)) { | |
80 | var r = f(theta * (cx / twopi), t) * 10; | |
81 | var x = cx + r * Math.cos(theta); | |
82 | var y = cy + r * Math.sin(theta); | |
83 | ctx.lineTo(x, y); | |
84 | } | |
85 | ctx.lineWidth = 2; | |
86 | ctx.strokeStyle = "#00ff30"; | |
87 | ctx.stroke(); | |
88 | ||
89 | // LINE 3: y is a function of x. | |
90 | ctx.beginPath(); | |
91 | for (var x = 0; x <= cx; x++) { | |
92 | var y = cy - f(x, t); | |
93 | ctx.lineTo(cx + x, y); | |
94 | } | |
95 | ctx.lineWidth = 2; | |
96 | ctx.strokeStyle = "blue"; | |
97 | ctx.stroke(); | |
98 | ||
99 | // LINE 4: theta is a function of r, but projected onto a cone. | |
100 | ctx.beginPath(); | |
101 | for (var r = 0; r <= cx; r++) { | |
102 | var theta = f(r, t) / 8; | |
103 | var x = cx + r * Math.cos(theta); | |
104 | var y = cy + r; | |
105 | ctx.lineTo(x, y); | |
106 | } | |
107 | ctx.lineWidth = 2; | |
108 | ctx.strokeStyle = "red"; | |
109 | ctx.stroke(); | |
110 | ||
111 | }; | |
112 | }; |
9 | 9 | <div id="container"></div> |
10 | 10 | |
11 | 11 | </body> |
12 | <script src="tentacles-undamped.js"></script> | |
12 | <script src="index.js"></script> | |
13 | 13 | <script> |
14 | 14 | launch('../common-yoob.js-0.11/', 'container'); |
15 | 15 | </script> |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId, config) { | |
3 | var config = config || {}; | |
4 | var deps = [ | |
5 | "element-factory.js", | |
6 | "animation.js" | |
7 | ]; | |
8 | var loaded = 0; | |
9 | for (var i = 0; i < deps.length; i++) { | |
10 | var elem = document.createElement('script'); | |
11 | elem.src = prefix + deps[i]; | |
12 | elem.onload = function() { | |
13 | if (++loaded < deps.length) return; | |
14 | ||
15 | var container = document.getElementById(containerId); | |
16 | var t = new Tentacles(); | |
17 | var canvas = yoob.makeCanvas(container, 500, 500); | |
18 | t.init({ | |
19 | 'canvas': canvas | |
20 | }); | |
21 | }; | |
22 | document.body.appendChild(elem); | |
23 | } | |
24 | } | |
25 | ||
26 | var TWOPI = Math.PI * 2; | |
27 | var DEGREES = TWOPI / 360; | |
28 | ||
29 | var Tentacle = function() { | |
30 | var thetas = []; | |
31 | var numSegments = 8; | |
32 | ||
33 | this.init = function(cfg) { | |
34 | this.x = cfg.x || 0; | |
35 | this.y = cfg.y || 0; | |
36 | this.r = cfg.r || 50; | |
37 | this.w = cfg.w || 24; | |
38 | this.phase = cfg.phase || Math.random() * TWOPI; | |
39 | this.segmentWidthReduction = cfg.segmentWidthReduction || 0.75; | |
40 | this.segmentLengthReduction = cfg.segmentLengthReduction || 0.85; | |
41 | this.segmentSpeedReduction = cfg.segmentSpeedReduction || 0.95; | |
42 | this.segmentRangeReduction = cfg.segmentRangeReduction || 0.95; | |
43 | this.range = cfg.range || 2; | |
44 | this.speed = cfg.speed || 50; | |
45 | this.delay = cfg.delay || Math.random() * 200; | |
46 | return this; | |
47 | }; | |
48 | ||
49 | this.draw = function(ctx, tick, theta) { | |
50 | var v = (tick - this.delay) * 5.0; | |
51 | ||
52 | var speed = this.speed; | |
53 | var range = this.range; | |
54 | for (var i = 0; i < numSegments; i++) { | |
55 | thetas[i] = (Math.sin(v / speed + this.phase) / range) - theta; | |
56 | speed *= this.segmentSpeedReduction; | |
57 | range *= this.segmentRangeReduction; | |
58 | } | |
59 | ||
60 | ctx.beginPath(); | |
61 | ctx.strokeStyle = "green"; | |
62 | ctx.lineCap = "round"; | |
63 | ctx.moveTo(this.x, this.y); | |
64 | ||
65 | var r = this.r; | |
66 | var w = this.w; | |
67 | var x = this.x; | |
68 | var y = this.y | |
69 | for (var i = 0; i < numSegments; i++) { | |
70 | x += r * Math.cos(thetas[i]); | |
71 | y += r * Math.sin(thetas[i]); | |
72 | ctx.lineTo(x, y); | |
73 | ctx.lineWidth = w; | |
74 | ctx.stroke(); | |
75 | w *= this.segmentWidthReduction; | |
76 | r *= this.segmentLengthReduction; | |
77 | } | |
78 | }; | |
79 | }; | |
80 | ||
81 | var Tentacles = function() { | |
82 | var ctx = undefined; | |
83 | var canvas = undefined; | |
84 | ||
85 | var tick = 0; | |
86 | ||
87 | var numTentacles = 13; | |
88 | var tentacles = []; | |
89 | ||
90 | this.init = function(cfg) { | |
91 | canvas = cfg.canvas; | |
92 | ctx = canvas.getContext("2d"); | |
93 | this.animation = new yoob.Animation().init({'object': this}); | |
94 | ||
95 | for (var i = 0; i < numTentacles; i++) { | |
96 | tentacles.push(new Tentacle().init({ | |
97 | x: canvas.width / 2, | |
98 | y: canvas.height / 2 | |
99 | })); | |
100 | } | |
101 | ||
102 | this.animation.start(); | |
103 | }; | |
104 | ||
105 | this.draw = function() { | |
106 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
107 | ||
108 | for (var tentNo = 0; tentNo < tentacles.length; tentNo++) { | |
109 | var theta = (TWOPI / tentacles.length) * tentNo; | |
110 | tentacles[tentNo].draw(ctx, tick, theta); | |
111 | } | |
112 | }; | |
113 | ||
114 | this.update = function() { | |
115 | tick += 1; | |
116 | }; | |
117 | }; |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId, config) { | |
3 | var config = config || {}; | |
4 | var deps = [ | |
5 | "element-factory.js", | |
6 | "animation.js" | |
7 | ]; | |
8 | var loaded = 0; | |
9 | for (var i = 0; i < deps.length; i++) { | |
10 | var elem = document.createElement('script'); | |
11 | elem.src = prefix + deps[i]; | |
12 | elem.onload = function() { | |
13 | if (++loaded < deps.length) return; | |
14 | ||
15 | var container = document.getElementById(containerId); | |
16 | var t = new Tentacles(); | |
17 | var canvas = yoob.makeCanvas(container, 500, 500); | |
18 | t.init({ | |
19 | 'canvas': canvas | |
20 | }); | |
21 | }; | |
22 | document.body.appendChild(elem); | |
23 | } | |
24 | } | |
25 | ||
26 | var TWOPI = Math.PI * 2; | |
27 | var DEGREES = TWOPI / 360; | |
28 | ||
29 | var Tentacle = function() { | |
30 | var thetas = []; | |
31 | var numSegments = 8; | |
32 | ||
33 | this.init = function(cfg) { | |
34 | this.x = cfg.x || 0; | |
35 | this.y = cfg.y || 0; | |
36 | this.r = cfg.r || 50; | |
37 | this.w = cfg.w || 24; | |
38 | this.phase = cfg.phase || Math.random() * TWOPI; | |
39 | this.segmentWidthReduction = cfg.segmentWidthReduction || 0.75; | |
40 | this.segmentLengthReduction = cfg.segmentLengthReduction || 0.85; | |
41 | this.segmentSpeedReduction = cfg.segmentSpeedReduction || 0.95; | |
42 | this.segmentRangeReduction = cfg.segmentRangeReduction || 0.95; | |
43 | this.range = cfg.range || 2; | |
44 | this.speed = cfg.speed || 50; | |
45 | this.delay = cfg.delay || Math.random() * 200; | |
46 | return this; | |
47 | }; | |
48 | ||
49 | this.draw = function(ctx, tick, theta) { | |
50 | var v = (tick - this.delay) * 5.0; | |
51 | ||
52 | var speed = this.speed; | |
53 | var range = this.range; | |
54 | for (var i = 0; i < numSegments; i++) { | |
55 | thetas[i] = (Math.sin(v / speed + this.phase) / range) - theta; | |
56 | speed *= this.segmentSpeedReduction; | |
57 | range *= this.segmentRangeReduction; | |
58 | } | |
59 | ||
60 | ctx.beginPath(); | |
61 | ctx.strokeStyle = "green"; | |
62 | ctx.lineCap = "round"; | |
63 | ctx.moveTo(this.x, this.y); | |
64 | ||
65 | var r = this.r; | |
66 | var w = this.w; | |
67 | var x = this.x; | |
68 | var y = this.y | |
69 | for (var i = 0; i < numSegments; i++) { | |
70 | x += r * Math.cos(thetas[i]); | |
71 | y += r * Math.sin(thetas[i]); | |
72 | ctx.lineTo(x, y); | |
73 | ctx.lineWidth = w; | |
74 | ctx.stroke(); | |
75 | w *= this.segmentWidthReduction; | |
76 | r *= this.segmentLengthReduction; | |
77 | } | |
78 | }; | |
79 | }; | |
80 | ||
81 | var Tentacles = function() { | |
82 | var ctx = undefined; | |
83 | var canvas = undefined; | |
84 | ||
85 | var tick = 0; | |
86 | ||
87 | var numTentacles = 13; | |
88 | var tentacles = []; | |
89 | ||
90 | this.init = function(cfg) { | |
91 | canvas = cfg.canvas; | |
92 | ctx = canvas.getContext("2d"); | |
93 | this.animation = new yoob.Animation().init({'object': this}); | |
94 | ||
95 | for (var i = 0; i < numTentacles; i++) { | |
96 | tentacles.push(new Tentacle().init({ | |
97 | x: canvas.width / 2, | |
98 | y: canvas.height / 2 | |
99 | })); | |
100 | } | |
101 | ||
102 | this.animation.start(); | |
103 | }; | |
104 | ||
105 | this.draw = function() { | |
106 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
107 | ||
108 | for (var tentNo = 0; tentNo < tentacles.length; tentNo++) { | |
109 | var theta = (TWOPI / tentacles.length) * tentNo; | |
110 | tentacles[tentNo].draw(ctx, tick, theta); | |
111 | } | |
112 | }; | |
113 | ||
114 | this.update = function() { | |
115 | tick += 1; | |
116 | }; | |
117 | }; |
13 | 13 | </div> |
14 | 14 | |
15 | 15 | </body> |
16 | <script src="text-uniquifier.js"></script> | |
16 | <script src="index.js"></script> | |
17 | 17 | <script> |
18 | 18 | launch('../common-yoob.js-0.11/', 'control_panel'); |
19 | 19 | </script> |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId) { | |
3 | var deps = [ | |
4 | "element-factory.js" | |
5 | ]; | |
6 | var loaded = 0; | |
7 | for (var i = 0; i < deps.length; i++) { | |
8 | var elem = document.createElement('script'); | |
9 | elem.src = prefix + deps[i]; | |
10 | elem.onload = function() { | |
11 | if (++loaded == deps.length) { | |
12 | var container = document.getElementById(containerId); | |
13 | var input = yoob.makeTextArea( | |
14 | container, 80, 10 | |
15 | ); | |
16 | yoob.makeLineBreak(container); | |
17 | var caseSensitive = yoob.makeCheckbox( | |
18 | container, true, "Case-sensitive" | |
19 | ); | |
20 | var span = document.createElement('span'); | |
21 | span.innerHTML = " "; | |
22 | container.appendChild(span); | |
23 | var puncSensitive = yoob.makeCheckbox( | |
24 | container, true, "Punctuation-sensitive" | |
25 | ); | |
26 | var preserve = yoob.makeSelect( | |
27 | container, " Preserve:", [ | |
28 | ['paragraph_breaks', "Paragraph breaks only", true], | |
29 | ['line_breaks', "All line breaks"], | |
30 | ['no_breaks', "Nothing"] | |
31 | ] | |
32 | ); | |
33 | ||
34 | var button = yoob.makeButton(container, "Uniquify"); | |
35 | ||
36 | yoob.makeLineBreak(container); | |
37 | ||
38 | var output = document.createElement('pre'); | |
39 | container.appendChild(output); | |
40 | output.style.textAlign = "left"; | |
41 | output.style.whiteSpace = "pre-wrap"; | |
42 | output.style.wordBreak = "normal"; | |
43 | ||
44 | button.style.cursor = 'pointer'; | |
45 | button.onclick = function() { | |
46 | button.style.cursor = 'wait'; | |
47 | var preserveWhat = preserve.options[preserve.selectedIndex].value; | |
48 | output.innerHTML = uniquify( | |
49 | input.value, preserveWhat, | |
50 | caseSensitive.checked, puncSensitive.checked | |
51 | ); | |
52 | button.style.cursor = 'pointer'; | |
53 | }; | |
54 | } | |
55 | }; | |
56 | document.body.appendChild(elem); | |
57 | } | |
58 | } | |
59 | ||
60 | function stripPunctuation(s) { | |
61 | var t = ''; | |
62 | for (var i = 0; i < s.length; i++) { | |
63 | var c = s.charAt(i); | |
64 | if ((c >= "0" && c <= "9") || (c >= "A" && c <= "Z") || (c >= 'a' && c <= 'z')) { | |
65 | t += c; | |
66 | } | |
67 | } | |
68 | return t; | |
69 | } | |
70 | ||
71 | function uniquify(text, preserve, caseSensitive, puncSensitive) { | |
72 | var set = {} | |
73 | var result = ''; | |
74 | ||
75 | text = text.replace('\r', '\n').replace('\t', ' '); | |
76 | ||
77 | var lines = text.split('\n'); | |
78 | ||
79 | for (var l = 0; l < lines.length; l++) { | |
80 | var words = lines[l].split(" "); | |
81 | ||
82 | var textLine = ''; | |
83 | for (var i = 0; i < words.length; i++) { | |
84 | var word = words[i]; | |
85 | if (word === '') { | |
86 | continue; | |
87 | } | |
88 | var z = word; | |
89 | if (!puncSensitive) { | |
90 | z = stripPunctuation(z); | |
91 | } | |
92 | if (!caseSensitive) { | |
93 | z = z.toUpperCase(); | |
94 | } | |
95 | if (!set[z]) { | |
96 | textLine += ' ' + word; | |
97 | } | |
98 | set[z] = true; | |
99 | } | |
100 | ||
101 | result += textLine.substring(1); | |
102 | ||
103 | if (preserve === 'line_breaks') { | |
104 | result += '\n'; | |
105 | } else if (preserve === 'paragraph_breaks') { | |
106 | if (words.length === 1 && words[0] === '') { | |
107 | result += '\n\n'; | |
108 | } else { | |
109 | result += ' '; | |
110 | } | |
111 | } else { | |
112 | result += ' '; | |
113 | } | |
114 | } | |
115 | ||
116 | return result; | |
117 | }; |
0 | "use strict"; | |
1 | ||
2 | function launch(prefix, containerId) { | |
3 | var deps = [ | |
4 | "element-factory.js" | |
5 | ]; | |
6 | var loaded = 0; | |
7 | for (var i = 0; i < deps.length; i++) { | |
8 | var elem = document.createElement('script'); | |
9 | elem.src = prefix + deps[i]; | |
10 | elem.onload = function() { | |
11 | if (++loaded == deps.length) { | |
12 | var container = document.getElementById(containerId); | |
13 | var input = yoob.makeTextArea( | |
14 | container, 80, 10 | |
15 | ); | |
16 | yoob.makeLineBreak(container); | |
17 | var caseSensitive = yoob.makeCheckbox( | |
18 | container, true, "Case-sensitive" | |
19 | ); | |
20 | var span = document.createElement('span'); | |
21 | span.innerHTML = " "; | |
22 | container.appendChild(span); | |
23 | var puncSensitive = yoob.makeCheckbox( | |
24 | container, true, "Punctuation-sensitive" | |
25 | ); | |
26 | var preserve = yoob.makeSelect( | |
27 | container, " Preserve:", [ | |
28 | ['paragraph_breaks', "Paragraph breaks only", true], | |
29 | ['line_breaks', "All line breaks"], | |
30 | ['no_breaks', "Nothing"] | |
31 | ] | |
32 | ); | |
33 | ||
34 | var button = yoob.makeButton(container, "Uniquify"); | |
35 | ||
36 | yoob.makeLineBreak(container); | |
37 | ||
38 | var output = document.createElement('pre'); | |
39 | container.appendChild(output); | |
40 | output.style.textAlign = "left"; | |
41 | output.style.whiteSpace = "pre-wrap"; | |
42 | output.style.wordBreak = "normal"; | |
43 | ||
44 | button.style.cursor = 'pointer'; | |
45 | button.onclick = function() { | |
46 | button.style.cursor = 'wait'; | |
47 | var preserveWhat = preserve.options[preserve.selectedIndex].value; | |
48 | output.innerHTML = uniquify( | |
49 | input.value, preserveWhat, | |
50 | caseSensitive.checked, puncSensitive.checked | |
51 | ); | |
52 | button.style.cursor = 'pointer'; | |
53 | }; | |
54 | } | |
55 | }; | |
56 | document.body.appendChild(elem); | |
57 | } | |
58 | } | |
59 | ||
60 | function stripPunctuation(s) { | |
61 | var t = ''; | |
62 | for (var i = 0; i < s.length; i++) { | |
63 | var c = s.charAt(i); | |
64 | if ((c >= "0" && c <= "9") || (c >= "A" && c <= "Z") || (c >= 'a' && c <= 'z')) { | |
65 | t += c; | |
66 | } | |
67 | } | |
68 | return t; | |
69 | } | |
70 | ||
71 | function uniquify(text, preserve, caseSensitive, puncSensitive) { | |
72 | var set = {} | |
73 | var result = ''; | |
74 | ||
75 | text = text.replace('\r', '\n').replace('\t', ' '); | |
76 | ||
77 | var lines = text.split('\n'); | |
78 | ||
79 | for (var l = 0; l < lines.length; l++) { | |
80 | var words = lines[l].split(" "); | |
81 | ||
82 | var textLine = ''; | |
83 | for (var i = 0; i < words.length; i++) { | |
84 | var word = words[i]; | |
85 | if (word === '') { | |
86 | continue; | |
87 | } | |
88 | var z = word; | |
89 | if (!puncSensitive) { | |
90 | z = stripPunctuation(z); | |
91 | } | |
92 | if (!caseSensitive) { | |
93 | z = z.toUpperCase(); | |
94 | } | |
95 | if (!set[z]) { | |
96 | textLine += ' ' + word; | |
97 | } | |
98 | set[z] = true; | |
99 | } | |
100 | ||
101 | result += textLine.substring(1); | |
102 | ||
103 | if (preserve === 'line_breaks') { | |
104 | result += '\n'; | |
105 | } else if (preserve === 'paragraph_breaks') { | |
106 | if (words.length === 1 && words[0] === '') { | |
107 | result += '\n\n'; | |
108 | } else { | |
109 | result += ' '; | |
110 | } | |
111 | } else { | |
112 | result += ' '; | |
113 | } | |
114 | } | |
115 | ||
116 | return result; | |
117 | }; |
19 | 19 | <div id="container"></div> |
20 | 20 | |
21 | 21 | </body> |
22 | <script src="the-frame.js"></script> | |
22 | <script src="index.js"></script> | |
23 | 23 | <script> |
24 | 24 | launch('../common-yoob.js-0.11/', 'container', { |
25 | 25 | 'imgURL': 'the-frame.png' |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "animation.js", | |
5 | "sprite-manager.js" | |
6 | ]; | |
7 | var loaded = 0; | |
8 | for (var i = 0; i < deps.length; i++) { | |
9 | var elem = document.createElement('script'); | |
10 | elem.src = prefix + deps[i]; | |
11 | elem.onload = function() { | |
12 | if (++loaded == deps.length) { | |
13 | var container = document.getElementById(containerId); | |
14 | var t = new TheFrame(); | |
15 | yoob.makeParagraph(container, | |
16 | "<small>Note 1. Green things can be dragged. " + | |
17 | "Note 2. Due to technical limitations, " + | |
18 | "things cannot be dragged off of the computer screen</small>" | |
19 | ); | |
20 | if (!config.canvas) { | |
21 | var c = yoob.makeCanvas(container, 800, 450); | |
22 | c.style.display = "block"; | |
23 | c.width = document.documentElement.clientWidth - c.offsetLeft * 2 | |
24 | //c.height = document.documentElement.clientHeight - c.offsetTop - 5; | |
25 | config.canvas = c; | |
26 | } | |
27 | var pleaseWait = yoob.makeParagraph(container, | |
28 | "Please wait, loading..." | |
29 | ); | |
30 | config.callback = function() { | |
31 | pleaseWait.style.display = "none"; | |
32 | } | |
33 | t.init(config); | |
34 | } | |
35 | }; | |
36 | document.body.appendChild(elem); | |
37 | } | |
38 | } | |
39 | ||
40 | Corner = function() { | |
41 | this.draw = function(ctx) { | |
42 | ctx.fillStyle = "green"; | |
43 | ctx.fillRect(this.getLeftX(), this.getTopY(), this.getWidth(), this.getHeight()); | |
44 | }; | |
45 | }; | |
46 | ||
47 | TheFrame = function() { | |
48 | var request; | |
49 | ||
50 | var canvas; | |
51 | var ctx; | |
52 | ||
53 | var img = new Image(); | |
54 | var fontHeight; | |
55 | ||
56 | var manager; | |
57 | ||
58 | var quote = [ | |
59 | "“The most important thing in art is The Frame.", | |
60 | "For painting: literally; for other arts: figuratively-- because,", | |
61 | "without this humble appliance, you can't know", | |
62 | "where The Art stops and The Real World begins.", | |
63 | "You have to put a 'box' around it because otherwise,", | |
64 | "what is that shit on the wall?”" | |
65 | ]; | |
66 | ||
67 | var getFontHeight = function() { | |
68 | for (var height = canvas.height / 6; ; height--) { | |
69 | ctx.font = height + "px Arial,Sans-serif"; | |
70 | var width = ctx.measureText(quote[1]).width; | |
71 | if (width < canvas.width) | |
72 | break; | |
73 | } | |
74 | fontHeight = height; | |
75 | } | |
76 | ||
77 | this.draw = function() { | |
78 | ctx.fillStyle = "white"; | |
79 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
80 | ||
81 | //ctx.drawImage(img, (canvas.width - img.width) / 2, 0); | |
82 | ctx.drawImage(img, 0, 0, canvas.width, canvas.height); | |
83 | ||
84 | /* XXX knows too much about SpriteManager! */ | |
85 | for (var i = 0; i < manager.sprites.length; i++) { | |
86 | var prev = manager.sprites[i === 0 ? manager.sprites.length - 1 : i - 1]; | |
87 | var curr = manager.sprites[i]; | |
88 | ||
89 | ctx.strokeStyle = "black"; | |
90 | ctx.lineWidth = 15; | |
91 | ctx.beginPath(); | |
92 | ctx.moveTo(prev.getX(), prev.getY()); | |
93 | ctx.lineTo(curr.getX(), curr.getY()); | |
94 | ctx.closePath(); | |
95 | ctx.stroke(); | |
96 | } | |
97 | ||
98 | manager.draw(ctx); | |
99 | ||
100 | ctx.textBaseline = "top"; | |
101 | ctx.font = fontHeight + "px Arial,Sans-serif"; | |
102 | var textTopY = (canvas.height - 6 * fontHeight) / 2; | |
103 | ctx.fillStyle = "white"; | |
104 | for (var i = 0; i <= 5; i++) { | |
105 | if (i === 5) { | |
106 | ctx.font = "bold italic " + fontHeight + "px Arial,Sans-serif"; | |
107 | } | |
108 | var width = ctx.measureText(quote[i]).width; | |
109 | var textX = (canvas.width - width) / 2; | |
110 | ||
111 | ctx.fillText(quote[i], textX, textTopY + i * (fontHeight + 4)); | |
112 | } | |
113 | }; | |
114 | ||
115 | this.update = function() { | |
116 | }; | |
117 | ||
118 | this.init = function(config) { | |
119 | Corner.prototype = new yoob.Sprite(); | |
120 | ||
121 | canvas = config.canvas; | |
122 | ctx = canvas.getContext("2d"); | |
123 | manager = (new yoob.SpriteManager()).init({ | |
124 | canvas: canvas | |
125 | }); | |
126 | var mkHandle = function(x, y) { | |
127 | var d = (new Corner()).init({ | |
128 | x: x, y: y, width: 30, height: 30, | |
129 | isDraggable: true | |
130 | }); | |
131 | manager.addSprite(d); | |
132 | }; | |
133 | var $this = this; | |
134 | img.onload = function() { | |
135 | config.callback(); | |
136 | // at this point, canvas.width is OK, so we can: | |
137 | mkHandle(45, 45); | |
138 | mkHandle(canvas.width - 45, 45); | |
139 | mkHandle(canvas.width - 45, canvas.height - 45); | |
140 | mkHandle(45, canvas.height - 45); | |
141 | getFontHeight(); | |
142 | $this.draw(); | |
143 | $this.animation = (new yoob.Animation()).init({ | |
144 | object: $this | |
145 | }); | |
146 | $this.animation.start(); | |
147 | } | |
148 | img.src = config.imgURL; | |
149 | }; | |
150 | }; |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "animation.js", | |
5 | "sprite-manager.js" | |
6 | ]; | |
7 | var loaded = 0; | |
8 | for (var i = 0; i < deps.length; i++) { | |
9 | var elem = document.createElement('script'); | |
10 | elem.src = prefix + deps[i]; | |
11 | elem.onload = function() { | |
12 | if (++loaded == deps.length) { | |
13 | var container = document.getElementById(containerId); | |
14 | var t = new TheFrame(); | |
15 | yoob.makeParagraph(container, | |
16 | "<small>Note 1. Green things can be dragged. " + | |
17 | "Note 2. Due to technical limitations, " + | |
18 | "things cannot be dragged off of the computer screen</small>" | |
19 | ); | |
20 | if (!config.canvas) { | |
21 | var c = yoob.makeCanvas(container, 800, 450); | |
22 | c.style.display = "block"; | |
23 | c.width = document.documentElement.clientWidth - c.offsetLeft * 2 | |
24 | //c.height = document.documentElement.clientHeight - c.offsetTop - 5; | |
25 | config.canvas = c; | |
26 | } | |
27 | var pleaseWait = yoob.makeParagraph(container, | |
28 | "Please wait, loading..." | |
29 | ); | |
30 | config.callback = function() { | |
31 | pleaseWait.style.display = "none"; | |
32 | } | |
33 | t.init(config); | |
34 | } | |
35 | }; | |
36 | document.body.appendChild(elem); | |
37 | } | |
38 | } | |
39 | ||
40 | Corner = function() { | |
41 | this.draw = function(ctx) { | |
42 | ctx.fillStyle = "green"; | |
43 | ctx.fillRect(this.getLeftX(), this.getTopY(), this.getWidth(), this.getHeight()); | |
44 | }; | |
45 | }; | |
46 | ||
47 | TheFrame = function() { | |
48 | var request; | |
49 | ||
50 | var canvas; | |
51 | var ctx; | |
52 | ||
53 | var img = new Image(); | |
54 | var fontHeight; | |
55 | ||
56 | var manager; | |
57 | ||
58 | var quote = [ | |
59 | "“The most important thing in art is The Frame.", | |
60 | "For painting: literally; for other arts: figuratively-- because,", | |
61 | "without this humble appliance, you can't know", | |
62 | "where The Art stops and The Real World begins.", | |
63 | "You have to put a 'box' around it because otherwise,", | |
64 | "what is that shit on the wall?”" | |
65 | ]; | |
66 | ||
67 | var getFontHeight = function() { | |
68 | for (var height = canvas.height / 6; ; height--) { | |
69 | ctx.font = height + "px Arial,Sans-serif"; | |
70 | var width = ctx.measureText(quote[1]).width; | |
71 | if (width < canvas.width) | |
72 | break; | |
73 | } | |
74 | fontHeight = height; | |
75 | } | |
76 | ||
77 | this.draw = function() { | |
78 | ctx.fillStyle = "white"; | |
79 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
80 | ||
81 | //ctx.drawImage(img, (canvas.width - img.width) / 2, 0); | |
82 | ctx.drawImage(img, 0, 0, canvas.width, canvas.height); | |
83 | ||
84 | /* XXX knows too much about SpriteManager! */ | |
85 | for (var i = 0; i < manager.sprites.length; i++) { | |
86 | var prev = manager.sprites[i === 0 ? manager.sprites.length - 1 : i - 1]; | |
87 | var curr = manager.sprites[i]; | |
88 | ||
89 | ctx.strokeStyle = "black"; | |
90 | ctx.lineWidth = 15; | |
91 | ctx.beginPath(); | |
92 | ctx.moveTo(prev.getX(), prev.getY()); | |
93 | ctx.lineTo(curr.getX(), curr.getY()); | |
94 | ctx.closePath(); | |
95 | ctx.stroke(); | |
96 | } | |
97 | ||
98 | manager.draw(ctx); | |
99 | ||
100 | ctx.textBaseline = "top"; | |
101 | ctx.font = fontHeight + "px Arial,Sans-serif"; | |
102 | var textTopY = (canvas.height - 6 * fontHeight) / 2; | |
103 | ctx.fillStyle = "white"; | |
104 | for (var i = 0; i <= 5; i++) { | |
105 | if (i === 5) { | |
106 | ctx.font = "bold italic " + fontHeight + "px Arial,Sans-serif"; | |
107 | } | |
108 | var width = ctx.measureText(quote[i]).width; | |
109 | var textX = (canvas.width - width) / 2; | |
110 | ||
111 | ctx.fillText(quote[i], textX, textTopY + i * (fontHeight + 4)); | |
112 | } | |
113 | }; | |
114 | ||
115 | this.update = function() { | |
116 | }; | |
117 | ||
118 | this.init = function(config) { | |
119 | Corner.prototype = new yoob.Sprite(); | |
120 | ||
121 | canvas = config.canvas; | |
122 | ctx = canvas.getContext("2d"); | |
123 | manager = (new yoob.SpriteManager()).init({ | |
124 | canvas: canvas | |
125 | }); | |
126 | var mkHandle = function(x, y) { | |
127 | var d = (new Corner()).init({ | |
128 | x: x, y: y, width: 30, height: 30, | |
129 | isDraggable: true | |
130 | }); | |
131 | manager.addSprite(d); | |
132 | }; | |
133 | var $this = this; | |
134 | img.onload = function() { | |
135 | config.callback(); | |
136 | // at this point, canvas.width is OK, so we can: | |
137 | mkHandle(45, 45); | |
138 | mkHandle(canvas.width - 45, 45); | |
139 | mkHandle(canvas.width - 45, canvas.height - 45); | |
140 | mkHandle(45, canvas.height - 45); | |
141 | getFontHeight(); | |
142 | $this.draw(); | |
143 | $this.animation = (new yoob.Animation()).init({ | |
144 | object: $this | |
145 | }); | |
146 | $this.animation.start(); | |
147 | } | |
148 | img.src = config.imgURL; | |
149 | }; | |
150 | }; |
13 | 13 | </div> |
14 | 14 | |
15 | 15 | </body> |
16 | <script src="the-judgment-of-paris.js"></script> | |
16 | <script src="index.js"></script> | |
17 | 17 | <script> |
18 | 18 | launch('../common-yoob.js-0.11/', 'control_panel'); |
19 | 19 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var canvas = yoob.makeCanvas(container, 500, 500); | |
13 | (new JudgmentOfParis()).init(canvas); | |
14 | } | |
15 | }; | |
16 | document.body.appendChild(elem); | |
17 | } | |
18 | } | |
19 | ||
20 | var twopi = Math.PI * 2; | |
21 | var degrees = twopi / 360; | |
22 | ||
23 | var points = []; | |
24 | ||
25 | Ball = function() { | |
26 | this.init = function(pt1, pt2, rate, radius, style) { | |
27 | this.pt1 = pt1; | |
28 | this.pt2 = pt2; | |
29 | this.style = style; | |
30 | this.radius = radius; | |
31 | this.rate = rate; | |
32 | return this; | |
33 | }; | |
34 | ||
35 | this.getX = function(p, t) { | |
36 | // p is between 0.0 (at pt1) and 1.0 (at pt2) | |
37 | var x1 = points[this.pt1][0] + Math.cos(t / 10) * 50; | |
38 | var x2 = points[this.pt2][0] + Math.sin(t / 10) * 50; | |
39 | return (x2 - x1) * p + x1; | |
40 | }; | |
41 | ||
42 | this.getY = function(p, t) { | |
43 | // p is between 0.0 (at pt1) and 1.0 (at pt2) | |
44 | var y1 = points[this.pt1][1] + Math.sin(t / 18) * 50; | |
45 | var y2 = points[this.pt2][1] + Math.cos(t / 18) * 50; | |
46 | return (y2 - y1) * p + y1; | |
47 | }; | |
48 | ||
49 | this.draw = function(ctx, t) { | |
50 | ctx.beginPath(); | |
51 | ctx.fillStyle = this.style; | |
52 | var p = (Math.sin(t / this.rate) + 1) / 2; | |
53 | var x = this.getX(p, t); | |
54 | var y = this.getY(p, t); | |
55 | ctx.arc(x, y, this.radius, 0, 2 * Math.PI, false); | |
56 | ctx.fill(); | |
57 | }; | |
58 | }; | |
59 | ||
60 | JudgmentOfParis = function() { | |
61 | var ctx = undefined; | |
62 | var canvas = undefined; | |
63 | var info; | |
64 | var balls = []; | |
65 | var numPoints = 10; | |
66 | var numBalls = 50; | |
67 | ||
68 | var t = 0; | |
69 | ||
70 | this.init = function(c) { | |
71 | canvas = c; | |
72 | ctx = canvas.getContext("2d"); | |
73 | info = document.getElementById('info'); | |
74 | var $this = this; | |
75 | ||
76 | points = []; | |
77 | for (var i = 0; i < numPoints; i++) { | |
78 | var pt = [Math.random() * canvas.width, Math.random() * canvas.height]; | |
79 | points.push(pt); | |
80 | } | |
81 | ||
82 | balls = []; | |
83 | for (var i = 0; i < numBalls; i++) { | |
84 | var pt1 = Math.floor(Math.random() * points.length); | |
85 | var pt2 = pt1; | |
86 | while (pt2 === pt1) { | |
87 | pt2 = Math.floor(Math.random() * points.length); | |
88 | } | |
89 | var rate = Math.floor(Math.random() * 100) + 10; | |
90 | var radius = Math.floor(Math.random() * 10) + 5; | |
91 | var style = "hsl(" + Math.floor(Math.random() * 256) + ",33%,66%)"; | |
92 | var ball = new Ball().init(pt1, pt2, rate, radius, style); | |
93 | balls.push(ball); | |
94 | } | |
95 | ||
96 | this.animation = (new yoob.Animation).init({ | |
97 | object: this | |
98 | }); | |
99 | this.animation.start(); | |
100 | ||
101 | return this; | |
102 | }; | |
103 | ||
104 | this.gradFill = function(x, y, w, h, gx1, gy1, gx2, gy2, t1, t2) { | |
105 | var linGrad = ctx.createLinearGradient(gx1, gy1, gx2, gy2); | |
106 | linGrad.addColorStop(0, "hsl(" + (t1 % 360) + ",50%,50%)"); | |
107 | linGrad.addColorStop(1, "hsl(" + (t2 % 360) + ",50%,50%)"); | |
108 | ctx.fillStyle = linGrad; | |
109 | ctx.fillRect(x, y, w, h); | |
110 | }; | |
111 | ||
112 | this.draw = function() { | |
113 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
114 | var cx = canvas.width / 2; | |
115 | var cy = canvas.width / 2; | |
116 | ||
117 | this.gradFill(0, 0, cx, cy, | |
118 | 0, 0, cx, cy, | |
119 | t, t + 180); | |
120 | this.gradFill(cx, 0, cx, cy, | |
121 | canvas.width, 0, cx, cy, | |
122 | t + 90, t + 270); | |
123 | this.gradFill(0, cy, cx, cy, | |
124 | 0, canvas.height, cx, cy, | |
125 | -t, -t + 180); | |
126 | this.gradFill(cx, cy, cx, cy, | |
127 | canvas.width, canvas.height, cx, cy, | |
128 | -t + 90, -t + 270); | |
129 | ||
130 | //if () { | |
131 | for (var i = 0; i < balls.length; i++) { | |
132 | balls[i].draw(ctx, t); | |
133 | } | |
134 | ||
135 | var phase = Math.floor(t / 100) % 3; | |
136 | ctx.save(); | |
137 | var f = 1 + Math.sin(t / 30); | |
138 | if (phase === 0) { | |
139 | ctx.scale(f, 1); | |
140 | ctx.translate(cx / f, cy); | |
141 | } else if (phase === 1) { | |
142 | ctx.scale(1, f); | |
143 | ctx.translate(cx / f, cy); | |
144 | } else { | |
145 | ctx.scale(f, 1 / f); | |
146 | ctx.translate(cx, cy); | |
147 | } | |
148 | ctx.beginPath(); | |
149 | ctx.strokeStyle = 'white'; | |
150 | ctx.lineWidth = 1; | |
151 | ctx.arc(0, 0, (Math.log(t % cx)) * 50, 0, 2 * Math.PI, false); | |
152 | ctx.stroke(); | |
153 | ctx.restore(); | |
154 | ||
155 | for (var j = 0; j < 4; j++) { | |
156 | ctx.beginPath(); | |
157 | for (var i = 0; i <= 25; i++) { | |
158 | var theta = twopi * ((j * 25 + i) / 100); | |
159 | var r = 150 + Math.sin((t + (i * i)) / twopi) * 60; | |
160 | var x = cx + r * Math.cos(theta); | |
161 | var y = cy + r * Math.sin(theta); | |
162 | ctx.lineTo(x, y); | |
163 | } | |
164 | ctx.strokeStyle = "black"; | |
165 | ctx.stroke(); | |
166 | } | |
167 | }; | |
168 | ||
169 | this.update = function() { | |
170 | t += 1; | |
171 | }; | |
172 | }; |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "animation.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | var canvas = yoob.makeCanvas(container, 500, 500); | |
13 | (new JudgmentOfParis()).init(canvas); | |
14 | } | |
15 | }; | |
16 | document.body.appendChild(elem); | |
17 | } | |
18 | } | |
19 | ||
20 | var twopi = Math.PI * 2; | |
21 | var degrees = twopi / 360; | |
22 | ||
23 | var points = []; | |
24 | ||
25 | Ball = function() { | |
26 | this.init = function(pt1, pt2, rate, radius, style) { | |
27 | this.pt1 = pt1; | |
28 | this.pt2 = pt2; | |
29 | this.style = style; | |
30 | this.radius = radius; | |
31 | this.rate = rate; | |
32 | return this; | |
33 | }; | |
34 | ||
35 | this.getX = function(p, t) { | |
36 | // p is between 0.0 (at pt1) and 1.0 (at pt2) | |
37 | var x1 = points[this.pt1][0] + Math.cos(t / 10) * 50; | |
38 | var x2 = points[this.pt2][0] + Math.sin(t / 10) * 50; | |
39 | return (x2 - x1) * p + x1; | |
40 | }; | |
41 | ||
42 | this.getY = function(p, t) { | |
43 | // p is between 0.0 (at pt1) and 1.0 (at pt2) | |
44 | var y1 = points[this.pt1][1] + Math.sin(t / 18) * 50; | |
45 | var y2 = points[this.pt2][1] + Math.cos(t / 18) * 50; | |
46 | return (y2 - y1) * p + y1; | |
47 | }; | |
48 | ||
49 | this.draw = function(ctx, t) { | |
50 | ctx.beginPath(); | |
51 | ctx.fillStyle = this.style; | |
52 | var p = (Math.sin(t / this.rate) + 1) / 2; | |
53 | var x = this.getX(p, t); | |
54 | var y = this.getY(p, t); | |
55 | ctx.arc(x, y, this.radius, 0, 2 * Math.PI, false); | |
56 | ctx.fill(); | |
57 | }; | |
58 | }; | |
59 | ||
60 | JudgmentOfParis = function() { | |
61 | var ctx = undefined; | |
62 | var canvas = undefined; | |
63 | var info; | |
64 | var balls = []; | |
65 | var numPoints = 10; | |
66 | var numBalls = 50; | |
67 | ||
68 | var t = 0; | |
69 | ||
70 | this.init = function(c) { | |
71 | canvas = c; | |
72 | ctx = canvas.getContext("2d"); | |
73 | info = document.getElementById('info'); | |
74 | var $this = this; | |
75 | ||
76 | points = []; | |
77 | for (var i = 0; i < numPoints; i++) { | |
78 | var pt = [Math.random() * canvas.width, Math.random() * canvas.height]; | |
79 | points.push(pt); | |
80 | } | |
81 | ||
82 | balls = []; | |
83 | for (var i = 0; i < numBalls; i++) { | |
84 | var pt1 = Math.floor(Math.random() * points.length); | |
85 | var pt2 = pt1; | |
86 | while (pt2 === pt1) { | |
87 | pt2 = Math.floor(Math.random() * points.length); | |
88 | } | |
89 | var rate = Math.floor(Math.random() * 100) + 10; | |
90 | var radius = Math.floor(Math.random() * 10) + 5; | |
91 | var style = "hsl(" + Math.floor(Math.random() * 256) + ",33%,66%)"; | |
92 | var ball = new Ball().init(pt1, pt2, rate, radius, style); | |
93 | balls.push(ball); | |
94 | } | |
95 | ||
96 | this.animation = (new yoob.Animation).init({ | |
97 | object: this | |
98 | }); | |
99 | this.animation.start(); | |
100 | ||
101 | return this; | |
102 | }; | |
103 | ||
104 | this.gradFill = function(x, y, w, h, gx1, gy1, gx2, gy2, t1, t2) { | |
105 | var linGrad = ctx.createLinearGradient(gx1, gy1, gx2, gy2); | |
106 | linGrad.addColorStop(0, "hsl(" + (t1 % 360) + ",50%,50%)"); | |
107 | linGrad.addColorStop(1, "hsl(" + (t2 % 360) + ",50%,50%)"); | |
108 | ctx.fillStyle = linGrad; | |
109 | ctx.fillRect(x, y, w, h); | |
110 | }; | |
111 | ||
112 | this.draw = function() { | |
113 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
114 | var cx = canvas.width / 2; | |
115 | var cy = canvas.width / 2; | |
116 | ||
117 | this.gradFill(0, 0, cx, cy, | |
118 | 0, 0, cx, cy, | |
119 | t, t + 180); | |
120 | this.gradFill(cx, 0, cx, cy, | |
121 | canvas.width, 0, cx, cy, | |
122 | t + 90, t + 270); | |
123 | this.gradFill(0, cy, cx, cy, | |
124 | 0, canvas.height, cx, cy, | |
125 | -t, -t + 180); | |
126 | this.gradFill(cx, cy, cx, cy, | |
127 | canvas.width, canvas.height, cx, cy, | |
128 | -t + 90, -t + 270); | |
129 | ||
130 | //if () { | |
131 | for (var i = 0; i < balls.length; i++) { | |
132 | balls[i].draw(ctx, t); | |
133 | } | |
134 | ||
135 | var phase = Math.floor(t / 100) % 3; | |
136 | ctx.save(); | |
137 | var f = 1 + Math.sin(t / 30); | |
138 | if (phase === 0) { | |
139 | ctx.scale(f, 1); | |
140 | ctx.translate(cx / f, cy); | |
141 | } else if (phase === 1) { | |
142 | ctx.scale(1, f); | |
143 | ctx.translate(cx / f, cy); | |
144 | } else { | |
145 | ctx.scale(f, 1 / f); | |
146 | ctx.translate(cx, cy); | |
147 | } | |
148 | ctx.beginPath(); | |
149 | ctx.strokeStyle = 'white'; | |
150 | ctx.lineWidth = 1; | |
151 | ctx.arc(0, 0, (Math.log(t % cx)) * 50, 0, 2 * Math.PI, false); | |
152 | ctx.stroke(); | |
153 | ctx.restore(); | |
154 | ||
155 | for (var j = 0; j < 4; j++) { | |
156 | ctx.beginPath(); | |
157 | for (var i = 0; i <= 25; i++) { | |
158 | var theta = twopi * ((j * 25 + i) / 100); | |
159 | var r = 150 + Math.sin((t + (i * i)) / twopi) * 60; | |
160 | var x = cx + r * Math.cos(theta); | |
161 | var y = cy + r * Math.sin(theta); | |
162 | ctx.lineTo(x, y); | |
163 | } | |
164 | ctx.strokeStyle = "black"; | |
165 | ctx.stroke(); | |
166 | } | |
167 | }; | |
168 | ||
169 | this.update = function() { | |
170 | t += 1; | |
171 | }; | |
172 | }; |
12 | 12 | <div id="container"></div> |
13 | 13 | |
14 | 14 | </body> |
15 | <script src="two-fifty-six.js"></script> | |
15 | <script src="index.js"></script> | |
16 | 16 | <script> |
17 | 17 | launch('../common-yoob.js-0.11/', 'container'); |
18 | 18 | </script> |
0 | "use strict"; | |
1 | ||
2 | var GRID_WIDTH = 16; | |
3 | var GRID_HEIGHT = 16; | |
4 | ||
5 | var BLOCK_WIDTH = 8; | |
6 | var BLOCK_HEIGHT = 8; | |
7 | ||
8 | var CELL_WIDTH = BLOCK_WIDTH * 2; | |
9 | var CELL_HEIGHT = BLOCK_HEIGHT * 2; | |
10 | ||
11 | ||
12 | function launch(prefix, containerId, config) { | |
13 | var config = config || {}; | |
14 | var deps = [ | |
15 | "element-factory.js", | |
16 | "playfield.js", | |
17 | "playfield-canvas-view.js", | |
18 | "animation.js" | |
19 | ]; | |
20 | var loaded = 0; | |
21 | for (var i = 0; i < deps.length; i++) { | |
22 | var elem = document.createElement('script'); | |
23 | elem.src = prefix + deps[i]; | |
24 | elem.onload = function() { | |
25 | if (++loaded < deps.length) return; | |
26 | ||
27 | var container = document.getElementById(containerId); | |
28 | var g = new TwoFiftySix(); | |
29 | ||
30 | var paramList = window.location.search.substr(1).split('&'); | |
31 | var params = {}; | |
32 | for (var i = 0; i < paramList.length; i++) { | |
33 | var pair = paramList[i].split('='); | |
34 | params[pair[0]] = pair[1]; | |
35 | } | |
36 | ||
37 | var getIntParam = function(paramName, def, minV, maxV) { | |
38 | var value = parseInt(params[paramName] || ('' + def), 10); | |
39 | value = isNaN(value) ? def : value; | |
40 | value = value < minV ? minV : value; | |
41 | value = value > maxV ? maxV : value; | |
42 | return value; | |
43 | }; | |
44 | ||
45 | var canvas = yoob.makeCanvas( | |
46 | container, | |
47 | GRID_WIDTH * CELL_WIDTH, GRID_HEIGHT * CELL_HEIGHT | |
48 | ); | |
49 | canvas.style.border = Math.round(BLOCK_WIDTH / 2) + 'px solid black'; | |
50 | ||
51 | var speed = getIntParam('speed', 5, 0, 50); | |
52 | yoob.makeLineBreak(container); | |
53 | yoob.makeSliderPlusTextInput( | |
54 | container, "Speed:", 0, 50, 5, speed, function(v) { | |
55 | g.setDelay(50 - v); | |
56 | } | |
57 | ); | |
58 | g.setDelay(50 - speed); | |
59 | ||
60 | var variety = getIntParam('variety', 1, 1, 256); | |
61 | yoob.makeLineBreak(container); | |
62 | yoob.makeSliderPlusTextInput( | |
63 | container, "Variety:", 1, 256, 5, variety, function(v) { | |
64 | g.setVariety(v); | |
65 | } | |
66 | ); | |
67 | g.setVariety(variety); | |
68 | ||
69 | var noise = getIntParam('noise', 0, 0, 100); | |
70 | yoob.makeLineBreak(container); | |
71 | yoob.makeSliderPlusTextInput( | |
72 | container, "Noise:", 0, 100, 5, noise, function(v) { | |
73 | g.setNoise(v); | |
74 | } | |
75 | ); | |
76 | g.setNoise(noise); | |
77 | ||
78 | var palette = params.palette || 'Tetrade'; | |
79 | ||
80 | yoob.makeLineBreak(container); | |
81 | yoob.makeSelect(container, "Palette:", [ | |
82 | ['RGB', 'RGB'], | |
83 | ['Greyscale', 'Greyscale'], | |
84 | ['Tetrade', 'Tetrade'] | |
85 | ], function(value) { | |
86 | var pals = { | |
87 | 'RGB': [ | |
88 | '#ffffff', | |
89 | '#ff0000', | |
90 | '#00ff00', | |
91 | '#0000ff' | |
92 | ], | |
93 | 'Greyscale': [ | |
94 | '#ffffff', | |
95 | '#aaaaaa', | |
96 | '#555555', | |
97 | '#000000' | |
98 | ], | |
99 | 'Tetrade': [ | |
100 | '#E1E685', | |
101 | '#85E6BB', | |
102 | '#8A85E6', | |
103 | '#E685B0' | |
104 | ] | |
105 | }; | |
106 | g.setMasterPalette(pals[value]); | |
107 | }, palette); | |
108 | ||
109 | g.init({ | |
110 | canvas: canvas, | |
111 | }); | |
112 | }; | |
113 | document.body.appendChild(elem); | |
114 | } | |
115 | } | |
116 | ||
117 | ||
118 | function shuffle(ary) { | |
119 | var oldAry = ary.map(function(x) { return x; }) | |
120 | var newAry = []; | |
121 | while (oldAry.length > 0) { | |
122 | newAry.push(oldAry.splice(Math.random() * oldAry.length, 1)[0]); | |
123 | } | |
124 | return newAry; | |
125 | } | |
126 | ||
127 | ||
128 | var TwoFiftySix = function() { | |
129 | this.init = function(cfg) { | |
130 | this.canvas = cfg.canvas; | |
131 | this.ctx = this.canvas.getContext('2d'); | |
132 | if (!this.masterPalette) { | |
133 | this.masterPalette = [ | |
134 | '#ffffff', | |
135 | '#ff0000', | |
136 | '#00ff00', | |
137 | '#0000ff' | |
138 | ]; | |
139 | } | |
140 | this.palettes = new Array(256); | |
141 | this.makePalettes(); | |
142 | //this.delay = cfg.delay || 0; | |
143 | this.delayCounter = 0; | |
144 | //this.noise = 0; | |
145 | //this.variety = cfg.variety || 1; | |
146 | ||
147 | this.playfield = (new yoob.Playfield()).init(); | |
148 | ||
149 | for (var x = 0; x < GRID_WIDTH; x++) { | |
150 | for (var y = 0; y < GRID_HEIGHT; y++) { | |
151 | this.playfield.put(x, y, y*GRID_WIDTH + x); | |
152 | } | |
153 | } | |
154 | ||
155 | this.canvasView = new yoob.PlayfieldCanvasView().init({ | |
156 | playfield: this.playfield, | |
157 | canvas: this.canvas, | |
158 | cellWidth: CELL_WIDTH, | |
159 | cellHeight: CELL_HEIGHT | |
160 | }); | |
161 | ||
162 | var $this = this; | |
163 | this.canvasView.drawCell = function(ctx, value, playfieldX, playfieldY, | |
164 | canvasX, canvasY, cellWidth, cellHeight) { | |
165 | ||
166 | var palIndex = playfieldX + playfieldY * GRID_WIDTH; | |
167 | var pal = $this.palettes[palIndex % $this.variety]; | |
168 | ||
169 | var colours = []; | |
170 | colours.push(pal[value & 0x03]); | |
171 | colours.push(pal[(value >> 2) & 0x03]); | |
172 | colours.push(pal[(value >> 4) & 0x03]); | |
173 | colours.push(pal[(value >> 6) & 0x03]); | |
174 | ||
175 | if (Math.floor(Math.random() * 100) < $this.noise) { | |
176 | colours = shuffle(colours); | |
177 | } | |
178 | ||
179 | ctx.fillStyle = colours[0]; | |
180 | ctx.fillRect(canvasX, canvasY, BLOCK_WIDTH, BLOCK_HEIGHT); | |
181 | ctx.fillStyle = colours[1]; | |
182 | ctx.fillRect(canvasX + BLOCK_WIDTH, canvasY, BLOCK_WIDTH, BLOCK_HEIGHT); | |
183 | ctx.fillStyle = colours[2]; | |
184 | ctx.fillRect(canvasX, canvasY + BLOCK_HEIGHT, BLOCK_WIDTH, BLOCK_HEIGHT); | |
185 | ctx.fillStyle = colours[3]; | |
186 | ctx.fillRect(canvasX + BLOCK_WIDTH, canvasY + BLOCK_HEIGHT, BLOCK_WIDTH, BLOCK_HEIGHT); | |
187 | ||
188 | if ($this.outline) { | |
189 | ctx.lineWidth = 1; | |
190 | ctx.strokeStyle = 'black'; | |
191 | ctx.strokeRect(canvasX, canvasY, CELL_WIDTH, CELL_HEIGHT); | |
192 | } | |
193 | }; | |
194 | ||
195 | this.animation = (new yoob.Animation()).init({'object': this}); | |
196 | this.animation.start(); | |
197 | }; | |
198 | ||
199 | this.setMasterPalette = function(pal) { | |
200 | this.masterPalette = pal; | |
201 | }; | |
202 | ||
203 | this.makePalettes = function() { | |
204 | for (var i = 0; i < 256; i++) { | |
205 | this.palettes[i] = shuffle(this.masterPalette); | |
206 | } | |
207 | }; | |
208 | ||
209 | this.setDelay = function(d) { | |
210 | this.delay = d; | |
211 | }; | |
212 | ||
213 | this.setNoise = function(d) { | |
214 | this.noise = d; | |
215 | }; | |
216 | ||
217 | this.setVariety = function(v) { | |
218 | v = v || 0; | |
219 | if (v < 1 || v > 256) return; | |
220 | this.variety = v; | |
221 | }; | |
222 | ||
223 | this.setScramble = function(b) { | |
224 | this.scramble = b; | |
225 | }; | |
226 | ||
227 | this.update = function() { | |
228 | if (this.delayCounter < this.delay) { | |
229 | this.delayCounter++; | |
230 | return; | |
231 | } | |
232 | this.delayCounter = 0; | |
233 | ||
234 | this.makePalettes(); | |
235 | }; | |
236 | ||
237 | this.draw = function() { | |
238 | this.canvasView.draw(); | |
239 | }; | |
240 | } |
0 | "use strict"; | |
1 | ||
2 | var GRID_WIDTH = 16; | |
3 | var GRID_HEIGHT = 16; | |
4 | ||
5 | var BLOCK_WIDTH = 8; | |
6 | var BLOCK_HEIGHT = 8; | |
7 | ||
8 | var CELL_WIDTH = BLOCK_WIDTH * 2; | |
9 | var CELL_HEIGHT = BLOCK_HEIGHT * 2; | |
10 | ||
11 | ||
12 | function launch(prefix, containerId, config) { | |
13 | var config = config || {}; | |
14 | var deps = [ | |
15 | "element-factory.js", | |
16 | "playfield.js", | |
17 | "playfield-canvas-view.js", | |
18 | "animation.js" | |
19 | ]; | |
20 | var loaded = 0; | |
21 | for (var i = 0; i < deps.length; i++) { | |
22 | var elem = document.createElement('script'); | |
23 | elem.src = prefix + deps[i]; | |
24 | elem.onload = function() { | |
25 | if (++loaded < deps.length) return; | |
26 | ||
27 | var container = document.getElementById(containerId); | |
28 | var g = new TwoFiftySix(); | |
29 | ||
30 | var paramList = window.location.search.substr(1).split('&'); | |
31 | var params = {}; | |
32 | for (var i = 0; i < paramList.length; i++) { | |
33 | var pair = paramList[i].split('='); | |
34 | params[pair[0]] = pair[1]; | |
35 | } | |
36 | ||
37 | var getIntParam = function(paramName, def, minV, maxV) { | |
38 | var value = parseInt(params[paramName] || ('' + def), 10); | |
39 | value = isNaN(value) ? def : value; | |
40 | value = value < minV ? minV : value; | |
41 | value = value > maxV ? maxV : value; | |
42 | return value; | |
43 | }; | |
44 | ||
45 | var canvas = yoob.makeCanvas( | |
46 | container, | |
47 | GRID_WIDTH * CELL_WIDTH, GRID_HEIGHT * CELL_HEIGHT | |
48 | ); | |
49 | canvas.style.border = Math.round(BLOCK_WIDTH / 2) + 'px solid black'; | |
50 | ||
51 | var speed = getIntParam('speed', 5, 0, 50); | |
52 | yoob.makeLineBreak(container); | |
53 | yoob.makeSliderPlusTextInput( | |
54 | container, "Speed:", 0, 50, 5, speed, function(v) { | |
55 | g.setDelay(50 - v); | |
56 | } | |
57 | ); | |
58 | g.setDelay(50 - speed); | |
59 | ||
60 | var variety = getIntParam('variety', 1, 1, 256); | |
61 | yoob.makeLineBreak(container); | |
62 | yoob.makeSliderPlusTextInput( | |
63 | container, "Variety:", 1, 256, 5, variety, function(v) { | |
64 | g.setVariety(v); | |
65 | } | |
66 | ); | |
67 | g.setVariety(variety); | |
68 | ||
69 | var noise = getIntParam('noise', 0, 0, 100); | |
70 | yoob.makeLineBreak(container); | |
71 | yoob.makeSliderPlusTextInput( | |
72 | container, "Noise:", 0, 100, 5, noise, function(v) { | |
73 | g.setNoise(v); | |
74 | } | |
75 | ); | |
76 | g.setNoise(noise); | |
77 | ||
78 | var palette = params.palette || 'Tetrade'; | |
79 | ||
80 | yoob.makeLineBreak(container); | |
81 | yoob.makeSelect(container, "Palette:", [ | |
82 | ['RGB', 'RGB'], | |
83 | ['Greyscale', 'Greyscale'], | |
84 | ['Tetrade', 'Tetrade'] | |
85 | ], function(value) { | |
86 | var pals = { | |
87 | 'RGB': [ | |
88 | '#ffffff', | |
89 | '#ff0000', | |
90 | '#00ff00', | |
91 | '#0000ff' | |
92 | ], | |
93 | 'Greyscale': [ | |
94 | '#ffffff', | |
95 | '#aaaaaa', | |
96 | '#555555', | |
97 | '#000000' | |
98 | ], | |
99 | 'Tetrade': [ | |
100 | '#E1E685', | |
101 | '#85E6BB', | |
102 | '#8A85E6', | |
103 | '#E685B0' | |
104 | ] | |
105 | }; | |
106 | g.setMasterPalette(pals[value]); | |
107 | }, palette); | |
108 | ||
109 | g.init({ | |
110 | canvas: canvas, | |
111 | }); | |
112 | }; | |
113 | document.body.appendChild(elem); | |
114 | } | |
115 | } | |
116 | ||
117 | ||
118 | function shuffle(ary) { | |
119 | var oldAry = ary.map(function(x) { return x; }) | |
120 | var newAry = []; | |
121 | while (oldAry.length > 0) { | |
122 | newAry.push(oldAry.splice(Math.random() * oldAry.length, 1)[0]); | |
123 | } | |
124 | return newAry; | |
125 | } | |
126 | ||
127 | ||
128 | var TwoFiftySix = function() { | |
129 | this.init = function(cfg) { | |
130 | this.canvas = cfg.canvas; | |
131 | this.ctx = this.canvas.getContext('2d'); | |
132 | if (!this.masterPalette) { | |
133 | this.masterPalette = [ | |
134 | '#ffffff', | |
135 | '#ff0000', | |
136 | '#00ff00', | |
137 | '#0000ff' | |
138 | ]; | |
139 | } | |
140 | this.palettes = new Array(256); | |
141 | this.makePalettes(); | |
142 | //this.delay = cfg.delay || 0; | |
143 | this.delayCounter = 0; | |
144 | //this.noise = 0; | |
145 | //this.variety = cfg.variety || 1; | |
146 | ||
147 | this.playfield = (new yoob.Playfield()).init(); | |
148 | ||
149 | for (var x = 0; x < GRID_WIDTH; x++) { | |
150 | for (var y = 0; y < GRID_HEIGHT; y++) { | |
151 | this.playfield.put(x, y, y*GRID_WIDTH + x); | |
152 | } | |
153 | } | |
154 | ||
155 | this.canvasView = new yoob.PlayfieldCanvasView().init({ | |
156 | playfield: this.playfield, | |
157 | canvas: this.canvas, | |
158 | cellWidth: CELL_WIDTH, | |
159 | cellHeight: CELL_HEIGHT | |
160 | }); | |
161 | ||
162 | var $this = this; | |
163 | this.canvasView.drawCell = function(ctx, value, playfieldX, playfieldY, | |
164 | canvasX, canvasY, cellWidth, cellHeight) { | |
165 | ||
166 | var palIndex = playfieldX + playfieldY * GRID_WIDTH; | |
167 | var pal = $this.palettes[palIndex % $this.variety]; | |
168 | ||
169 | var colours = []; | |
170 | colours.push(pal[value & 0x03]); | |
171 | colours.push(pal[(value >> 2) & 0x03]); | |
172 | colours.push(pal[(value >> 4) & 0x03]); | |
173 | colours.push(pal[(value >> 6) & 0x03]); | |
174 | ||
175 | if (Math.floor(Math.random() * 100) < $this.noise) { | |
176 | colours = shuffle(colours); | |
177 | } | |
178 | ||
179 | ctx.fillStyle = colours[0]; | |
180 | ctx.fillRect(canvasX, canvasY, BLOCK_WIDTH, BLOCK_HEIGHT); | |
181 | ctx.fillStyle = colours[1]; | |
182 | ctx.fillRect(canvasX + BLOCK_WIDTH, canvasY, BLOCK_WIDTH, BLOCK_HEIGHT); | |
183 | ctx.fillStyle = colours[2]; | |
184 | ctx.fillRect(canvasX, canvasY + BLOCK_HEIGHT, BLOCK_WIDTH, BLOCK_HEIGHT); | |
185 | ctx.fillStyle = colours[3]; | |
186 | ctx.fillRect(canvasX + BLOCK_WIDTH, canvasY + BLOCK_HEIGHT, BLOCK_WIDTH, BLOCK_HEIGHT); | |
187 | ||
188 | if ($this.outline) { | |
189 | ctx.lineWidth = 1; | |
190 | ctx.strokeStyle = 'black'; | |
191 | ctx.strokeRect(canvasX, canvasY, CELL_WIDTH, CELL_HEIGHT); | |
192 | } | |
193 | }; | |
194 | ||
195 | this.animation = (new yoob.Animation()).init({'object': this}); | |
196 | this.animation.start(); | |
197 | }; | |
198 | ||
199 | this.setMasterPalette = function(pal) { | |
200 | this.masterPalette = pal; | |
201 | }; | |
202 | ||
203 | this.makePalettes = function() { | |
204 | for (var i = 0; i < 256; i++) { | |
205 | this.palettes[i] = shuffle(this.masterPalette); | |
206 | } | |
207 | }; | |
208 | ||
209 | this.setDelay = function(d) { | |
210 | this.delay = d; | |
211 | }; | |
212 | ||
213 | this.setNoise = function(d) { | |
214 | this.noise = d; | |
215 | }; | |
216 | ||
217 | this.setVariety = function(v) { | |
218 | v = v || 0; | |
219 | if (v < 1 || v > 256) return; | |
220 | this.variety = v; | |
221 | }; | |
222 | ||
223 | this.setScramble = function(b) { | |
224 | this.scramble = b; | |
225 | }; | |
226 | ||
227 | this.update = function() { | |
228 | if (this.delayCounter < this.delay) { | |
229 | this.delayCounter++; | |
230 | return; | |
231 | } | |
232 | this.delayCounter = 0; | |
233 | ||
234 | this.makePalettes(); | |
235 | }; | |
236 | ||
237 | this.draw = function() { | |
238 | this.canvasView.draw(); | |
239 | }; | |
240 | } |
9 | 9 | <div id="container"></div> |
10 | 10 | |
11 | 11 | </body> |
12 | <script src="uncle-ankur.js"></script> | |
12 | <script src="index.js"></script> | |
13 | 13 | <script> |
14 | 14 | launch('../common-yoob.js-0.11/', 'container'); |
15 | 15 | </script> |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "animation.js" | |
5 | ]; | |
6 | var loaded = 0; | |
7 | for (var i = 0; i < deps.length; i++) { | |
8 | var elem = document.createElement('script'); | |
9 | elem.src = prefix + deps[i]; | |
10 | elem.onload = function() { | |
11 | if (++loaded < deps.length) return; | |
12 | var container = document.getElementById(containerId); | |
13 | var t = new UncleAnkur(); | |
14 | var canvas = yoob.makeCanvas(container, 500, 500); | |
15 | t.init({ | |
16 | 'canvas': canvas | |
17 | }); | |
18 | }; | |
19 | document.body.appendChild(elem); | |
20 | } | |
21 | } | |
22 | ||
23 | ||
24 | Transform = function() { | |
25 | this.init = function(a, b, c, d, e, f) { | |
26 | this.a = a; | |
27 | this.b = b; | |
28 | this.c = c; | |
29 | this.d = d; | |
30 | this.e = e; | |
31 | this.f = f; | |
32 | return this; | |
33 | }; | |
34 | ||
35 | this.initRandom = function() { | |
36 | this.init( | |
37 | Math.random() * 2 - 1, | |
38 | Math.random() * 2 - 1, | |
39 | Math.random() * 2 - 1, | |
40 | Math.random() * 2 - 1, | |
41 | Math.random() * 2 - 1, | |
42 | Math.random() * 2 - 1 | |
43 | ); | |
44 | return this; | |
45 | }; | |
46 | ||
47 | this.applyToContext = function(ctx) { | |
48 | ctx.setTransform(this.a, this.b, this.c, this.d, this.e, this.f); | |
49 | }; | |
50 | }; | |
51 | ||
52 | ||
53 | UncleAnkur = function() { | |
54 | var canvas; | |
55 | var ctx; | |
56 | var linGrad; | |
57 | var radGrad; | |
58 | var xforms = new Array(); | |
59 | var xformIndex = 0; | |
60 | ||
61 | this.draw = function() { | |
62 | ctx.fillStyle = linGrad; | |
63 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
64 | ||
65 | for (var i = 0; i < xforms.length; i++) { | |
66 | ctx.save(); | |
67 | xforms[i].applyToContext(ctx); | |
68 | ctx.fillStyle = radGrad; | |
69 | ctx.beginPath(); | |
70 | ctx.arc(230, 230, 150, 0, Math.PI * 2, false); | |
71 | ctx.fill(); | |
72 | ctx.restore(); | |
73 | } | |
74 | } | |
75 | ||
76 | this.update = function() { | |
77 | xforms[xformIndex] = (new Transform()).initRandom(); | |
78 | xformIndex = (xformIndex + 1) % xforms.length; | |
79 | }; | |
80 | ||
81 | this.init = function(cfg) { | |
82 | canvas = cfg.canvas; | |
83 | numHighlights = cfg.numHighlights || 8; | |
84 | ctx = canvas.getContext("2d"); | |
85 | linGrad = ctx.createLinearGradient(50, 0, 250, 400); | |
86 | ||
87 | linGrad.addColorStop(0, "aquamarine"); | |
88 | linGrad.addColorStop(1, "darkolivegreen"); | |
89 | ||
90 | radGrad = ctx.createRadialGradient( | |
91 | 200, 200, 25, | |
92 | 200, 200, 150); | |
93 | radGrad.addColorStop(0, "#c0e0ff"); | |
94 | radGrad.addColorStop(1, "rgba(255,255,255,0)"); | |
95 | ||
96 | for (var i = 0; i < numHighlights; i++) { | |
97 | xforms[i] = (new Transform()).initRandom(); | |
98 | } | |
99 | ||
100 | this.animation = (new yoob.Animation()).init({ | |
101 | 'object': this | |
102 | }); | |
103 | this.animation.start(); | |
104 | }; | |
105 | }; |
0 | function launch(prefix, containerId, config) { | |
1 | var config = config || {}; | |
2 | var deps = [ | |
3 | "element-factory.js", | |
4 | "animation.js" | |
5 | ]; | |
6 | var loaded = 0; | |
7 | for (var i = 0; i < deps.length; i++) { | |
8 | var elem = document.createElement('script'); | |
9 | elem.src = prefix + deps[i]; | |
10 | elem.onload = function() { | |
11 | if (++loaded < deps.length) return; | |
12 | var container = document.getElementById(containerId); | |
13 | var t = new UncleAnkur(); | |
14 | var canvas = yoob.makeCanvas(container, 500, 500); | |
15 | t.init({ | |
16 | 'canvas': canvas | |
17 | }); | |
18 | }; | |
19 | document.body.appendChild(elem); | |
20 | } | |
21 | } | |
22 | ||
23 | ||
24 | Transform = function() { | |
25 | this.init = function(a, b, c, d, e, f) { | |
26 | this.a = a; | |
27 | this.b = b; | |
28 | this.c = c; | |
29 | this.d = d; | |
30 | this.e = e; | |
31 | this.f = f; | |
32 | return this; | |
33 | }; | |
34 | ||
35 | this.initRandom = function() { | |
36 | this.init( | |
37 | Math.random() * 2 - 1, | |
38 | Math.random() * 2 - 1, | |
39 | Math.random() * 2 - 1, | |
40 | Math.random() * 2 - 1, | |
41 | Math.random() * 2 - 1, | |
42 | Math.random() * 2 - 1 | |
43 | ); | |
44 | return this; | |
45 | }; | |
46 | ||
47 | this.applyToContext = function(ctx) { | |
48 | ctx.setTransform(this.a, this.b, this.c, this.d, this.e, this.f); | |
49 | }; | |
50 | }; | |
51 | ||
52 | ||
53 | UncleAnkur = function() { | |
54 | var canvas; | |
55 | var ctx; | |
56 | var linGrad; | |
57 | var radGrad; | |
58 | var xforms = new Array(); | |
59 | var xformIndex = 0; | |
60 | ||
61 | this.draw = function() { | |
62 | ctx.fillStyle = linGrad; | |
63 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
64 | ||
65 | for (var i = 0; i < xforms.length; i++) { | |
66 | ctx.save(); | |
67 | xforms[i].applyToContext(ctx); | |
68 | ctx.fillStyle = radGrad; | |
69 | ctx.beginPath(); | |
70 | ctx.arc(230, 230, 150, 0, Math.PI * 2, false); | |
71 | ctx.fill(); | |
72 | ctx.restore(); | |
73 | } | |
74 | } | |
75 | ||
76 | this.update = function() { | |
77 | xforms[xformIndex] = (new Transform()).initRandom(); | |
78 | xformIndex = (xformIndex + 1) % xforms.length; | |
79 | }; | |
80 | ||
81 | this.init = function(cfg) { | |
82 | canvas = cfg.canvas; | |
83 | numHighlights = cfg.numHighlights || 8; | |
84 | ctx = canvas.getContext("2d"); | |
85 | linGrad = ctx.createLinearGradient(50, 0, 250, 400); | |
86 | ||
87 | linGrad.addColorStop(0, "aquamarine"); | |
88 | linGrad.addColorStop(1, "darkolivegreen"); | |
89 | ||
90 | radGrad = ctx.createRadialGradient( | |
91 | 200, 200, 25, | |
92 | 200, 200, 150); | |
93 | radGrad.addColorStop(0, "#c0e0ff"); | |
94 | radGrad.addColorStop(1, "rgba(255,255,255,0)"); | |
95 | ||
96 | for (var i = 0; i < numHighlights; i++) { | |
97 | xforms[i] = (new Transform()).initRandom(); | |
98 | } | |
99 | ||
100 | this.animation = (new yoob.Animation()).init({ | |
101 | 'object': this | |
102 | }); | |
103 | this.animation.start(); | |
104 | }; | |
105 | }; |
15 | 15 | <div id="container"></div> |
16 | 16 | |
17 | 17 | </body> |
18 | <script src="woman-on-film.js"></script> | |
18 | <script src="index.js"></script> | |
19 | 19 | <script> |
20 | 20 | launch('../common-yoob.js-0.11/', 'container'); |
21 | 21 | </script> |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "path.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | ||
13 | var map = yoob.makeCanvas(container, 432, 284); | |
14 | map.style.background = "transparent"; | |
15 | map.style.position = "absolute"; | |
16 | map.style.zIndex = "100"; | |
17 | ||
18 | var quotation_container = yoob.makeSpan(container); | |
19 | quotation_container.style.width = "432px"; | |
20 | quotation_container.style.height = "284px"; | |
21 | quotation_container.style.background = "transparent"; | |
22 | quotation_container.style.position = "absolute"; | |
23 | quotation_container.style.zIndex = "50"; | |
24 | ||
25 | var quotation = yoob.makeSpan(quotation_container); | |
26 | quotation.style.width = "432px"; | |
27 | quotation.style.height = "284px"; | |
28 | quotation.style.background = "transparent"; | |
29 | quotation.style.display = "table-cell"; | |
30 | quotation.style.verticalAlign = "middle"; | |
31 | quotation.style.padding = "2px"; | |
32 | quotation.style.fontSize = "150%"; | |
33 | quotation.style.textShadow = "2px 2px 2px #404040"; | |
34 | quotation.style.color = "white"; | |
35 | quotation.style.lineHeight = "30px"; | |
36 | ||
37 | var canvas = yoob.makeCanvas(container, 432, 284); | |
38 | yoob.makeLineBreak(container); | |
39 | ||
40 | var buttons_container = yoob.makeDiv(container); | |
41 | var buttons = {}; | |
42 | buttons.up = yoob.makeButton(buttons_container, '↑'); | |
43 | ||
44 | yoob.makeLineBreak(buttons_container); | |
45 | buttons.left = yoob.makeButton(buttons_container, '←'); | |
46 | buttons.showMap = yoob.makeButton(buttons_container, 'map'); | |
47 | buttons.right = yoob.makeButton(buttons_container, '→'); | |
48 | yoob.makeLineBreak(buttons_container); | |
49 | buttons.down = yoob.makeButton(buttons_container, '↓'); | |
50 | ||
51 | for (key in buttons) { | |
52 | buttons[key].style.fontSize = '125%'; | |
53 | buttons[key].style.lineHeight = '25px'; | |
54 | } | |
55 | ||
56 | var t = new WomanOnFilm(); | |
57 | t.init(canvas, quotation, map, buttons); | |
58 | } | |
59 | }; | |
60 | document.body.appendChild(elem); | |
61 | } | |
62 | } | |
63 | ||
64 | /* ================================================================== */ | |
65 | ||
66 | function makePathSets() { | |
67 | return [ | |
68 | // first attempt | |
69 | [ | |
70 | new yoob.Path({title:"outline",strokeStyle:"black",lineWidth:"4", | |
71 | points:[49.666666666666664,141.33333333333334,57,94.66666666666667,65,86.66666666666667,81.33333333333333,76,81.66666666666667,72.66666666666667,80,69,75.33333333333333,73.66666666666667,66,79,58.666666666666664,79,54,75.66666666666667,53.333333333333336,65.66666666666667,48,62,44,62,46,65.66666666666667,42,65.33333333333333,40.666666666666664,62.333333333333336,42.666666666666664,59.333333333333336,43,57,41,55,41.666666666666664,54,44.333333333333336,53.333333333333336,50.333333333333336,54.666666666666664,55.333333333333336,49.666666666666664,59,40.666666666666664,65.33333333333333,29.333333333333332,73,14,87.33333333333333,2,92,1.3333333333333333,100.33333333333333,3.6666666666666665,109.33333333333333,7.333333333333333,116.66666666666667,15.333333333333334,122.66666666666667,28.333333333333332,128,41,130.66666666666666,51.333333333333336,134.33333333333334,57.333333333333336,139,58.666666666666664,136.66666666666666,65,132,71.33333333333333,130.33333333333334,73,144.33333333333334,78.33333333333333,143,80.66666666666667,156,92,167.66666666666666,106.33333333333333,179.33333333333334,124,188,141]}), | |
72 | new yoob.Path({title:"face",strokeStyle:"black", | |
73 | points:[74,47,77.66666666666667,51.333333333333336,80.33333333333333,50.333333333333336,82.33333333333333,57.666666666666664,87.33333333333333,63.333333333333336,94.33333333333333,67.66666666666667,103.33333333333333,69.33333333333333,108,66,113.66666666666667,60.333333333333336,116,52,117,50,118,35,115,33.666666666666664,113.66666666666667,34.333333333333336,111.66666666666667,33,106,36.666666666666664,105.33333333333333,34.666666666666664,106.66666666666667,30.666666666666668,101.33333333333333,26.333333333333332,97.33333333333333,18.333333333333332,96.33333333333333,17,93.33333333333333,18,88,21.333333333333332,80.66666666666667,33,80,44.333333333333336,78.33333333333333,43.666666666666664,74,45.333333333333336,74,47.333333333333336]}), | |
74 | new yoob.Path({title:"eyebrow",strokeStyle:"black", | |
75 | points:[86.33333333333333,31.666666666666668,89.66666666666667,29.666666666666668,92.33333333333333,29.666666666666668,95,31.333333333333332,97,32.333333333333336]}), | |
76 | new yoob.Path({title:"mouth outline",strokeStyle:"black", | |
77 | points:[94.33333333333333,58,100.33333333333333,56.333333333333336,103,56.333333333333336,109.33333333333333,56.666666666666664,108,58.666666666666664,107,61,103.33333333333333,62.333333333333336,99.33333333333333,61.333333333333336,95.33333333333333,58.333333333333336]}), | |
78 | new yoob.Path({title:"lips",strokeStyle:"black", | |
79 | points:[95,57.666666666666664,100.66666666666667,58.666666666666664,106.33333333333333,58.666666666666664,109,57.333333333333336]}), | |
80 | new yoob.Path({title:"nose",strokeStyle:"black", | |
81 | points:[104.66666666666667,36.666666666666664,107,44.666666666666664,109,48.666666666666664,107.33333333333333,50.666666666666664,104.33333333333333,52.333333333333336,102,51.333333333333336,98.66666666666667,50,99.33333333333333,47.333333333333336,101.33333333333333,46.333333333333336]}), | |
82 | new yoob.Path({title:"left eye",strokeStyle:"black", | |
83 | points:[88.33333333333333,38,91.33333333333333,36,94.66666666666667,35.666666666666664,98,37.333333333333336,96,39.666666666666664,91.66666666666667,40.333333333333336,89,38.333333333333336]}), | |
84 | new yoob.Path({title:"right eye",strokeStyle:"black", | |
85 | points:[107.66666666666667,38,110.33333333333333,39.333333333333336,114.33333333333333,40,116,38,114.33333333333333,35.333333333333336,110.66666666666667,36,107.66666666666667,38]}), | |
86 | new yoob.Path({title:"inner coat",strokeStyle:"black", | |
87 | points:[63.666666666666664,141.66666666666666,83,77.66666666666667,89.66666666666667,84.66666666666667,97.33333333333333,85.33333333333333,105.66666666666667,81.66666666666667,108.66666666666667,119,113.66666666666667,141.33333333333334]}), | |
88 | new yoob.Path({title:"left neck",strokeStyle:"black", | |
89 | points:[80,69,86,70.66666666666667,82.66666666666667,59]}), | |
90 | new yoob.Path({title:"scarf",strokeStyle:"black", | |
91 | points:[106,81,112,77.33333333333333,113,74,118.66666666666667,70.66666666666667,129.33333333333334,72,120.66666666666667,64.66666666666667,113,64.33333333333333,112,68.66666666666667,104.66666666666667,69.33333333333333,94,71,86.33333333333333,70.66666666666667]}), | |
92 | new yoob.Path({title:"button 1",strokeStyle:"black", | |
93 | points:[116.66666666666667,80.66666666666667,113.33333333333333,81.33333333333333,112.33333333333333,85,114.33333333333333,87.66666666666667,117.66666666666667,88.33333333333333,119.66666666666667,85.66666666666667,120,83,117.66666666666667,81]}), | |
94 | new yoob.Path({title:"button 2",strokeStyle:"black", | |
95 | points:[123,112.66666666666667,119.66666666666667,109.66666666666667,116.33333333333333,110.33333333333333,114.33333333333333,114,115.33333333333333,117.66666666666667,119,119.66666666666667,122.33333333333333,117.66666666666667,123.33333333333333,113.33333333333333]}) | |
96 | ], | |
97 | // 2nd attempt | |
98 | [ | |
99 | new yoob.Path({title:"coat",fillStyle:"#8A6A00",strokeStyle:"black",closed:"true", | |
100 | points:[50,142.16666666666666,50.833333333333336,126.83333333333333,54.833333333333336,100.83333333333333,57.666666666666664,92.66666666666667,64,87.83333333333333,64.83333333333333,84.83333333333333,81.33333333333333,74.66666666666667,83.5,79.66666666666667,90.16666666666667,84.5,98.5,85,112.16666666666667,77.16666666666667,112.83333333333333,74,120.16666666666667,70.5,122.33333333333333,67.5,143.5,78,143.33333333333334,81.16666666666667,154.16666666666666,90.16666666666667,175.16666666666666,116.16666666666667,188.5,141.83333333333334]}), | |
101 | new yoob.Path({title:"inner coat",fillStyle:"grey",closed:"true", | |
102 | points:[62.833333333333336,142.16666666666666,83.5,80,90.16666666666667,84.66666666666667,98.66666666666667,85.33333333333333,103.66666666666667,82.16666666666667,110.16666666666667,126.5,113.16666666666667,141.5]}), | |
103 | new yoob.Path({title:"neck",fillStyle:"#F2C763",closed:"true", | |
104 | points:[83.16666666666667,59.5,82.83333333333333,67.66666666666667,88.16666666666667,70.5,96.16666666666667,70.33333333333333,105.16666666666667,68,111.66666666666667,67.66666666666667,112.5,65.16666666666667,112,62,109,64.83333333333333,104.66666666666667,68.16666666666667,99.5,68.33333333333333,92.83333333333333,67,87.33333333333333,63.833333333333336]}), | |
105 | new yoob.Path({title:"face",fillStyle:"#F5D998",strokeStyle:"black",closed:"true", | |
106 | points:[99,68.33333333333333,104.5,68.16666666666667,108.66666666666667,65.16666666666667,114.16666666666667,59.166666666666664,115.5,51.666666666666664,118,38.833333333333336,117.33333333333333,33.666666666666664,115,22.5,108.5,17.166666666666668,96,16.833333333333332,89.5,19,84,26.166666666666668,79.83333333333333,32.5,79.5,42,77.83333333333333,39,75,38,73,40,73.5,46.333333333333336,76.16666666666667,50.666666666666664,78.5,51.333333333333336,80.83333333333333,49.833333333333336,82.83333333333333,59,87.33333333333333,63.833333333333336,93.16666666666667,67.16666666666667]}), | |
107 | new yoob.Path({title:"hair",fillStyle:"#550000",strokeStyle:"black",lineWidth:"3",closed:"true", | |
108 | points:[59.333333333333336,79,73.5,74.83333333333333,80.33333333333333,66.33333333333333,85.16666666666667,69.33333333333333,80.83333333333333,49.833333333333336,78.66666666666667,51.5,76.16666666666667,50.833333333333336,73.33333333333333,46.166666666666664,73.33333333333333,43.5,77.33333333333333,44.333333333333336,79.66666666666667,41.5,79.83333333333333,32.5,89.5,19,96,16.833333333333332,100,20.333333333333332,101.83333333333333,26.333333333333332,106.33333333333333,29.333333333333332,106.33333333333333,33.166666666666664,104.66666666666667,36,107.5,36.333333333333336,110.5,32.666666666666664,113.83333333333333,33.166666666666664,114.5,35.333333333333336,115.83333333333333,33.166666666666664,117.33333333333333,33.833333333333336,118.16666666666667,38.666666666666664,115.66666666666667,51.833333333333336,114.16666666666667,59.333333333333336,111.83333333333333,61.666666666666664,112.33333333333333,65,118.33333333333333,64.83333333333333,131.5,72,134.83333333333334,70,139.33333333333334,58.833333333333336,136.5,58.166666666666664,131,52,128.83333333333334,42,125.16666666666667,36.166666666666664,121.5,22.5,118.33333333333333,15,110.16666666666667,6.333333333333333,102,3.5,91.16666666666667,1,89,1.1666666666666667,73.83333333333333,11.333333333333334,67.16666666666667,23.5,64,31,59.833333333333336,39.666666666666664,50.833333333333336,53.5,47.833333333333336,54.333333333333336,43.833333333333336,50.166666666666664,42.666666666666664,53,39.666666666666664,54.666666666666664,43,56,43.333333333333336,57.666666666666664,40.333333333333336,60.833333333333336,40.166666666666664,64.16666666666667,45,65.16666666666667,43,61.333333333333336,46.5,60.666666666666664,52.5,64.5,53.833333333333336,71,53.166666666666664,74]}), | |
109 | new yoob.Path({title:"scarf",fillStyle:"red",closed:"true", | |
110 | points:[80,67.33333333333333,82.16666666666667,72.5,81.5,75,83.66666666666667,79.83333333333333,90.33333333333333,84.66666666666667,98.66666666666667,85.33333333333333,112.16666666666667,77.16666666666667,113,74,120.5,70.33333333333333,122.5,67,118.33333333333333,64.83333333333333,113,65,111.83333333333333,67.33333333333333,105.16666666666667,68.16666666666667,96.16666666666667,70.5,88.33333333333333,70.66666666666667,80.66666666666667,66.33333333333333]}), | |
111 | new yoob.Path({title:"left eye",fillStyle:"white",strokeStyle:"black",closed:"true", | |
112 | points:[89.6,38.1,91.2,38.9,93.7,39,95.6,38.5,96.4,37.4,95.1,36,94.1,35.7,91.5,35.8,90.5,36.6]}), | |
113 | new yoob.Path({title:"left pupil",fillStyle:"green",closed:"true", | |
114 | points:[93.5,37.7,93.8,36.8,94.8,36.1,95.8,36.6,96.1,37.5,95.4,38.6,94.5,38.6]}), | |
115 | new yoob.Path({title:"right eye",fillStyle:"white",strokeStyle:"black",closed:"true", | |
116 | points:[107.9,37.5,109.4,38.3,111.9,38.6,113.6,38.1,114.7,36.9,113.7,35.5,112.8,35.3,109.9,35.3,108.7,36.1]}), | |
117 | new yoob.Path({title:"right pupil",fillStyle:"green",closed:"true", | |
118 | points:[112,36.8,112.4,36,113.2,35.5,114.1,36.1,114.3,36.9,113.7,37.7,112.8,37.7]}), | |
119 | new yoob.Path({title:"left eyebrow",strokeStyle:"black", | |
120 | points:[87.66666666666667,30.11111111111111,90,29.11111111111111,92.22222222222223,29.22222222222222,95.22222222222223,30.444444444444443,96.55555555555556,31.666666666666668]}), | |
121 | new yoob.Path({title:"lips",fillStyle:"red",closed:"true", | |
122 | points:[96.22222222222223,57.77777777777778,99.77777777777777,56.111111111111114,106.55555555555556,56.333333333333336,108.22222222222223,57.333333333333336,107.22222222222223,58.55555555555556,105.22222222222223,59.55555555555556,100.55555555555556,59.666666666666664]}), | |
123 | new yoob.Path({title:"lip line",strokeStyle:"black", | |
124 | points:[96.22222222222223,57.888888888888886,103.22222222222223,57.888888888888886,108.11111111111111,57.44444444444444]}), | |
125 | new yoob.Path({title:"nostrils",strokeStyle:"black", | |
126 | points:[99.5,49.7,101.9,49.7,103.1,51.1,104.5,51.4,106.1,50.9,106.6,49.4,107.8,49.3]}), | |
127 | new yoob.Path({title:"septum",strokeStyle:"black", | |
128 | points:[107.3,47.1,106.2,46.4,105.4,43.5,105,39.8]}), | |
129 | new yoob.Path({title:"button 1",fillStyle:"white",closed:"true", | |
130 | points:[114.33333333333333,88.16666666666667,117.33333333333333,88.33333333333333,119.66666666666667,86.16666666666667,119.83333333333333,83.5,117.83333333333333,81.33333333333333,114.83333333333333,81.16666666666667,112.83333333333333,82.66666666666667,112.66666666666667,85.5]}), | |
131 | new yoob.Path({title:"button 2",fillStyle:"white",closed:"true", | |
132 | points:[114.5,116.5,114.33333333333333,113,117,110.5,120,110.66666666666667,122.16666666666667,112.33333333333333,122.83333333333333,115.5,120.83333333333333,118.33333333333333,117.66666666666667,119]}) | |
133 | ], | |
134 | // third attempt | |
135 | [ | |
136 | new yoob.Path({title:"hair 3",fillStyle:"#444444",closed:"true", | |
137 | points:[99.66666666666667,2.6666666666666665,107.5,5.333333333333333,116.16666666666667,12.833333333333334,125.16666666666667,36.5,128.83333333333334,38.166666666666664,134.33333333333334,38.166666666666664,128.83333333333334,39.333333333333336,125.83333333333333,38.666666666666664,129.16666666666666,42.833333333333336,129.66666666666666,47,132.66666666666666,49.166666666666664,137.16666666666666,49.333333333333336,138.83333333333334,52.333333333333336,138.16666666666666,59,137.66666666666666,53.666666666666664,136.66666666666666,52.166666666666664,131.33333333333334,52.5,131.16666666666666,57,133.83333333333334,59.666666666666664,138.66666666666666,59.5,134.66666666666666,66.5,134.16666666666666,69.66666666666667,129.33333333333334,72,120.33333333333333,68.16666666666667,101.33333333333333,71,93.5,4]}), | |
138 | new yoob.Path({title:"hair 2",fillStyle:"#aaaaaa",closed:"true", | |
139 | points:[54.333333333333336,72.83333333333333,51.833333333333336,65.5,47.333333333333336,62.666666666666664,43.166666666666664,61.833333333333336,44.833333333333336,65,41.833333333333336,65.33333333333333,39.5,62,40.333333333333336,60.333333333333336,37.166666666666664,57.166666666666664,40.333333333333336,54,41,48,40.166666666666664,43,44.833333333333336,38.333333333333336,55.166666666666664,36.833333333333336,63.333333333333336,31.333333333333332,67.33333333333333,22.5,72.33333333333333,15.333333333333334,72.5,12.833333333333334,79.66666666666667,5.333333333333333,89.33333333333333,0.5,94.5,0.6666666666666666,102,3.1666666666666665,99.66666666666667,5.5,105,6.333333333333333,114,12.833333333333334,107.66666666666667,11,113.83333333333333,16,110.33333333333333,15.833333333333334,117,24,117,27.5,110.83333333333333,19.666666666666668,101.33333333333333,11,94.33333333333333,9.833333333333334,99.66666666666667,12.166666666666666,109.66666666666667,20.5,111.66666666666667,24,107.83333333333333,22.666666666666668,111.33333333333333,29.333333333333332,104.83333333333333,25,101.66666666666667,16.833333333333332,96.66666666666667,13.666666666666666,65.33333333333333,36,61.333333333333336,73.66666666666667]}), | |
140 | new yoob.Path({title:"hair 1",fillStyle:"grey",closed:"true", | |
141 | points:[82.33333333333333,67.66666666666667,78.5,67.66666666666667,73.83333333333333,74.16666666666667,65.5,78,58,78.66666666666667,53.166666666666664,74.66666666666667,53.833333333333336,70.16666666666667,58.166666666666664,69.83333333333333,58.666666666666664,63.166666666666664,62,58.5,59.666666666666664,58.333333333333336,53.166666666666664,65,47.166666666666664,61.333333333333336,44.166666666666664,60.666666666666664,43.333333333333336,55.5,40.333333333333336,54,44.166666666666664,50.5,48.666666666666664,54.333333333333336,55.5,48.666666666666664,56.333333333333336,45.333333333333336,59.166666666666664,42.333333333333336,59.333333333333336,40.333333333333336,62.5,37.666666666666664,63.833333333333336,31,69.83333333333333,25.5,76.33333333333333,18.833333333333332,75.66666666666667,24,81.83333333333333,18.166666666666668,80.66666666666667,23.166666666666668,92.33333333333333,15,84,11.5,95.5,4.5,89.66666666666667,10.5,96.33333333333333,13,97.5,17]}), | |
142 | new yoob.Path({title:"neck",fillStyle:"#ffccaa",strokeStyle:"black",closed:"true", | |
143 | points:[82.42857142857143,75.85714285714286,81.85714285714286,49.714285714285715,96.14285714285714,64.57142857142857,104.57142857142857,64.57142857142857,112,59,112.14285714285714,69.71428571428571,102,78.57142857142857]}), | |
144 | new yoob.Path({title:"face",fillStyle:"#ffccaa",strokeStyle:"black",closed:"true", | |
145 | points:[83.5,59.333333333333336,90,64.66666666666667,97.5,67.83333333333333,101.5,68.33333333333333,105.16666666666667,67.5,110.66666666666667,63.333333333333336,114.16666666666667,59.166666666666664,116,50.666666666666664,117.33333333333333,47,118.16666666666667,38.833333333333336,117.33333333333333,37,117.33333333333333,34,113.16666666666667,32.5,105,36.5,106.66666666666667,29.5,101.5,25.5,97.66666666666667,17.166666666666668,92.33333333333333,17.166666666666668,80.5,31.5,79.83333333333333,33.333333333333336,79.66666666666667,40.666666666666664,77.16666666666667,44.166666666666664,74,44.166666666666664,74.16666666666667,47.666666666666664,77.5,51.5,80.66666666666667,49.833333333333336]}), | |
146 | new yoob.Path({title:"lips",fillStyle:"#ffaacc",strokeStyle:"black",closed:"true", | |
147 | points:[93.6,57.8,99,56,102.7,55.5,103.7,55.9,104.6,55.6,107.7,56,109.4,56.7,108,57.9,107.3,60,105.4,61.3,100.6,61.4,98.6,60.8,96.7,58.9]}), | |
148 | new yoob.Path({title:"lip line",strokeStyle:"black", | |
149 | points:[94.5,57.9,106.1,58,109.1,56.8]}), | |
150 | new yoob.Path({title:"left eye",fillStyle:"#faaaaa",strokeStyle:"black",closed:"true", | |
151 | points:[87.71428571428571,37.714285714285715,88.28571428571429,36.285714285714285,90.57142857142857,34.857142857142854,95.57142857142857,34.857142857142854,98,37,97.85714285714286,38.857142857142854,95,40.857142857142854,90.85714285714286,41,88.28571428571429,39.142857142857146]}), | |
152 | new yoob.Path({title:"right eye",fillStyle:"#faaaaa",strokeStyle:"black",closed:"true", | |
153 | points:[106.71428571428571,38.57142857142857,109.28571428571429,40.714285714285715,113.42857142857143,41,114.85714285714286,39.142857142857146,115.14285714285714,36.42857142857143,113.71428571428571,35.142857142857146,109,35,107.14285714285714,37]}), | |
154 | new yoob.Path({title:"nose",strokeStyle:"black", | |
155 | points:[104,36.285714285714285,105.57142857142857,45.285714285714285,105.71428571428571,50.57142857142857,107.71428571428571,49,100.57142857142857,49.57142857142857]}), | |
156 | new yoob.Path({title:"coat 1",fillStyle:"brown",strokeStyle:"black",closed:"true", | |
157 | points:[50.4,142,50.8,127.8,53.6,118,54.8,102.6,56,96.4,58,91.6,64.2,87.8,65,84.6,71.8,81.2,82.4,74.2,121.6,69.2,143.2,78,142.2,80.2,150,86.2,173.2,113,188.4,141.2]}), | |
158 | new yoob.Path({title:"coat 2",fillStyle:"brown",strokeStyle:"black",closed:"true", | |
159 | points:[112.6,73.8,118.8,79,143.6,79.4,143,93.4,145.6,113.6,155.8,141.6,189,141.8,175.2,116.6,157.4,94.4,142.6,80.6,144,78.8,117.2,66.8]}), | |
160 | new yoob.Path({title:"vest",fillStyle:"#005500",strokeStyle:"black",closed:"true", | |
161 | points:[62.4,141.8,84.2,76.8,106.6,77,104.6,89,108,118.4,114.2,141.8]}), | |
162 | new yoob.Path({title:"scarf",fillStyle:"blue",strokeStyle:"black",closed:"true", | |
163 | points:[82.42857142857143,77.14285714285714,82.57142857142857,71.85714285714286,80.85714285714286,67.57142857142857,82.42857142857143,63.857142857142854,83.71428571428571,68,86.57142857142857,70.71428571428571,92.85714285714286,71,101.57142857142857,69,112.28571428571429,68.28571428571429,113.28571428571429,67,112.85714285714286,64.28571428571429,119.57142857142857,64.71428571428571,122.71428571428571,70,119.28571428571429,69.57142857142857,112.71428571428571,72.42857142857143,112.28571428571429,76.71428571428571,99.14285714285714,85,90.85714285714286,85.14285714285714]}), | |
164 | new yoob.Path({title:"left pupil",fillStyle:"black",closed:"true", | |
165 | points:[93.11111111111111,37.666666666666664,94.33333333333333,38.44444444444444,96,38.666666666666664,97.66666666666667,37.333333333333336,96.22222222222223,35.77777777777778,94.55555555555556,35.77777777777778]}), | |
166 | new yoob.Path({title:"right pupil",fillStyle:"black",closed:"true", | |
167 | points:[111.44444444444444,37.333333333333336,112.55555555555556,35.111111111111114,114.11111111111111,35.333333333333336,114.88888888888889,36.44444444444444,114.55555555555556,37.666666666666664,113.11111111111111,38.22222222222222]}), | |
168 | new yoob.Path({title:"r.sleeve",strokeStyle:"black", | |
169 | points:[56.2,141.8,62.6,112,74,84.6,81.2,84.2,79.6,80.4,74,78.8,64.6,84.2,62.4,93,73.8,84.8]}), | |
170 | new yoob.Path({title:"button 1",fillStyle:"gainsboro",strokeStyle:"black",closed:"true", | |
171 | points:[111.8,83.2,112.4,86.4,116.8,87.8,120.2,85.2,120,82.8,116,80]}), | |
172 | new yoob.Path({title:"button 2",fillStyle:"gainsboro",strokeStyle:"black",closed:"true", | |
173 | points:[114.4,112.8,114.8,117,117,118.6,120.6,119.2,122.6,117.2,123,112.4,120.4,110.4,117,110]}) | |
174 | ] | |
175 | ]; | |
176 | } | |
177 | ||
178 | /* ================================================================== */ | |
179 | ||
180 | var quotationMapStyle = "rgba(150,100,0,0.66)"; | |
181 | var zQuotationMapStyle = "rgba(0,100,150,0.66)"; | |
182 | var mQuotationMapStyle = "rgba(0,150,100,0.66)"; | |
183 | ||
184 | var clonePathSet = function(pathSet) { | |
185 | var n = []; | |
186 | for (var i = 0; i < pathSet.length; i++) { | |
187 | n.push(pathSet[i].clone()); | |
188 | } | |
189 | return n; | |
190 | }; | |
191 | ||
192 | var mapWithJitter = function(path, jitter) { | |
193 | var r = function() { | |
194 | return Math.random() * jitter - (jitter / 2); | |
195 | }; | |
196 | return path.map(function(x, y) { | |
197 | return [x + r(), y + r()]; | |
198 | }); | |
199 | }; | |
200 | ||
201 | ||
202 | function WomanOnFilm() { | |
203 | var cx; | |
204 | var cy; | |
205 | var hx; | |
206 | var hy; | |
207 | var canvas; | |
208 | var ctx; | |
209 | var map; | |
210 | var mapctx; | |
211 | var quotation; | |
212 | var buttons; | |
213 | var mapShown = false; | |
214 | var count = 0; | |
215 | var transitionFromDx = undefined; | |
216 | var transitionFromDy = undefined; | |
217 | var transitionCount = undefined; | |
218 | ||
219 | var pathSets = makePathSets(); | |
220 | var jPathSets = []; | |
221 | var currentJitter = 0.7; | |
222 | var currentJitterRate = 6; | |
223 | ||
224 | var persPathSet = undefined; | |
225 | ||
226 | var cmap; | |
227 | cmap = [ | |
228 | // row 2 (well actually 1) | |
229 | [ | |
230 | undefined, | |
231 | undefined, | |
232 | { | |
233 | onenter: function() { | |
234 | setQuotation( | |
235 | "I love Los Angeles. I love Hollywood. They're so beautiful. " + | |
236 | "Everything's plastic, but I love plastic. I want to be plastic." | |
237 | ); | |
238 | }, | |
239 | mapstyle: quotationMapStyle | |
240 | }, | |
241 | { | |
242 | // WARHOL 1 | |
243 | draw: function () { | |
244 | drawPaths(ctx, "#aaffff", jPathSets[0], 0, 0); | |
245 | drawPaths(ctx, "#ffaaff", jPathSets[1], hx, 0); | |
246 | drawPaths(ctx, "#ffffaa", jPathSets[2], 0, hy); | |
247 | drawPaths(ctx, "#aaaaaa", jPathSets[0], hx, hy); | |
248 | drawPaths(ctx, "transparent", jPathSets[0], 0, 0, 2, 2, | |
249 | {lineWidth: 2, strokeStyle:"rgba(0,0,0,0.5)"}); | |
250 | } | |
251 | }, | |
252 | { | |
253 | // WARHOL 2 | |
254 | draw: function () { | |
255 | drawPaths(ctx, "#ffffff", jPathSets[0], 0, 0); | |
256 | drawPaths(ctx, "#ffaaaa", jPathSets[1], hx, 0, 1, 1, | |
257 | {lineWidth: 2, strokeStyle:"black"}); | |
258 | drawPaths(ctx, "#aaffaa", jPathSets[2], 0, hy); | |
259 | drawPaths(ctx, "#aaaaff", jPathSets[0], hx, hy); | |
260 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2, | |
261 | {lineWidth: 2, fillStyle:"rgba(0,0,0,0.5)"}); | |
262 | } | |
263 | }, | |
264 | { | |
265 | // WARHOL 3 | |
266 | draw: function () { | |
267 | drawPaths(ctx, "#ff00aa", jPathSets[0], 0, 0); | |
268 | drawPaths(ctx, "#ffaa00", jPathSets[1], hx, 0); | |
269 | drawPaths(ctx, "#aa00ff", jPathSets[2], 0, hy, 1, 1, | |
270 | {lineWidth: 2, strokeStyle:"#ff00ff"}); | |
271 | drawPaths(ctx, "#aaff00", jPathSets[2], hx, hy, 1, 1, | |
272 | {lineWidth: 2, strokeStyle:"#00aaff"}); | |
273 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2); | |
274 | } | |
275 | } | |
276 | ], | |
277 | // row 3 | |
278 | [ | |
279 | { | |
280 | draw: function () { | |
281 | drawPaths(ctx, "white", jPathSets[0], 0, 0, 2, 2); | |
282 | } | |
283 | }, | |
284 | { | |
285 | draw: function () { | |
286 | drawPaths(ctx, "white", jPathSets[1], 0, 0, 2, 2); | |
287 | } | |
288 | }, | |
289 | { | |
290 | draw: function () { | |
291 | drawPaths(ctx, "white", jPathSets[2], 0, 0, 2, 2); | |
292 | } | |
293 | }, | |
294 | undefined, | |
295 | undefined, | |
296 | { | |
297 | // merge node | |
298 | onenter: function() { | |
299 | setQuotation( | |
300 | "Right when I was being shot and ever since, I knew that I was watching " + | |
301 | "television. The channels switch, but it's all television." | |
302 | ); | |
303 | }, | |
304 | mapstyle: quotationMapStyle | |
305 | }, | |
306 | { | |
307 | // TV 1 | |
308 | draw: function () { | |
309 | ctx.fillStyle = "#d0d0d0"; | |
310 | ctx.fillRect(0, 0, canvas.width, canvas.height / 2); | |
311 | ctx.fillStyle = "#404040"; // bah | |
312 | ctx.fillRect(0, canvas.height / 2, canvas.width, canvas.height / 2); | |
313 | ||
314 | // sun | |
315 | ctx.beginPath(); | |
316 | ctx.arc(canvas.width * 0.17, canvas.height * 0.25, | |
317 | canvas.height * 0.10, 0, Math.PI * 2, false); | |
318 | ctx.fillStyle = "#f7f7f7"; | |
319 | ctx.fill(); | |
320 | ctx.lineWidth = 4; | |
321 | ctx.strokeStyle = "#ffffff"; | |
322 | ctx.stroke(); | |
323 | ||
324 | // cactus | |
325 | ctx.beginPath(); | |
326 | var cacx = 0.85; | |
327 | var cacxl = cacx - 0.045; | |
328 | var cacxr = cacx + 0.040; | |
329 | ||
330 | ctx.moveTo(canvas.width * cacx, canvas.height * 0.75); | |
331 | ctx.lineTo(canvas.width * cacx, canvas.height * 0.25); | |
332 | ||
333 | ctx.moveTo(canvas.width * cacx, canvas.height * 0.45); | |
334 | ctx.lineTo(canvas.width * cacxl, canvas.height * 0.45); | |
335 | ctx.lineTo(canvas.width * cacxl, canvas.height * 0.33); | |
336 | ||
337 | ctx.moveTo(canvas.width * cacx, canvas.height * 0.55); | |
338 | ctx.lineTo(canvas.width * cacxr, canvas.height * 0.55); | |
339 | ctx.lineTo(canvas.width * cacxr, canvas.height * 0.45); | |
340 | ||
341 | ctx.lineWidth = 15; | |
342 | ctx.lineCap = "round"; | |
343 | ctx.strokeStyle = "#101010"; | |
344 | ctx.stroke(); | |
345 | ||
346 | drawPaths(ctx, "transparent", jPathSets[0], 0, 0, 2, 2, | |
347 | function(p) { | |
348 | if (p.title === 'outline') { | |
349 | return {strokeStyle:"black",fillStyle:"#808080", | |
350 | lineWidth:4}; | |
351 | } | |
352 | if (p.title === 'left eye' || p.title === 'right eye') { | |
353 | return {strokeStyle:"black",fillStyle:"#959595", | |
354 | lineWidth:0.5}; | |
355 | } | |
356 | return true; | |
357 | }); | |
358 | } | |
359 | }, | |
360 | { | |
361 | // TV 2 | |
362 | draw: function () { | |
363 | ctx.fillStyle = "white"; | |
364 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
365 | ctx.strokeStyle = "black"; | |
366 | ctx.lineWidth = 2; | |
367 | var x1 = 0; | |
368 | var y1 = 0; | |
369 | var x2 = canvas.width; | |
370 | var y2 = canvas.height; | |
371 | var cx = canvas.width * 0.75; | |
372 | var cy = canvas.height * 0.25; | |
373 | var c = 128; | |
374 | var f = 0.25; | |
375 | for (var i = 0; i < 10; i++) { | |
376 | ctx.fillStyle = "rgba(" + c + ",0,0,1.0)"; | |
377 | if (i === 9) ctx.fillStyle = "#222222"; | |
378 | ctx.fillRect(x1, y1, x2-x1, y2-y1); | |
379 | ctx.strokeRect(x1, y1, x2-x1, y2-y1); | |
380 | var nx1 = x1 + Math.abs(cx-x1) * f; | |
381 | var nx2 = x2 - Math.abs(cx-x2) * f; | |
382 | var ny1 = y1 + Math.abs(cy-y1) * f; | |
383 | var ny2 = y2 - Math.abs(cy-y2) * f; | |
384 | ||
385 | if (i < 9) { | |
386 | ctx.beginPath(); | |
387 | ctx.moveTo(x1, y1); ctx.lineTo(nx1, ny1); | |
388 | ctx.moveTo(x2, y1); ctx.lineTo(nx2, ny1); | |
389 | ctx.moveTo(x1, y2); ctx.lineTo(nx1, ny2); | |
390 | ctx.moveTo(x2, y2); ctx.lineTo(nx2, ny2); | |
391 | ctx.stroke(); | |
392 | } | |
393 | ||
394 | c = Math.floor(c * 0.75); | |
395 | x1 = nx1; y1 = ny1; x2 = nx2; y2 = ny2; | |
396 | } | |
397 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2); | |
398 | } | |
399 | }, | |
400 | { | |
401 | // TV 3 | |
402 | draw: function () { | |
403 | ctx.fillStyle = "#000000"; | |
404 | ctx.fillRect(0, 0, canvas.width, canvas.height / 2); | |
405 | ctx.fillStyle = "#000060"; | |
406 | ctx.fillRect(0, canvas.height / 2, canvas.width, canvas.height / 2); | |
407 | ||
408 | // moon | |
409 | var moonRadius = canvas.height * 0.08; | |
410 | var moonX = canvas.width * 0.80; | |
411 | ctx.beginPath(); | |
412 | ctx.arc(moonX, canvas.height * 0.25, | |
413 | moonRadius, 0, Math.PI * 2, false); | |
414 | ctx.fillStyle = "#b0b090"; | |
415 | ctx.fill(); | |
416 | ||
417 | // reflection | |
418 | ctx.strokeStyle = "#7070ff"; | |
419 | ctx.lineWidth = 2; | |
420 | var lines = [[0.5, 0.70], [1.0, 0.75], [0.5, 0.80]]; | |
421 | for (var i = 0; i < lines.length; i++) { | |
422 | var r = moonRadius * lines[i][0] + 3 * Math.cos(count / 10.0); | |
423 | var y = canvas.height * lines[i][1] + 3 * Math.sin((count + (i * 10)) / 10.0); | |
424 | ctx.beginPath(); | |
425 | ctx.moveTo(moonX - r, y); | |
426 | ctx.lineTo(moonX + r, y); | |
427 | ctx.stroke(); | |
428 | } | |
429 | ||
430 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2); | |
431 | } | |
432 | }, | |
433 | { | |
434 | onenter: function() { | |
435 | setQuotation( | |
436 | "... when you do something exactly wrong, you always turn up something." | |
437 | ); | |
438 | }, | |
439 | mapstyle: quotationMapStyle | |
440 | }, | |
441 | { | |
442 | draw: function () { | |
443 | // COMPOSITE WOMAN | |
444 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
445 | drawPaths(ctx, "transparent", jPathSets[0], 0, 0, 2, 2, | |
446 | {lineWidth: 2, fillStyle:"rgba(0,0,0,0.2)"}); | |
447 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2, | |
448 | {lineWidth: 2, fillStyle:"rgba(0,0,0,0.2)"}); | |
449 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2, | |
450 | {lineWidth: 2, fillStyle:"rgba(0,0,0,0.2)"}); | |
451 | } | |
452 | }, | |
453 | { | |
454 | draw: function () { | |
455 | // RGB NEON | |
456 | drawPaths(ctx, "white", jPathSets[0], 0, 0, 2, 2, | |
457 | {lineWidth: 1, strokeStyle:"rgba(255,0,0,0.8)"}); | |
458 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2, | |
459 | {lineWidth: 1, strokeStyle:"rgba(0,255,0,0.8)"}); | |
460 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2, | |
461 | {lineWidth: 1, strokeStyle:"rgba(0,0,255,0.8)"}); | |
462 | } | |
463 | }, | |
464 | { | |
465 | draw: function () { | |
466 | // STARS | |
467 | if (count % 4 !== 0) return; | |
468 | foreachPaths(ctx, "black", jPathSets[1], 0, 0, 2, 2, | |
469 | function(path, x, y) { | |
470 | ctx.beginPath(); | |
471 | ctx.fillStyle = "yellow"; | |
472 | ctx.strokeStyle = "white"; | |
473 | var r = Math.random() * 2; | |
474 | if (Math.random() > 0.5) { | |
475 | r *= 1.5; | |
476 | //ctx.fillStyle = "white"; | |
477 | //ctx.strokeStyle = "#aaaaaa"; | |
478 | } | |
479 | ctx.arc(x, y, r, 0, Math.PI * 2, false); | |
480 | ctx.fill(); | |
481 | ctx.lineWidth = 0.5; | |
482 | ctx.stroke(); | |
483 | } | |
484 | ); | |
485 | } | |
486 | }, | |
487 | { | |
488 | onenter: function() { | |
489 | setQuotation( | |
490 | "[...] one anxiously awaits a movie in which her harmony won't be drowned out by the filmmaker's noodling.", | |
491 | 'http://www.metroactive.com/papers/metro/09.19.96/grace-heart-9638.html' | |
492 | ); | |
493 | }, | |
494 | draw: function () { | |
495 | ctx.fillStyle = "black"; | |
496 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
497 | }, | |
498 | mapstyle: mQuotationMapStyle | |
499 | } | |
500 | ], | |
501 | // row 4 | |
502 | [ | |
503 | { | |
504 | draw: function () { | |
505 | // SEQUENCE OF TRACINGS | |
506 | drawPaths(ctx, "white", jPathSets[0], 0, 0, 1, 1, | |
507 | function(p) { | |
508 | return p.title === 'outline'; | |
509 | }); | |
510 | drawPaths(ctx, "white", jPathSets[0], hx, 0, 1, 1, | |
511 | function(p) { | |
512 | return p.title === 'outline' | |
513 | || p.title === 'inner coat' | |
514 | || p.title === 'scarf'; | |
515 | }); | |
516 | drawPaths(ctx, "white", jPathSets[0], 0, hy, 1, 1, | |
517 | function(p) { | |
518 | return p.title === 'outline' | |
519 | || p.title === 'inner coat' | |
520 | || p.title === 'left neck' | |
521 | || p.title === 'scarf' | |
522 | || p.title === 'face'; | |
523 | }); | |
524 | drawPaths(ctx, "white", jPathSets[0], hx, hy, 1, 1); | |
525 | } | |
526 | }, | |
527 | undefined, | |
528 | { | |
529 | onenter: function() { | |
530 | setQuotation( | |
531 | "People sometimes say that the way things happen in movies is unreal, " + | |
532 | "but actually it's the way things happen in life that's unreal." | |
533 | ); | |
534 | }, | |
535 | mapstyle: quotationMapStyle | |
536 | }, | |
537 | { | |
538 | draw: function () { | |
539 | drawPaths(ctx, "#00aa00", jPathSets[0], 0, 0, 1, 1, | |
540 | function(p) { | |
541 | if (p.title === 'outline') { | |
542 | return {fillStyle:"#aa00aa"}; | |
543 | } else { | |
544 | return {lineWidth: 2, strokeStyle:"#000000"}; | |
545 | } | |
546 | }); | |
547 | drawPaths(ctx, "#aa00aa", jPathSets[0], hx, 0, 1, 1, | |
548 | function(p) { | |
549 | if (p.title === 'outline') { | |
550 | return {fillStyle:"#0000aa"}; | |
551 | } else { | |
552 | return {lineWidth: 2, strokeStyle:"#000000"}; | |
553 | } | |
554 | }); | |
555 | drawPaths(ctx, "#0000aa", jPathSets[0], 0, hy, 1, 1, | |
556 | function(p) { | |
557 | if (p.title === 'outline') { | |
558 | return {fillStyle:"#00aa00"}; | |
559 | } else { | |
560 | return {lineWidth: 2, strokeStyle:"#000000"}; | |
561 | } | |
562 | }); | |
563 | drawPaths(ctx, "#00aa00", jPathSets[0], hx, hy, 1, 1, | |
564 | function(p) { | |
565 | if (p.title === 'outline') { | |
566 | return {fillStyle:"#0000aa", | |
567 | lineWidth: 2, strokeStyle:"#ffffff"}; | |
568 | } else { | |
569 | return {lineWidth: 2, strokeStyle:"#ffffff"}; | |
570 | } | |
571 | }); | |
572 | } | |
573 | }, | |
574 | { | |
575 | draw: function () { | |
576 | // EIGHT ELVISES | |
577 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
578 | var dx = 50; | |
579 | var dy = 71; | |
580 | var s = 1.25; | |
581 | var o = {strokeStyle: "black", lineWidth: 1}; | |
582 | drawPaths(ctx, "transparent", jPathSets[1], 0-dx, dy, s, s, o) | |
583 | drawPaths(ctx, "transparent", jPathSets[1], (hx*0.25)-dx, dy+4, s, s, o); | |
584 | drawPaths(ctx, "transparent", jPathSets[1], (hx*0.50)-dx, dy+8, s, s, o); | |
585 | drawPaths(ctx, "transparent", jPathSets[1], (hx*0.75)-dx, dy, s, s, o); | |
586 | drawPaths(ctx, "transparent", jPathSets[1], (hx*1.00)-dx, dy-4, s, s, o); | |
587 | drawPaths(ctx, "transparent", jPathSets[1], (hx*1.12)-dx, dy, s, s, o); | |
588 | drawPaths(ctx, "transparent", jPathSets[1], (hx*1.20)-dx, dy-4, s, s, o); | |
589 | drawPaths(ctx, "transparent", jPathSets[1], (hx*1.25)-dx, dy-4, s, s, o); | |
590 | } | |
591 | }, | |
592 | { | |
593 | // LOTS OF COLOUR | |
594 | draw: function () { | |
595 | drawPaths(ctx, "#bbbbbb", jPathSets[2], 0, 0, 1, 1, | |
596 | function(p) { | |
597 | if (p.title === 'coat 1' || p.title === 'coat 2') { | |
598 | return {fillStyle:"#004444", strokeStyle:"black"}; | |
599 | } | |
600 | if (p.title === 'hair 1') { | |
601 | return {fillStyle:"#800000"}; | |
602 | } | |
603 | if (p.title === 'hair 2') { | |
604 | return {fillStyle:"#ff0000"}; | |
605 | } | |
606 | if (p.title === 'hair 3') { | |
607 | return {fillStyle:"#440000"}; | |
608 | } | |
609 | if (p.title === 'scarf') { | |
610 | return {fillStyle:"#d0d000", | |
611 | strokeStyle:"black", | |
612 | lineWitdh:2}; | |
613 | } | |
614 | if (p.title === 'vest') { | |
615 | return {fillStyle:"white"}; | |
616 | } | |
617 | }); | |
618 | drawPaths(ctx, "white", jPathSets[2], hx, 0, 1, 1, | |
619 | function(p) { | |
620 | if (p.title === 'coat 1' || p.title === 'coat 2') { | |
621 | return {fillStyle:"#440044", strokeStyle:"black"}; | |
622 | } | |
623 | if (p.title === 'hair 1') { | |
624 | return {fillStyle:"#008000"}; | |
625 | } | |
626 | if (p.title === 'hair 2') { | |
627 | return {fillStyle:"#00ff00"}; | |
628 | } | |
629 | if (p.title === 'hair 3') { | |
630 | return {fillStyle:"#004400"}; | |
631 | } | |
632 | if (p.title === 'scarf') { | |
633 | return {fillStyle:"#009999", | |
634 | strokeStyle:"black", | |
635 | lineWitdh:2}; | |
636 | } | |
637 | if (p.title === 'vest') { | |
638 | return {fillStyle:"black"}; | |
639 | } | |
640 | }); | |
641 | drawPaths(ctx, "white", jPathSets[2], 0, hy, 1, 1, | |
642 | function(p) { | |
643 | if (p.title === 'coat 1' || p.title === 'coat 2') { | |
644 | return {fillStyle:"#444400", strokeStyle:"black"}; | |
645 | } | |
646 | if (p.title === 'hair 1') { | |
647 | return {fillStyle:"#000080"}; | |
648 | } | |
649 | if (p.title === 'hair 2') { | |
650 | return {fillStyle:"#0000ff"}; | |
651 | } | |
652 | if (p.title === 'hair 3') { | |
653 | return {fillStyle:"#000044"}; | |
654 | } | |
655 | if (p.title === 'scarf') { | |
656 | return {fillStyle:"black", | |
657 | strokeStyle:"black", | |
658 | lineWitdh:2}; | |
659 | } | |
660 | if (p.title === 'vest') { | |
661 | return {fillStyle:"#808080"}; | |
662 | } | |
663 | }); | |
664 | drawPaths(ctx, "#bbbbbb", jPathSets[2], hx, hy, 1, 1); | |
665 | } | |
666 | }, | |
667 | undefined, | |
668 | undefined, | |
669 | undefined, | |
670 | undefined, | |
671 | { | |
672 | // "RONALD MC-WOMAN-ON-FILM" | |
673 | onenter: function () { | |
674 | currentJitter = 1.25; | |
675 | currentJitterRate = 3; | |
676 | quotation.innerHTML = ''; | |
677 | quotation.style.background = 'transparent'; | |
678 | }, | |
679 | draw: function () { | |
680 | drawPaths(ctx, "yellow", pathSets[0], 0, 0, 2, 2, | |
681 | {strokeStyle: "orange", lineWidth: 16}); | |
682 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
683 | {strokeStyle: "white", lineWidth: 14}); | |
684 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
685 | {strokeStyle: "red", lineWidth: 12}); | |
686 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
687 | {strokeStyle: "white", lineWidth: 10}); | |
688 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
689 | {strokeStyle: "orange", lineWidth: 8}); | |
690 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
691 | {strokeStyle: "white", lineWidth: 7}); | |
692 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
693 | {strokeStyle: "yellow", lineWidth: 6}); | |
694 | drawPaths(ctx, "transparent", jPathSets[0], 0, 0, 2, 2, | |
695 | {strokeStyle: "orange", lineWidth: 4}); | |
696 | drawPaths(ctx, "transparent", jPathSets[0], 0, 0, 2, 2, | |
697 | {strokeStyle: "red", lineWidth: 2}); | |
698 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
699 | {strokeStyle: "black", lineWidth: 1}); | |
700 | } | |
701 | }, | |
702 | { | |
703 | // ANGEL / DEVIL | |
704 | draw: function () { | |
705 | ctx.fillStyle = "red"; | |
706 | ctx.fillRect(0, 0, canvas.width / 2, canvas.height); | |
707 | ctx.fillStyle = "white"; | |
708 | ctx.fillRect(canvas.width / 2, 0, canvas.width / 2, canvas.height); | |
709 | ||
710 | drawPaths(ctx, "red", jPathSets[1], -10, hy * 0.25, 1, 1, | |
711 | {fillStyle: "white", strokeStyle: "white", lineWidth: 2}); | |
712 | ||
713 | ctx.beginPath(); | |
714 | var bx = 65; | |
715 | var by = 20; | |
716 | var bw = 40; | |
717 | ctx.moveTo(bx, by); | |
718 | ctx.bezierCurveTo(bx, by - 10, bx + bw, by - 10, bx + bw, by); | |
719 | ctx.bezierCurveTo(bx + bw, by + 10, bx, by + 10, bx, by); | |
720 | ctx.lineWidth = 3; | |
721 | ctx.strokeStyle = "yellow"; | |
722 | ctx.stroke(); | |
723 | ||
724 | drawPaths(ctx, "white", jPathSets[1], hx, hy * 0.25, 1, 1, | |
725 | {fillStyle: "red", strokeStyle: "red", lineWidth: 2}); | |
726 | ||
727 | ctx.beginPath(); | |
728 | var bx = hx + 70; | |
729 | var by = 20; | |
730 | var bw = 50; | |
731 | ctx.moveTo(bx, by); | |
732 | ctx.bezierCurveTo(bx, by + 30, bx + bw, by + 30, bx + bw, by); | |
733 | ctx.bezierCurveTo(bx + bw, by + 40, bx, by + 40, bx, by); | |
734 | ctx.fillStyle = "red"; | |
735 | ctx.fill(); | |
736 | ||
737 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2, | |
738 | {fillStyle: "black", strokeStyle: "white", lineWidth: 2}); | |
739 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2, | |
740 | {strokeStyle: "red", lineWidth: 0.5}); | |
741 | } | |
742 | }, | |
743 | { | |
744 | // MOVING BARS | |
745 | draw: function () { | |
746 | ctx.fillStyle = "green"; | |
747 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
748 | var numBars = 10; | |
749 | var barWidth = Math.ceil(canvas.width / numBars); | |
750 | for (var i = 0; i < numBars + 2; i++) { | |
751 | ctx.fillStyle = i % 2 === 0 ? "black": "white"; | |
752 | var offs = (count + 40) % (barWidth * 2); | |
753 | ctx.fillRect(i * barWidth - offs, 0, barWidth, canvas.height); | |
754 | } | |
755 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2); | |
756 | for (var i = 0; i < numBars + 4; i++) { | |
757 | ctx.fillStyle = i % 4 === 0 ? "black": "transparent"; | |
758 | var offs = (count + 40) % (barWidth * 4); | |
759 | ctx.fillRect(i * barWidth - offs, 0, barWidth, canvas.height); | |
760 | } | |
761 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2, | |
762 | function(p) { | |
763 | if (p.title === 'left eye' || | |
764 | p.title === 'right eye' || | |
765 | p.title === 'nose' || | |
766 | p.title === 'lips' || | |
767 | p.title === 'lip line') | |
768 | return {strokeStyle:"#400040", fillStyle:"#faaaaa", | |
769 | lineWidth:0.5}; | |
770 | if (p.title === 'left pupil' || | |
771 | p.title === 'right pupil' || | |
772 | p.title === 'button 1' || p.title === 'button 2') | |
773 | return true; | |
774 | return false; | |
775 | }); | |
776 | } | |
777 | } | |
778 | ], | |
779 | [ | |
780 | // row 5 | |
781 | undefined, | |
782 | undefined, | |
783 | undefined, | |
784 | undefined, | |
785 | undefined, | |
786 | undefined, | |
787 | undefined, | |
788 | undefined, | |
789 | undefined, | |
790 | undefined, | |
791 | undefined, | |
792 | { | |
793 | onenter: function() { | |
794 | setQuotation( | |
795 | "Now there was a Law in the Pyramid, tried and healthful, " + | |
796 | "which held that no male should have freedom to adventure " + | |
797 | "into the Night Land, before the age of twenty-two; " + | |
798 | "<em>and no female ever</em>.", | |
799 | "http://en.wikipedia.org/wiki/The_Night_Land" | |
800 | ); | |
801 | }, | |
802 | mapstyle: zQuotationMapStyle | |
803 | } | |
804 | ], | |
805 | [ | |
806 | // row 6 | |
807 | undefined, | |
808 | undefined, | |
809 | undefined, | |
810 | undefined, | |
811 | undefined, | |
812 | undefined, | |
813 | undefined, | |
814 | undefined, | |
815 | undefined, | |
816 | { | |
817 | onenter: function() { | |
818 | setQuotation( | |
819 | "And pride had we taken of ourselves to perceive those " + | |
820 | "monsters which had most of ugliness and horror to commend " + | |
821 | "them; for, thereby did we stand to have won the game of " + | |
822 | "watching, until such time as a more fearsome Brute be " + | |
823 | "discovered.", | |
824 | "http://en.wikipedia.org/wiki/The_Night_Land" | |
825 | ); | |
826 | }, | |
827 | mapstyle: zQuotationMapStyle | |
828 | }, | |
829 | { | |
830 | // HIGH JITTER 2 | |
831 | onenter: function () { | |
832 | currentJitter = 0; | |
833 | quotation.innerHTML = ''; | |
834 | quotation.style.background = 'transparent'; | |
835 | }, | |
836 | draw: function () { | |
837 | drawPaths(ctx, "gainsboro", jPathSets[1], 0, 0, 2, 2); | |
838 | if (currentJitter < 20) | |
839 | currentJitter += 0.025; | |
840 | } | |
841 | }, | |
842 | { | |
843 | // HIGH JITTER 1 | |
844 | onenter: function () { | |
845 | currentJitter = 4; | |
846 | quotation.innerHTML = ''; | |
847 | quotation.style.background = 'transparent'; | |
848 | }, | |
849 | draw: function () { | |
850 | drawPaths(ctx, "#303030", jPathSets[0], 0, 0, 2, 2); | |
851 | } | |
852 | } | |
853 | ], | |
854 | [ | |
855 | // row 7 (actually 6) | |
856 | undefined, | |
857 | undefined, | |
858 | undefined, | |
859 | undefined, | |
860 | undefined, | |
861 | undefined, | |
862 | undefined, | |
863 | undefined, | |
864 | undefined, | |
865 | { | |
866 | // HIGH JITTER 3 | |
867 | onenter: function () { | |
868 | persPathSet = clonePathSet(pathSets[2]); | |
869 | quotation.innerHTML = ''; | |
870 | quotation.style.background = 'transparent'; | |
871 | }, | |
872 | draw: function () { | |
873 | //var color = "rgba(" + (count % 256) + ",0,0,1.0)"; | |
874 | drawPaths(ctx, "white", persPathSet, 0, 0, 2, 2); | |
875 | // TODO this could be made more efficient | |
876 | // by in-place rewriting of points, but... whateva | |
877 | var newPathSet = []; | |
878 | for (var i = 0; i < persPathSet.length; i++) { | |
879 | newPathSet.push(mapWithJitter(persPathSet[i], 1)); | |
880 | } | |
881 | persPathSet = newPathSet; | |
882 | } | |
883 | } | |
884 | ], | |
885 | [ | |
886 | // row 8 (actually 7) | |
887 | undefined, | |
888 | undefined, | |
889 | undefined, | |
890 | undefined, | |
891 | undefined, | |
892 | undefined, | |
893 | undefined, | |
894 | undefined, | |
895 | undefined, | |
896 | { | |
897 | onenter: function() { | |
898 | setQuotation( | |
899 | "And so went the play; yet with ever, it doth " + | |
900 | "seem to me now, something of a half-known shudder to the " + | |
901 | "heart, and a child's rejoicing unknowingly in that safety " + | |
902 | "which had power to make light the seeming of such matters.", | |
903 | "http://en.wikipedia.org/wiki/The_Night_Land" | |
904 | ); | |
905 | }, | |
906 | mapstyle: zQuotationMapStyle | |
907 | } | |
908 | ] | |
909 | ]; | |
910 | ||
911 | this.getCfg = function(cx, cy) { | |
912 | var g = cmap[cy]; | |
913 | if (g === undefined) return undefined; | |
914 | return g[cx]; | |
915 | ||
916 | }; | |
917 | ||
918 | this.reJitterPaths = function() { | |
919 | for (var i = 0; i <= 2; i++) { | |
920 | var newPaths = []; | |
921 | for (var j = 0; j < pathSets[i].length; j++) { | |
922 | newPaths.push(mapWithJitter(pathSets[i][j], currentJitter)); | |
923 | } | |
924 | jPathSets[i] = newPaths; | |
925 | } | |
926 | }; | |
927 | ||
928 | this.showMap = function(setting) { | |
929 | if (setting === undefined) { | |
930 | mapShown = !mapShown; | |
931 | } else { | |
932 | mapShown = setting; | |
933 | } | |
934 | if (mapShown) { | |
935 | map.style.display = "inline"; | |
936 | quotation.style.display = "none"; | |
937 | } else { | |
938 | map.style.display = "none"; | |
939 | quotation.style.display = "table-cell"; | |
940 | } | |
941 | }; | |
942 | ||
943 | this.drawMap = function() { | |
944 | mapctx.clearRect(0, 0, map.width, map.height); | |
945 | var mapWidth = 14; | |
946 | var mapHeight = cmap.length; | |
947 | var sizeX = 25; | |
948 | var sizeY = 25; | |
949 | ||
950 | var offX = (map.width - (sizeX * mapWidth)) / 2 + sizeX * 0.2; | |
951 | var offY = (map.height - (sizeY * mapHeight)) / 2 + sizeY * 0.2; | |
952 | ||
953 | for (var y = 0; y <= mapHeight; y++) { | |
954 | var g = cmap[y]; | |
955 | if (g !== undefined) { | |
956 | for (var x = 0; x <= mapWidth; x++) { | |
957 | var style = "transparent"; | |
958 | if (g[x] !== undefined) { | |
959 | style = g[x].mapstyle || "rgba(0,0,0,0.5)"; | |
960 | if (x == cx && y == cy) { | |
961 | style = "rgba(255,0,0,0.5)"; | |
962 | } | |
963 | mapctx.fillStyle = style; | |
964 | mapctx.fillRect(x * sizeX + offX, y * sizeY + offY, | |
965 | sizeX * 0.8, sizeY * 0.8); | |
966 | mapctx.lineWidth = 1; | |
967 | mapctx.strokeStyle = "rgba(255,255,255,0.5)"; | |
968 | mapctx.strokeRect(x * sizeX + offX, y * sizeY + offY, | |
969 | sizeX * 0.8, sizeY * 0.8); | |
970 | } | |
971 | } | |
972 | } | |
973 | } | |
974 | }; | |
975 | ||
976 | this.enableArrowButtons = function() { | |
977 | buttons.up.disabled = (this.getCfg(cx, cy-1) === undefined); | |
978 | buttons.down.disabled = (this.getCfg(cx, cy+1) === undefined); | |
979 | buttons.left.disabled = (this.getCfg(cx-1, cy) === undefined); | |
980 | buttons.right.disabled = (this.getCfg(cx+1, cy) === undefined); | |
981 | this.showMap(false); | |
982 | }; | |
983 | ||
984 | this.move = function(dx, dy) { | |
985 | if (this.getCfg(cx+dx, cy+dy) === undefined) return; | |
986 | cx += dx; | |
987 | cy += dy; | |
988 | this.enableArrowButtons(); | |
989 | transitionFromDx = dx; | |
990 | transitionFromDy = dy; | |
991 | transitionCount = 0; | |
992 | count = 0; | |
993 | currentJitter = 0.7; | |
994 | currentJitterRate = 6; | |
995 | ||
996 | var cfg = this.getCfg(cx, cy); | |
997 | if (cfg.onenter !== undefined) { | |
998 | cfg.onenter(); | |
999 | } else { | |
1000 | quotation.innerHTML = ''; | |
1001 | quotation.style.background = 'transparent'; | |
1002 | } | |
1003 | if (cfg.draw === undefined) { | |
1004 | ctx.fillStyle = "black"; | |
1005 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
1006 | } else { | |
1007 | cfg.draw(); | |
1008 | } | |
1009 | }; | |
1010 | ||
1011 | var drawPaths = function(ctx, style, paths, x, y, sx, sy, where) { | |
1012 | ctx.save(); | |
1013 | ctx.translate(x, y); | |
1014 | ctx.scale(sx || 1, sy || 1); | |
1015 | ctx.fillStyle = style; | |
1016 | ctx.fillRect(0, 0, hx, hy); | |
1017 | for (var p = 0; p < paths.length; p++) { | |
1018 | var path = paths[p]; | |
1019 | var override = where; | |
1020 | if (typeof override === 'function') { | |
1021 | override = override(path); | |
1022 | } | |
1023 | if (override === false) continue; | |
1024 | if (typeof override === 'object') { | |
1025 | path.drawOverride(ctx, override); | |
1026 | } else { | |
1027 | path.draw(ctx, {lineWidth: 0.5}); | |
1028 | } | |
1029 | } | |
1030 | ctx.restore(); | |
1031 | }; | |
1032 | ||
1033 | var foreachPaths = function(ctx, style, paths, x, y, sx, sy, callback) { | |
1034 | ctx.save(); | |
1035 | ctx.translate(x, y); | |
1036 | ctx.scale(sx || 1, sy || 1); | |
1037 | ctx.fillStyle = style; | |
1038 | ctx.fillRect(0, 0, hx, hy); | |
1039 | for (var p = 0; p < paths.length; p++) { | |
1040 | var path = paths[p]; | |
1041 | for (var i = 0; i < path.points.length; i += 2) { | |
1042 | callback(path, path.points[i], path.points[i+1]) | |
1043 | } | |
1044 | } | |
1045 | ctx.restore(); | |
1046 | }; | |
1047 | ||
1048 | var setQuotation = function(text, link) { | |
1049 | link = link || "http://en.wikipedia.org/wiki/Andy_Warhol"; | |
1050 | quotation.innerHTML = '<a href="' + link + '">«' + text + '»</a>'; | |
1051 | quotation.style.background = 'black'; | |
1052 | }; | |
1053 | ||
1054 | this.init = function(c, q, m, b) { | |
1055 | canvas = c; | |
1056 | ctx = canvas.getContext('2d'); | |
1057 | quotation = q; | |
1058 | quotation.innerHTML = ''; | |
1059 | map = m; | |
1060 | buttons = b; | |
1061 | ||
1062 | var $this = this; | |
1063 | ||
1064 | buttons.up.onclick = function() { $this.move(0,-1); }; | |
1065 | buttons.down.onclick = function() { $this.move(0,1); }; | |
1066 | buttons.left.onclick = function() { $this.move(-1,0); }; | |
1067 | buttons.right.onclick = function() { $this.move(1,0); }; | |
1068 | buttons.showMap.onclick = function() { $this.showMap(); }; | |
1069 | ||
1070 | mapctx = map.getContext('2d'); | |
1071 | cx = 0; | |
1072 | cy = 1; | |
1073 | hx = canvas.width / 2; | |
1074 | hy = canvas.height / 2; | |
1075 | this.enableArrowButtons(); | |
1076 | currentJitter = 0.7; | |
1077 | this.reJitterPaths(); | |
1078 | var intervalId = setInterval(function() { | |
1079 | var cfg = $this.getCfg(cx, cy); | |
1080 | if (cfg === undefined) { | |
1081 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
1082 | } else { | |
1083 | if (count % currentJitterRate === 0) { | |
1084 | $this.reJitterPaths(); | |
1085 | } | |
1086 | if (cfg.draw !== undefined) { | |
1087 | cfg.draw(); | |
1088 | } | |
1089 | $this.drawMap(); | |
1090 | count++; | |
1091 | } | |
1092 | }, 16); | |
1093 | }; | |
1094 | }; |
0 | function launch(prefix, containerId) { | |
1 | var deps = [ | |
2 | "element-factory.js", | |
3 | "path.js" | |
4 | ]; | |
5 | var loaded = 0; | |
6 | for (var i = 0; i < deps.length; i++) { | |
7 | var elem = document.createElement('script'); | |
8 | elem.src = prefix + deps[i]; | |
9 | elem.onload = function() { | |
10 | if (++loaded == deps.length) { | |
11 | var container = document.getElementById(containerId); | |
12 | ||
13 | var map = yoob.makeCanvas(container, 432, 284); | |
14 | map.style.background = "transparent"; | |
15 | map.style.position = "absolute"; | |
16 | map.style.zIndex = "100"; | |
17 | ||
18 | var quotation_container = yoob.makeSpan(container); | |
19 | quotation_container.style.width = "432px"; | |
20 | quotation_container.style.height = "284px"; | |
21 | quotation_container.style.background = "transparent"; | |
22 | quotation_container.style.position = "absolute"; | |
23 | quotation_container.style.zIndex = "50"; | |
24 | ||
25 | var quotation = yoob.makeSpan(quotation_container); | |
26 | quotation.style.width = "432px"; | |
27 | quotation.style.height = "284px"; | |
28 | quotation.style.background = "transparent"; | |
29 | quotation.style.display = "table-cell"; | |
30 | quotation.style.verticalAlign = "middle"; | |
31 | quotation.style.padding = "2px"; | |
32 | quotation.style.fontSize = "150%"; | |
33 | quotation.style.textShadow = "2px 2px 2px #404040"; | |
34 | quotation.style.color = "white"; | |
35 | quotation.style.lineHeight = "30px"; | |
36 | ||
37 | var canvas = yoob.makeCanvas(container, 432, 284); | |
38 | yoob.makeLineBreak(container); | |
39 | ||
40 | var buttons_container = yoob.makeDiv(container); | |
41 | var buttons = {}; | |
42 | buttons.up = yoob.makeButton(buttons_container, '↑'); | |
43 | ||
44 | yoob.makeLineBreak(buttons_container); | |
45 | buttons.left = yoob.makeButton(buttons_container, '←'); | |
46 | buttons.showMap = yoob.makeButton(buttons_container, 'map'); | |
47 | buttons.right = yoob.makeButton(buttons_container, '→'); | |
48 | yoob.makeLineBreak(buttons_container); | |
49 | buttons.down = yoob.makeButton(buttons_container, '↓'); | |
50 | ||
51 | for (key in buttons) { | |
52 | buttons[key].style.fontSize = '125%'; | |
53 | buttons[key].style.lineHeight = '25px'; | |
54 | } | |
55 | ||
56 | var t = new WomanOnFilm(); | |
57 | t.init(canvas, quotation, map, buttons); | |
58 | } | |
59 | }; | |
60 | document.body.appendChild(elem); | |
61 | } | |
62 | } | |
63 | ||
64 | /* ================================================================== */ | |
65 | ||
66 | function makePathSets() { | |
67 | return [ | |
68 | // first attempt | |
69 | [ | |
70 | new yoob.Path({title:"outline",strokeStyle:"black",lineWidth:"4", | |
71 | points:[49.666666666666664,141.33333333333334,57,94.66666666666667,65,86.66666666666667,81.33333333333333,76,81.66666666666667,72.66666666666667,80,69,75.33333333333333,73.66666666666667,66,79,58.666666666666664,79,54,75.66666666666667,53.333333333333336,65.66666666666667,48,62,44,62,46,65.66666666666667,42,65.33333333333333,40.666666666666664,62.333333333333336,42.666666666666664,59.333333333333336,43,57,41,55,41.666666666666664,54,44.333333333333336,53.333333333333336,50.333333333333336,54.666666666666664,55.333333333333336,49.666666666666664,59,40.666666666666664,65.33333333333333,29.333333333333332,73,14,87.33333333333333,2,92,1.3333333333333333,100.33333333333333,3.6666666666666665,109.33333333333333,7.333333333333333,116.66666666666667,15.333333333333334,122.66666666666667,28.333333333333332,128,41,130.66666666666666,51.333333333333336,134.33333333333334,57.333333333333336,139,58.666666666666664,136.66666666666666,65,132,71.33333333333333,130.33333333333334,73,144.33333333333334,78.33333333333333,143,80.66666666666667,156,92,167.66666666666666,106.33333333333333,179.33333333333334,124,188,141]}), | |
72 | new yoob.Path({title:"face",strokeStyle:"black", | |
73 | points:[74,47,77.66666666666667,51.333333333333336,80.33333333333333,50.333333333333336,82.33333333333333,57.666666666666664,87.33333333333333,63.333333333333336,94.33333333333333,67.66666666666667,103.33333333333333,69.33333333333333,108,66,113.66666666666667,60.333333333333336,116,52,117,50,118,35,115,33.666666666666664,113.66666666666667,34.333333333333336,111.66666666666667,33,106,36.666666666666664,105.33333333333333,34.666666666666664,106.66666666666667,30.666666666666668,101.33333333333333,26.333333333333332,97.33333333333333,18.333333333333332,96.33333333333333,17,93.33333333333333,18,88,21.333333333333332,80.66666666666667,33,80,44.333333333333336,78.33333333333333,43.666666666666664,74,45.333333333333336,74,47.333333333333336]}), | |
74 | new yoob.Path({title:"eyebrow",strokeStyle:"black", | |
75 | points:[86.33333333333333,31.666666666666668,89.66666666666667,29.666666666666668,92.33333333333333,29.666666666666668,95,31.333333333333332,97,32.333333333333336]}), | |
76 | new yoob.Path({title:"mouth outline",strokeStyle:"black", | |
77 | points:[94.33333333333333,58,100.33333333333333,56.333333333333336,103,56.333333333333336,109.33333333333333,56.666666666666664,108,58.666666666666664,107,61,103.33333333333333,62.333333333333336,99.33333333333333,61.333333333333336,95.33333333333333,58.333333333333336]}), | |
78 | new yoob.Path({title:"lips",strokeStyle:"black", | |
79 | points:[95,57.666666666666664,100.66666666666667,58.666666666666664,106.33333333333333,58.666666666666664,109,57.333333333333336]}), | |
80 | new yoob.Path({title:"nose",strokeStyle:"black", | |
81 | points:[104.66666666666667,36.666666666666664,107,44.666666666666664,109,48.666666666666664,107.33333333333333,50.666666666666664,104.33333333333333,52.333333333333336,102,51.333333333333336,98.66666666666667,50,99.33333333333333,47.333333333333336,101.33333333333333,46.333333333333336]}), | |
82 | new yoob.Path({title:"left eye",strokeStyle:"black", | |
83 | points:[88.33333333333333,38,91.33333333333333,36,94.66666666666667,35.666666666666664,98,37.333333333333336,96,39.666666666666664,91.66666666666667,40.333333333333336,89,38.333333333333336]}), | |
84 | new yoob.Path({title:"right eye",strokeStyle:"black", | |
85 | points:[107.66666666666667,38,110.33333333333333,39.333333333333336,114.33333333333333,40,116,38,114.33333333333333,35.333333333333336,110.66666666666667,36,107.66666666666667,38]}), | |
86 | new yoob.Path({title:"inner coat",strokeStyle:"black", | |
87 | points:[63.666666666666664,141.66666666666666,83,77.66666666666667,89.66666666666667,84.66666666666667,97.33333333333333,85.33333333333333,105.66666666666667,81.66666666666667,108.66666666666667,119,113.66666666666667,141.33333333333334]}), | |
88 | new yoob.Path({title:"left neck",strokeStyle:"black", | |
89 | points:[80,69,86,70.66666666666667,82.66666666666667,59]}), | |
90 | new yoob.Path({title:"scarf",strokeStyle:"black", | |
91 | points:[106,81,112,77.33333333333333,113,74,118.66666666666667,70.66666666666667,129.33333333333334,72,120.66666666666667,64.66666666666667,113,64.33333333333333,112,68.66666666666667,104.66666666666667,69.33333333333333,94,71,86.33333333333333,70.66666666666667]}), | |
92 | new yoob.Path({title:"button 1",strokeStyle:"black", | |
93 | points:[116.66666666666667,80.66666666666667,113.33333333333333,81.33333333333333,112.33333333333333,85,114.33333333333333,87.66666666666667,117.66666666666667,88.33333333333333,119.66666666666667,85.66666666666667,120,83,117.66666666666667,81]}), | |
94 | new yoob.Path({title:"button 2",strokeStyle:"black", | |
95 | points:[123,112.66666666666667,119.66666666666667,109.66666666666667,116.33333333333333,110.33333333333333,114.33333333333333,114,115.33333333333333,117.66666666666667,119,119.66666666666667,122.33333333333333,117.66666666666667,123.33333333333333,113.33333333333333]}) | |
96 | ], | |
97 | // 2nd attempt | |
98 | [ | |
99 | new yoob.Path({title:"coat",fillStyle:"#8A6A00",strokeStyle:"black",closed:"true", | |
100 | points:[50,142.16666666666666,50.833333333333336,126.83333333333333,54.833333333333336,100.83333333333333,57.666666666666664,92.66666666666667,64,87.83333333333333,64.83333333333333,84.83333333333333,81.33333333333333,74.66666666666667,83.5,79.66666666666667,90.16666666666667,84.5,98.5,85,112.16666666666667,77.16666666666667,112.83333333333333,74,120.16666666666667,70.5,122.33333333333333,67.5,143.5,78,143.33333333333334,81.16666666666667,154.16666666666666,90.16666666666667,175.16666666666666,116.16666666666667,188.5,141.83333333333334]}), | |
101 | new yoob.Path({title:"inner coat",fillStyle:"grey",closed:"true", | |
102 | points:[62.833333333333336,142.16666666666666,83.5,80,90.16666666666667,84.66666666666667,98.66666666666667,85.33333333333333,103.66666666666667,82.16666666666667,110.16666666666667,126.5,113.16666666666667,141.5]}), | |
103 | new yoob.Path({title:"neck",fillStyle:"#F2C763",closed:"true", | |
104 | points:[83.16666666666667,59.5,82.83333333333333,67.66666666666667,88.16666666666667,70.5,96.16666666666667,70.33333333333333,105.16666666666667,68,111.66666666666667,67.66666666666667,112.5,65.16666666666667,112,62,109,64.83333333333333,104.66666666666667,68.16666666666667,99.5,68.33333333333333,92.83333333333333,67,87.33333333333333,63.833333333333336]}), | |
105 | new yoob.Path({title:"face",fillStyle:"#F5D998",strokeStyle:"black",closed:"true", | |
106 | points:[99,68.33333333333333,104.5,68.16666666666667,108.66666666666667,65.16666666666667,114.16666666666667,59.166666666666664,115.5,51.666666666666664,118,38.833333333333336,117.33333333333333,33.666666666666664,115,22.5,108.5,17.166666666666668,96,16.833333333333332,89.5,19,84,26.166666666666668,79.83333333333333,32.5,79.5,42,77.83333333333333,39,75,38,73,40,73.5,46.333333333333336,76.16666666666667,50.666666666666664,78.5,51.333333333333336,80.83333333333333,49.833333333333336,82.83333333333333,59,87.33333333333333,63.833333333333336,93.16666666666667,67.16666666666667]}), | |
107 | new yoob.Path({title:"hair",fillStyle:"#550000",strokeStyle:"black",lineWidth:"3",closed:"true", | |
108 | points:[59.333333333333336,79,73.5,74.83333333333333,80.33333333333333,66.33333333333333,85.16666666666667,69.33333333333333,80.83333333333333,49.833333333333336,78.66666666666667,51.5,76.16666666666667,50.833333333333336,73.33333333333333,46.166666666666664,73.33333333333333,43.5,77.33333333333333,44.333333333333336,79.66666666666667,41.5,79.83333333333333,32.5,89.5,19,96,16.833333333333332,100,20.333333333333332,101.83333333333333,26.333333333333332,106.33333333333333,29.333333333333332,106.33333333333333,33.166666666666664,104.66666666666667,36,107.5,36.333333333333336,110.5,32.666666666666664,113.83333333333333,33.166666666666664,114.5,35.333333333333336,115.83333333333333,33.166666666666664,117.33333333333333,33.833333333333336,118.16666666666667,38.666666666666664,115.66666666666667,51.833333333333336,114.16666666666667,59.333333333333336,111.83333333333333,61.666666666666664,112.33333333333333,65,118.33333333333333,64.83333333333333,131.5,72,134.83333333333334,70,139.33333333333334,58.833333333333336,136.5,58.166666666666664,131,52,128.83333333333334,42,125.16666666666667,36.166666666666664,121.5,22.5,118.33333333333333,15,110.16666666666667,6.333333333333333,102,3.5,91.16666666666667,1,89,1.1666666666666667,73.83333333333333,11.333333333333334,67.16666666666667,23.5,64,31,59.833333333333336,39.666666666666664,50.833333333333336,53.5,47.833333333333336,54.333333333333336,43.833333333333336,50.166666666666664,42.666666666666664,53,39.666666666666664,54.666666666666664,43,56,43.333333333333336,57.666666666666664,40.333333333333336,60.833333333333336,40.166666666666664,64.16666666666667,45,65.16666666666667,43,61.333333333333336,46.5,60.666666666666664,52.5,64.5,53.833333333333336,71,53.166666666666664,74]}), | |
109 | new yoob.Path({title:"scarf",fillStyle:"red",closed:"true", | |
110 | points:[80,67.33333333333333,82.16666666666667,72.5,81.5,75,83.66666666666667,79.83333333333333,90.33333333333333,84.66666666666667,98.66666666666667,85.33333333333333,112.16666666666667,77.16666666666667,113,74,120.5,70.33333333333333,122.5,67,118.33333333333333,64.83333333333333,113,65,111.83333333333333,67.33333333333333,105.16666666666667,68.16666666666667,96.16666666666667,70.5,88.33333333333333,70.66666666666667,80.66666666666667,66.33333333333333]}), | |
111 | new yoob.Path({title:"left eye",fillStyle:"white",strokeStyle:"black",closed:"true", | |
112 | points:[89.6,38.1,91.2,38.9,93.7,39,95.6,38.5,96.4,37.4,95.1,36,94.1,35.7,91.5,35.8,90.5,36.6]}), | |
113 | new yoob.Path({title:"left pupil",fillStyle:"green",closed:"true", | |
114 | points:[93.5,37.7,93.8,36.8,94.8,36.1,95.8,36.6,96.1,37.5,95.4,38.6,94.5,38.6]}), | |
115 | new yoob.Path({title:"right eye",fillStyle:"white",strokeStyle:"black",closed:"true", | |
116 | points:[107.9,37.5,109.4,38.3,111.9,38.6,113.6,38.1,114.7,36.9,113.7,35.5,112.8,35.3,109.9,35.3,108.7,36.1]}), | |
117 | new yoob.Path({title:"right pupil",fillStyle:"green",closed:"true", | |
118 | points:[112,36.8,112.4,36,113.2,35.5,114.1,36.1,114.3,36.9,113.7,37.7,112.8,37.7]}), | |
119 | new yoob.Path({title:"left eyebrow",strokeStyle:"black", | |
120 | points:[87.66666666666667,30.11111111111111,90,29.11111111111111,92.22222222222223,29.22222222222222,95.22222222222223,30.444444444444443,96.55555555555556,31.666666666666668]}), | |
121 | new yoob.Path({title:"lips",fillStyle:"red",closed:"true", | |
122 | points:[96.22222222222223,57.77777777777778,99.77777777777777,56.111111111111114,106.55555555555556,56.333333333333336,108.22222222222223,57.333333333333336,107.22222222222223,58.55555555555556,105.22222222222223,59.55555555555556,100.55555555555556,59.666666666666664]}), | |
123 | new yoob.Path({title:"lip line",strokeStyle:"black", | |
124 | points:[96.22222222222223,57.888888888888886,103.22222222222223,57.888888888888886,108.11111111111111,57.44444444444444]}), | |
125 | new yoob.Path({title:"nostrils",strokeStyle:"black", | |
126 | points:[99.5,49.7,101.9,49.7,103.1,51.1,104.5,51.4,106.1,50.9,106.6,49.4,107.8,49.3]}), | |
127 | new yoob.Path({title:"septum",strokeStyle:"black", | |
128 | points:[107.3,47.1,106.2,46.4,105.4,43.5,105,39.8]}), | |
129 | new yoob.Path({title:"button 1",fillStyle:"white",closed:"true", | |
130 | points:[114.33333333333333,88.16666666666667,117.33333333333333,88.33333333333333,119.66666666666667,86.16666666666667,119.83333333333333,83.5,117.83333333333333,81.33333333333333,114.83333333333333,81.16666666666667,112.83333333333333,82.66666666666667,112.66666666666667,85.5]}), | |
131 | new yoob.Path({title:"button 2",fillStyle:"white",closed:"true", | |
132 | points:[114.5,116.5,114.33333333333333,113,117,110.5,120,110.66666666666667,122.16666666666667,112.33333333333333,122.83333333333333,115.5,120.83333333333333,118.33333333333333,117.66666666666667,119]}) | |
133 | ], | |
134 | // third attempt | |
135 | [ | |
136 | new yoob.Path({title:"hair 3",fillStyle:"#444444",closed:"true", | |
137 | points:[99.66666666666667,2.6666666666666665,107.5,5.333333333333333,116.16666666666667,12.833333333333334,125.16666666666667,36.5,128.83333333333334,38.166666666666664,134.33333333333334,38.166666666666664,128.83333333333334,39.333333333333336,125.83333333333333,38.666666666666664,129.16666666666666,42.833333333333336,129.66666666666666,47,132.66666666666666,49.166666666666664,137.16666666666666,49.333333333333336,138.83333333333334,52.333333333333336,138.16666666666666,59,137.66666666666666,53.666666666666664,136.66666666666666,52.166666666666664,131.33333333333334,52.5,131.16666666666666,57,133.83333333333334,59.666666666666664,138.66666666666666,59.5,134.66666666666666,66.5,134.16666666666666,69.66666666666667,129.33333333333334,72,120.33333333333333,68.16666666666667,101.33333333333333,71,93.5,4]}), | |
138 | new yoob.Path({title:"hair 2",fillStyle:"#aaaaaa",closed:"true", | |
139 | points:[54.333333333333336,72.83333333333333,51.833333333333336,65.5,47.333333333333336,62.666666666666664,43.166666666666664,61.833333333333336,44.833333333333336,65,41.833333333333336,65.33333333333333,39.5,62,40.333333333333336,60.333333333333336,37.166666666666664,57.166666666666664,40.333333333333336,54,41,48,40.166666666666664,43,44.833333333333336,38.333333333333336,55.166666666666664,36.833333333333336,63.333333333333336,31.333333333333332,67.33333333333333,22.5,72.33333333333333,15.333333333333334,72.5,12.833333333333334,79.66666666666667,5.333333333333333,89.33333333333333,0.5,94.5,0.6666666666666666,102,3.1666666666666665,99.66666666666667,5.5,105,6.333333333333333,114,12.833333333333334,107.66666666666667,11,113.83333333333333,16,110.33333333333333,15.833333333333334,117,24,117,27.5,110.83333333333333,19.666666666666668,101.33333333333333,11,94.33333333333333,9.833333333333334,99.66666666666667,12.166666666666666,109.66666666666667,20.5,111.66666666666667,24,107.83333333333333,22.666666666666668,111.33333333333333,29.333333333333332,104.83333333333333,25,101.66666666666667,16.833333333333332,96.66666666666667,13.666666666666666,65.33333333333333,36,61.333333333333336,73.66666666666667]}), | |
140 | new yoob.Path({title:"hair 1",fillStyle:"grey",closed:"true", | |
141 | points:[82.33333333333333,67.66666666666667,78.5,67.66666666666667,73.83333333333333,74.16666666666667,65.5,78,58,78.66666666666667,53.166666666666664,74.66666666666667,53.833333333333336,70.16666666666667,58.166666666666664,69.83333333333333,58.666666666666664,63.166666666666664,62,58.5,59.666666666666664,58.333333333333336,53.166666666666664,65,47.166666666666664,61.333333333333336,44.166666666666664,60.666666666666664,43.333333333333336,55.5,40.333333333333336,54,44.166666666666664,50.5,48.666666666666664,54.333333333333336,55.5,48.666666666666664,56.333333333333336,45.333333333333336,59.166666666666664,42.333333333333336,59.333333333333336,40.333333333333336,62.5,37.666666666666664,63.833333333333336,31,69.83333333333333,25.5,76.33333333333333,18.833333333333332,75.66666666666667,24,81.83333333333333,18.166666666666668,80.66666666666667,23.166666666666668,92.33333333333333,15,84,11.5,95.5,4.5,89.66666666666667,10.5,96.33333333333333,13,97.5,17]}), | |
142 | new yoob.Path({title:"neck",fillStyle:"#ffccaa",strokeStyle:"black",closed:"true", | |
143 | points:[82.42857142857143,75.85714285714286,81.85714285714286,49.714285714285715,96.14285714285714,64.57142857142857,104.57142857142857,64.57142857142857,112,59,112.14285714285714,69.71428571428571,102,78.57142857142857]}), | |
144 | new yoob.Path({title:"face",fillStyle:"#ffccaa",strokeStyle:"black",closed:"true", | |
145 | points:[83.5,59.333333333333336,90,64.66666666666667,97.5,67.83333333333333,101.5,68.33333333333333,105.16666666666667,67.5,110.66666666666667,63.333333333333336,114.16666666666667,59.166666666666664,116,50.666666666666664,117.33333333333333,47,118.16666666666667,38.833333333333336,117.33333333333333,37,117.33333333333333,34,113.16666666666667,32.5,105,36.5,106.66666666666667,29.5,101.5,25.5,97.66666666666667,17.166666666666668,92.33333333333333,17.166666666666668,80.5,31.5,79.83333333333333,33.333333333333336,79.66666666666667,40.666666666666664,77.16666666666667,44.166666666666664,74,44.166666666666664,74.16666666666667,47.666666666666664,77.5,51.5,80.66666666666667,49.833333333333336]}), | |
146 | new yoob.Path({title:"lips",fillStyle:"#ffaacc",strokeStyle:"black",closed:"true", | |
147 | points:[93.6,57.8,99,56,102.7,55.5,103.7,55.9,104.6,55.6,107.7,56,109.4,56.7,108,57.9,107.3,60,105.4,61.3,100.6,61.4,98.6,60.8,96.7,58.9]}), | |
148 | new yoob.Path({title:"lip line",strokeStyle:"black", | |
149 | points:[94.5,57.9,106.1,58,109.1,56.8]}), | |
150 | new yoob.Path({title:"left eye",fillStyle:"#faaaaa",strokeStyle:"black",closed:"true", | |
151 | points:[87.71428571428571,37.714285714285715,88.28571428571429,36.285714285714285,90.57142857142857,34.857142857142854,95.57142857142857,34.857142857142854,98,37,97.85714285714286,38.857142857142854,95,40.857142857142854,90.85714285714286,41,88.28571428571429,39.142857142857146]}), | |
152 | new yoob.Path({title:"right eye",fillStyle:"#faaaaa",strokeStyle:"black",closed:"true", | |
153 | points:[106.71428571428571,38.57142857142857,109.28571428571429,40.714285714285715,113.42857142857143,41,114.85714285714286,39.142857142857146,115.14285714285714,36.42857142857143,113.71428571428571,35.142857142857146,109,35,107.14285714285714,37]}), | |
154 | new yoob.Path({title:"nose",strokeStyle:"black", | |
155 | points:[104,36.285714285714285,105.57142857142857,45.285714285714285,105.71428571428571,50.57142857142857,107.71428571428571,49,100.57142857142857,49.57142857142857]}), | |
156 | new yoob.Path({title:"coat 1",fillStyle:"brown",strokeStyle:"black",closed:"true", | |
157 | points:[50.4,142,50.8,127.8,53.6,118,54.8,102.6,56,96.4,58,91.6,64.2,87.8,65,84.6,71.8,81.2,82.4,74.2,121.6,69.2,143.2,78,142.2,80.2,150,86.2,173.2,113,188.4,141.2]}), | |
158 | new yoob.Path({title:"coat 2",fillStyle:"brown",strokeStyle:"black",closed:"true", | |
159 | points:[112.6,73.8,118.8,79,143.6,79.4,143,93.4,145.6,113.6,155.8,141.6,189,141.8,175.2,116.6,157.4,94.4,142.6,80.6,144,78.8,117.2,66.8]}), | |
160 | new yoob.Path({title:"vest",fillStyle:"#005500",strokeStyle:"black",closed:"true", | |
161 | points:[62.4,141.8,84.2,76.8,106.6,77,104.6,89,108,118.4,114.2,141.8]}), | |
162 | new yoob.Path({title:"scarf",fillStyle:"blue",strokeStyle:"black",closed:"true", | |
163 | points:[82.42857142857143,77.14285714285714,82.57142857142857,71.85714285714286,80.85714285714286,67.57142857142857,82.42857142857143,63.857142857142854,83.71428571428571,68,86.57142857142857,70.71428571428571,92.85714285714286,71,101.57142857142857,69,112.28571428571429,68.28571428571429,113.28571428571429,67,112.85714285714286,64.28571428571429,119.57142857142857,64.71428571428571,122.71428571428571,70,119.28571428571429,69.57142857142857,112.71428571428571,72.42857142857143,112.28571428571429,76.71428571428571,99.14285714285714,85,90.85714285714286,85.14285714285714]}), | |
164 | new yoob.Path({title:"left pupil",fillStyle:"black",closed:"true", | |
165 | points:[93.11111111111111,37.666666666666664,94.33333333333333,38.44444444444444,96,38.666666666666664,97.66666666666667,37.333333333333336,96.22222222222223,35.77777777777778,94.55555555555556,35.77777777777778]}), | |
166 | new yoob.Path({title:"right pupil",fillStyle:"black",closed:"true", | |
167 | points:[111.44444444444444,37.333333333333336,112.55555555555556,35.111111111111114,114.11111111111111,35.333333333333336,114.88888888888889,36.44444444444444,114.55555555555556,37.666666666666664,113.11111111111111,38.22222222222222]}), | |
168 | new yoob.Path({title:"r.sleeve",strokeStyle:"black", | |
169 | points:[56.2,141.8,62.6,112,74,84.6,81.2,84.2,79.6,80.4,74,78.8,64.6,84.2,62.4,93,73.8,84.8]}), | |
170 | new yoob.Path({title:"button 1",fillStyle:"gainsboro",strokeStyle:"black",closed:"true", | |
171 | points:[111.8,83.2,112.4,86.4,116.8,87.8,120.2,85.2,120,82.8,116,80]}), | |
172 | new yoob.Path({title:"button 2",fillStyle:"gainsboro",strokeStyle:"black",closed:"true", | |
173 | points:[114.4,112.8,114.8,117,117,118.6,120.6,119.2,122.6,117.2,123,112.4,120.4,110.4,117,110]}) | |
174 | ] | |
175 | ]; | |
176 | } | |
177 | ||
178 | /* ================================================================== */ | |
179 | ||
180 | var quotationMapStyle = "rgba(150,100,0,0.66)"; | |
181 | var zQuotationMapStyle = "rgba(0,100,150,0.66)"; | |
182 | var mQuotationMapStyle = "rgba(0,150,100,0.66)"; | |
183 | ||
184 | var clonePathSet = function(pathSet) { | |
185 | var n = []; | |
186 | for (var i = 0; i < pathSet.length; i++) { | |
187 | n.push(pathSet[i].clone()); | |
188 | } | |
189 | return n; | |
190 | }; | |
191 | ||
192 | var mapWithJitter = function(path, jitter) { | |
193 | var r = function() { | |
194 | return Math.random() * jitter - (jitter / 2); | |
195 | }; | |
196 | return path.map(function(x, y) { | |
197 | return [x + r(), y + r()]; | |
198 | }); | |
199 | }; | |
200 | ||
201 | ||
202 | function WomanOnFilm() { | |
203 | var cx; | |
204 | var cy; | |
205 | var hx; | |
206 | var hy; | |
207 | var canvas; | |
208 | var ctx; | |
209 | var map; | |
210 | var mapctx; | |
211 | var quotation; | |
212 | var buttons; | |
213 | var mapShown = false; | |
214 | var count = 0; | |
215 | var transitionFromDx = undefined; | |
216 | var transitionFromDy = undefined; | |
217 | var transitionCount = undefined; | |
218 | ||
219 | var pathSets = makePathSets(); | |
220 | var jPathSets = []; | |
221 | var currentJitter = 0.7; | |
222 | var currentJitterRate = 6; | |
223 | ||
224 | var persPathSet = undefined; | |
225 | ||
226 | var cmap; | |
227 | cmap = [ | |
228 | // row 2 (well actually 1) | |
229 | [ | |
230 | undefined, | |
231 | undefined, | |
232 | { | |
233 | onenter: function() { | |
234 | setQuotation( | |
235 | "I love Los Angeles. I love Hollywood. They're so beautiful. " + | |
236 | "Everything's plastic, but I love plastic. I want to be plastic." | |
237 | ); | |
238 | }, | |
239 | mapstyle: quotationMapStyle | |
240 | }, | |
241 | { | |
242 | // WARHOL 1 | |
243 | draw: function () { | |
244 | drawPaths(ctx, "#aaffff", jPathSets[0], 0, 0); | |
245 | drawPaths(ctx, "#ffaaff", jPathSets[1], hx, 0); | |
246 | drawPaths(ctx, "#ffffaa", jPathSets[2], 0, hy); | |
247 | drawPaths(ctx, "#aaaaaa", jPathSets[0], hx, hy); | |
248 | drawPaths(ctx, "transparent", jPathSets[0], 0, 0, 2, 2, | |
249 | {lineWidth: 2, strokeStyle:"rgba(0,0,0,0.5)"}); | |
250 | } | |
251 | }, | |
252 | { | |
253 | // WARHOL 2 | |
254 | draw: function () { | |
255 | drawPaths(ctx, "#ffffff", jPathSets[0], 0, 0); | |
256 | drawPaths(ctx, "#ffaaaa", jPathSets[1], hx, 0, 1, 1, | |
257 | {lineWidth: 2, strokeStyle:"black"}); | |
258 | drawPaths(ctx, "#aaffaa", jPathSets[2], 0, hy); | |
259 | drawPaths(ctx, "#aaaaff", jPathSets[0], hx, hy); | |
260 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2, | |
261 | {lineWidth: 2, fillStyle:"rgba(0,0,0,0.5)"}); | |
262 | } | |
263 | }, | |
264 | { | |
265 | // WARHOL 3 | |
266 | draw: function () { | |
267 | drawPaths(ctx, "#ff00aa", jPathSets[0], 0, 0); | |
268 | drawPaths(ctx, "#ffaa00", jPathSets[1], hx, 0); | |
269 | drawPaths(ctx, "#aa00ff", jPathSets[2], 0, hy, 1, 1, | |
270 | {lineWidth: 2, strokeStyle:"#ff00ff"}); | |
271 | drawPaths(ctx, "#aaff00", jPathSets[2], hx, hy, 1, 1, | |
272 | {lineWidth: 2, strokeStyle:"#00aaff"}); | |
273 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2); | |
274 | } | |
275 | } | |
276 | ], | |
277 | // row 3 | |
278 | [ | |
279 | { | |
280 | draw: function () { | |
281 | drawPaths(ctx, "white", jPathSets[0], 0, 0, 2, 2); | |
282 | } | |
283 | }, | |
284 | { | |
285 | draw: function () { | |
286 | drawPaths(ctx, "white", jPathSets[1], 0, 0, 2, 2); | |
287 | } | |
288 | }, | |
289 | { | |
290 | draw: function () { | |
291 | drawPaths(ctx, "white", jPathSets[2], 0, 0, 2, 2); | |
292 | } | |
293 | }, | |
294 | undefined, | |
295 | undefined, | |
296 | { | |
297 | // merge node | |
298 | onenter: function() { | |
299 | setQuotation( | |
300 | "Right when I was being shot and ever since, I knew that I was watching " + | |
301 | "television. The channels switch, but it's all television." | |
302 | ); | |
303 | }, | |
304 | mapstyle: quotationMapStyle | |
305 | }, | |
306 | { | |
307 | // TV 1 | |
308 | draw: function () { | |
309 | ctx.fillStyle = "#d0d0d0"; | |
310 | ctx.fillRect(0, 0, canvas.width, canvas.height / 2); | |
311 | ctx.fillStyle = "#404040"; // bah | |
312 | ctx.fillRect(0, canvas.height / 2, canvas.width, canvas.height / 2); | |
313 | ||
314 | // sun | |
315 | ctx.beginPath(); | |
316 | ctx.arc(canvas.width * 0.17, canvas.height * 0.25, | |
317 | canvas.height * 0.10, 0, Math.PI * 2, false); | |
318 | ctx.fillStyle = "#f7f7f7"; | |
319 | ctx.fill(); | |
320 | ctx.lineWidth = 4; | |
321 | ctx.strokeStyle = "#ffffff"; | |
322 | ctx.stroke(); | |
323 | ||
324 | // cactus | |
325 | ctx.beginPath(); | |
326 | var cacx = 0.85; | |
327 | var cacxl = cacx - 0.045; | |
328 | var cacxr = cacx + 0.040; | |
329 | ||
330 | ctx.moveTo(canvas.width * cacx, canvas.height * 0.75); | |
331 | ctx.lineTo(canvas.width * cacx, canvas.height * 0.25); | |
332 | ||
333 | ctx.moveTo(canvas.width * cacx, canvas.height * 0.45); | |
334 | ctx.lineTo(canvas.width * cacxl, canvas.height * 0.45); | |
335 | ctx.lineTo(canvas.width * cacxl, canvas.height * 0.33); | |
336 | ||
337 | ctx.moveTo(canvas.width * cacx, canvas.height * 0.55); | |
338 | ctx.lineTo(canvas.width * cacxr, canvas.height * 0.55); | |
339 | ctx.lineTo(canvas.width * cacxr, canvas.height * 0.45); | |
340 | ||
341 | ctx.lineWidth = 15; | |
342 | ctx.lineCap = "round"; | |
343 | ctx.strokeStyle = "#101010"; | |
344 | ctx.stroke(); | |
345 | ||
346 | drawPaths(ctx, "transparent", jPathSets[0], 0, 0, 2, 2, | |
347 | function(p) { | |
348 | if (p.title === 'outline') { | |
349 | return {strokeStyle:"black",fillStyle:"#808080", | |
350 | lineWidth:4}; | |
351 | } | |
352 | if (p.title === 'left eye' || p.title === 'right eye') { | |
353 | return {strokeStyle:"black",fillStyle:"#959595", | |
354 | lineWidth:0.5}; | |
355 | } | |
356 | return true; | |
357 | }); | |
358 | } | |
359 | }, | |
360 | { | |
361 | // TV 2 | |
362 | draw: function () { | |
363 | ctx.fillStyle = "white"; | |
364 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
365 | ctx.strokeStyle = "black"; | |
366 | ctx.lineWidth = 2; | |
367 | var x1 = 0; | |
368 | var y1 = 0; | |
369 | var x2 = canvas.width; | |
370 | var y2 = canvas.height; | |
371 | var cx = canvas.width * 0.75; | |
372 | var cy = canvas.height * 0.25; | |
373 | var c = 128; | |
374 | var f = 0.25; | |
375 | for (var i = 0; i < 10; i++) { | |
376 | ctx.fillStyle = "rgba(" + c + ",0,0,1.0)"; | |
377 | if (i === 9) ctx.fillStyle = "#222222"; | |
378 | ctx.fillRect(x1, y1, x2-x1, y2-y1); | |
379 | ctx.strokeRect(x1, y1, x2-x1, y2-y1); | |
380 | var nx1 = x1 + Math.abs(cx-x1) * f; | |
381 | var nx2 = x2 - Math.abs(cx-x2) * f; | |
382 | var ny1 = y1 + Math.abs(cy-y1) * f; | |
383 | var ny2 = y2 - Math.abs(cy-y2) * f; | |
384 | ||
385 | if (i < 9) { | |
386 | ctx.beginPath(); | |
387 | ctx.moveTo(x1, y1); ctx.lineTo(nx1, ny1); | |
388 | ctx.moveTo(x2, y1); ctx.lineTo(nx2, ny1); | |
389 | ctx.moveTo(x1, y2); ctx.lineTo(nx1, ny2); | |
390 | ctx.moveTo(x2, y2); ctx.lineTo(nx2, ny2); | |
391 | ctx.stroke(); | |
392 | } | |
393 | ||
394 | c = Math.floor(c * 0.75); | |
395 | x1 = nx1; y1 = ny1; x2 = nx2; y2 = ny2; | |
396 | } | |
397 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2); | |
398 | } | |
399 | }, | |
400 | { | |
401 | // TV 3 | |
402 | draw: function () { | |
403 | ctx.fillStyle = "#000000"; | |
404 | ctx.fillRect(0, 0, canvas.width, canvas.height / 2); | |
405 | ctx.fillStyle = "#000060"; | |
406 | ctx.fillRect(0, canvas.height / 2, canvas.width, canvas.height / 2); | |
407 | ||
408 | // moon | |
409 | var moonRadius = canvas.height * 0.08; | |
410 | var moonX = canvas.width * 0.80; | |
411 | ctx.beginPath(); | |
412 | ctx.arc(moonX, canvas.height * 0.25, | |
413 | moonRadius, 0, Math.PI * 2, false); | |
414 | ctx.fillStyle = "#b0b090"; | |
415 | ctx.fill(); | |
416 | ||
417 | // reflection | |
418 | ctx.strokeStyle = "#7070ff"; | |
419 | ctx.lineWidth = 2; | |
420 | var lines = [[0.5, 0.70], [1.0, 0.75], [0.5, 0.80]]; | |
421 | for (var i = 0; i < lines.length; i++) { | |
422 | var r = moonRadius * lines[i][0] + 3 * Math.cos(count / 10.0); | |
423 | var y = canvas.height * lines[i][1] + 3 * Math.sin((count + (i * 10)) / 10.0); | |
424 | ctx.beginPath(); | |
425 | ctx.moveTo(moonX - r, y); | |
426 | ctx.lineTo(moonX + r, y); | |
427 | ctx.stroke(); | |
428 | } | |
429 | ||
430 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2); | |
431 | } | |
432 | }, | |
433 | { | |
434 | onenter: function() { | |
435 | setQuotation( | |
436 | "... when you do something exactly wrong, you always turn up something." | |
437 | ); | |
438 | }, | |
439 | mapstyle: quotationMapStyle | |
440 | }, | |
441 | { | |
442 | draw: function () { | |
443 | // COMPOSITE WOMAN | |
444 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
445 | drawPaths(ctx, "transparent", jPathSets[0], 0, 0, 2, 2, | |
446 | {lineWidth: 2, fillStyle:"rgba(0,0,0,0.2)"}); | |
447 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2, | |
448 | {lineWidth: 2, fillStyle:"rgba(0,0,0,0.2)"}); | |
449 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2, | |
450 | {lineWidth: 2, fillStyle:"rgba(0,0,0,0.2)"}); | |
451 | } | |
452 | }, | |
453 | { | |
454 | draw: function () { | |
455 | // RGB NEON | |
456 | drawPaths(ctx, "white", jPathSets[0], 0, 0, 2, 2, | |
457 | {lineWidth: 1, strokeStyle:"rgba(255,0,0,0.8)"}); | |
458 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2, | |
459 | {lineWidth: 1, strokeStyle:"rgba(0,255,0,0.8)"}); | |
460 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2, | |
461 | {lineWidth: 1, strokeStyle:"rgba(0,0,255,0.8)"}); | |
462 | } | |
463 | }, | |
464 | { | |
465 | draw: function () { | |
466 | // STARS | |
467 | if (count % 4 !== 0) return; | |
468 | foreachPaths(ctx, "black", jPathSets[1], 0, 0, 2, 2, | |
469 | function(path, x, y) { | |
470 | ctx.beginPath(); | |
471 | ctx.fillStyle = "yellow"; | |
472 | ctx.strokeStyle = "white"; | |
473 | var r = Math.random() * 2; | |
474 | if (Math.random() > 0.5) { | |
475 | r *= 1.5; | |
476 | //ctx.fillStyle = "white"; | |
477 | //ctx.strokeStyle = "#aaaaaa"; | |
478 | } | |
479 | ctx.arc(x, y, r, 0, Math.PI * 2, false); | |
480 | ctx.fill(); | |
481 | ctx.lineWidth = 0.5; | |
482 | ctx.stroke(); | |
483 | } | |
484 | ); | |
485 | } | |
486 | }, | |
487 | { | |
488 | onenter: function() { | |
489 | setQuotation( | |
490 | "[...] one anxiously awaits a movie in which her harmony won't be drowned out by the filmmaker's noodling.", | |
491 | 'http://www.metroactive.com/papers/metro/09.19.96/grace-heart-9638.html' | |
492 | ); | |
493 | }, | |
494 | draw: function () { | |
495 | ctx.fillStyle = "black"; | |
496 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
497 | }, | |
498 | mapstyle: mQuotationMapStyle | |
499 | } | |
500 | ], | |
501 | // row 4 | |
502 | [ | |
503 | { | |
504 | draw: function () { | |
505 | // SEQUENCE OF TRACINGS | |
506 | drawPaths(ctx, "white", jPathSets[0], 0, 0, 1, 1, | |
507 | function(p) { | |
508 | return p.title === 'outline'; | |
509 | }); | |
510 | drawPaths(ctx, "white", jPathSets[0], hx, 0, 1, 1, | |
511 | function(p) { | |
512 | return p.title === 'outline' | |
513 | || p.title === 'inner coat' | |
514 | || p.title === 'scarf'; | |
515 | }); | |
516 | drawPaths(ctx, "white", jPathSets[0], 0, hy, 1, 1, | |
517 | function(p) { | |
518 | return p.title === 'outline' | |
519 | || p.title === 'inner coat' | |
520 | || p.title === 'left neck' | |
521 | || p.title === 'scarf' | |
522 | || p.title === 'face'; | |
523 | }); | |
524 | drawPaths(ctx, "white", jPathSets[0], hx, hy, 1, 1); | |
525 | } | |
526 | }, | |
527 | undefined, | |
528 | { | |
529 | onenter: function() { | |
530 | setQuotation( | |
531 | "People sometimes say that the way things happen in movies is unreal, " + | |
532 | "but actually it's the way things happen in life that's unreal." | |
533 | ); | |
534 | }, | |
535 | mapstyle: quotationMapStyle | |
536 | }, | |
537 | { | |
538 | draw: function () { | |
539 | drawPaths(ctx, "#00aa00", jPathSets[0], 0, 0, 1, 1, | |
540 | function(p) { | |
541 | if (p.title === 'outline') { | |
542 | return {fillStyle:"#aa00aa"}; | |
543 | } else { | |
544 | return {lineWidth: 2, strokeStyle:"#000000"}; | |
545 | } | |
546 | }); | |
547 | drawPaths(ctx, "#aa00aa", jPathSets[0], hx, 0, 1, 1, | |
548 | function(p) { | |
549 | if (p.title === 'outline') { | |
550 | return {fillStyle:"#0000aa"}; | |
551 | } else { | |
552 | return {lineWidth: 2, strokeStyle:"#000000"}; | |
553 | } | |
554 | }); | |
555 | drawPaths(ctx, "#0000aa", jPathSets[0], 0, hy, 1, 1, | |
556 | function(p) { | |
557 | if (p.title === 'outline') { | |
558 | return {fillStyle:"#00aa00"}; | |
559 | } else { | |
560 | return {lineWidth: 2, strokeStyle:"#000000"}; | |
561 | } | |
562 | }); | |
563 | drawPaths(ctx, "#00aa00", jPathSets[0], hx, hy, 1, 1, | |
564 | function(p) { | |
565 | if (p.title === 'outline') { | |
566 | return {fillStyle:"#0000aa", | |
567 | lineWidth: 2, strokeStyle:"#ffffff"}; | |
568 | } else { | |
569 | return {lineWidth: 2, strokeStyle:"#ffffff"}; | |
570 | } | |
571 | }); | |
572 | } | |
573 | }, | |
574 | { | |
575 | draw: function () { | |
576 | // EIGHT ELVISES | |
577 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
578 | var dx = 50; | |
579 | var dy = 71; | |
580 | var s = 1.25; | |
581 | var o = {strokeStyle: "black", lineWidth: 1}; | |
582 | drawPaths(ctx, "transparent", jPathSets[1], 0-dx, dy, s, s, o) | |
583 | drawPaths(ctx, "transparent", jPathSets[1], (hx*0.25)-dx, dy+4, s, s, o); | |
584 | drawPaths(ctx, "transparent", jPathSets[1], (hx*0.50)-dx, dy+8, s, s, o); | |
585 | drawPaths(ctx, "transparent", jPathSets[1], (hx*0.75)-dx, dy, s, s, o); | |
586 | drawPaths(ctx, "transparent", jPathSets[1], (hx*1.00)-dx, dy-4, s, s, o); | |
587 | drawPaths(ctx, "transparent", jPathSets[1], (hx*1.12)-dx, dy, s, s, o); | |
588 | drawPaths(ctx, "transparent", jPathSets[1], (hx*1.20)-dx, dy-4, s, s, o); | |
589 | drawPaths(ctx, "transparent", jPathSets[1], (hx*1.25)-dx, dy-4, s, s, o); | |
590 | } | |
591 | }, | |
592 | { | |
593 | // LOTS OF COLOUR | |
594 | draw: function () { | |
595 | drawPaths(ctx, "#bbbbbb", jPathSets[2], 0, 0, 1, 1, | |
596 | function(p) { | |
597 | if (p.title === 'coat 1' || p.title === 'coat 2') { | |
598 | return {fillStyle:"#004444", strokeStyle:"black"}; | |
599 | } | |
600 | if (p.title === 'hair 1') { | |
601 | return {fillStyle:"#800000"}; | |
602 | } | |
603 | if (p.title === 'hair 2') { | |
604 | return {fillStyle:"#ff0000"}; | |
605 | } | |
606 | if (p.title === 'hair 3') { | |
607 | return {fillStyle:"#440000"}; | |
608 | } | |
609 | if (p.title === 'scarf') { | |
610 | return {fillStyle:"#d0d000", | |
611 | strokeStyle:"black", | |
612 | lineWitdh:2}; | |
613 | } | |
614 | if (p.title === 'vest') { | |
615 | return {fillStyle:"white"}; | |
616 | } | |
617 | }); | |
618 | drawPaths(ctx, "white", jPathSets[2], hx, 0, 1, 1, | |
619 | function(p) { | |
620 | if (p.title === 'coat 1' || p.title === 'coat 2') { | |
621 | return {fillStyle:"#440044", strokeStyle:"black"}; | |
622 | } | |
623 | if (p.title === 'hair 1') { | |
624 | return {fillStyle:"#008000"}; | |
625 | } | |
626 | if (p.title === 'hair 2') { | |
627 | return {fillStyle:"#00ff00"}; | |
628 | } | |
629 | if (p.title === 'hair 3') { | |
630 | return {fillStyle:"#004400"}; | |
631 | } | |
632 | if (p.title === 'scarf') { | |
633 | return {fillStyle:"#009999", | |
634 | strokeStyle:"black", | |
635 | lineWitdh:2}; | |
636 | } | |
637 | if (p.title === 'vest') { | |
638 | return {fillStyle:"black"}; | |
639 | } | |
640 | }); | |
641 | drawPaths(ctx, "white", jPathSets[2], 0, hy, 1, 1, | |
642 | function(p) { | |
643 | if (p.title === 'coat 1' || p.title === 'coat 2') { | |
644 | return {fillStyle:"#444400", strokeStyle:"black"}; | |
645 | } | |
646 | if (p.title === 'hair 1') { | |
647 | return {fillStyle:"#000080"}; | |
648 | } | |
649 | if (p.title === 'hair 2') { | |
650 | return {fillStyle:"#0000ff"}; | |
651 | } | |
652 | if (p.title === 'hair 3') { | |
653 | return {fillStyle:"#000044"}; | |
654 | } | |
655 | if (p.title === 'scarf') { | |
656 | return {fillStyle:"black", | |
657 | strokeStyle:"black", | |
658 | lineWitdh:2}; | |
659 | } | |
660 | if (p.title === 'vest') { | |
661 | return {fillStyle:"#808080"}; | |
662 | } | |
663 | }); | |
664 | drawPaths(ctx, "#bbbbbb", jPathSets[2], hx, hy, 1, 1); | |
665 | } | |
666 | }, | |
667 | undefined, | |
668 | undefined, | |
669 | undefined, | |
670 | undefined, | |
671 | { | |
672 | // "RONALD MC-WOMAN-ON-FILM" | |
673 | onenter: function () { | |
674 | currentJitter = 1.25; | |
675 | currentJitterRate = 3; | |
676 | quotation.innerHTML = ''; | |
677 | quotation.style.background = 'transparent'; | |
678 | }, | |
679 | draw: function () { | |
680 | drawPaths(ctx, "yellow", pathSets[0], 0, 0, 2, 2, | |
681 | {strokeStyle: "orange", lineWidth: 16}); | |
682 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
683 | {strokeStyle: "white", lineWidth: 14}); | |
684 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
685 | {strokeStyle: "red", lineWidth: 12}); | |
686 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
687 | {strokeStyle: "white", lineWidth: 10}); | |
688 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
689 | {strokeStyle: "orange", lineWidth: 8}); | |
690 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
691 | {strokeStyle: "white", lineWidth: 7}); | |
692 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
693 | {strokeStyle: "yellow", lineWidth: 6}); | |
694 | drawPaths(ctx, "transparent", jPathSets[0], 0, 0, 2, 2, | |
695 | {strokeStyle: "orange", lineWidth: 4}); | |
696 | drawPaths(ctx, "transparent", jPathSets[0], 0, 0, 2, 2, | |
697 | {strokeStyle: "red", lineWidth: 2}); | |
698 | drawPaths(ctx, "transparent", pathSets[0], 0, 0, 2, 2, | |
699 | {strokeStyle: "black", lineWidth: 1}); | |
700 | } | |
701 | }, | |
702 | { | |
703 | // ANGEL / DEVIL | |
704 | draw: function () { | |
705 | ctx.fillStyle = "red"; | |
706 | ctx.fillRect(0, 0, canvas.width / 2, canvas.height); | |
707 | ctx.fillStyle = "white"; | |
708 | ctx.fillRect(canvas.width / 2, 0, canvas.width / 2, canvas.height); | |
709 | ||
710 | drawPaths(ctx, "red", jPathSets[1], -10, hy * 0.25, 1, 1, | |
711 | {fillStyle: "white", strokeStyle: "white", lineWidth: 2}); | |
712 | ||
713 | ctx.beginPath(); | |
714 | var bx = 65; | |
715 | var by = 20; | |
716 | var bw = 40; | |
717 | ctx.moveTo(bx, by); | |
718 | ctx.bezierCurveTo(bx, by - 10, bx + bw, by - 10, bx + bw, by); | |
719 | ctx.bezierCurveTo(bx + bw, by + 10, bx, by + 10, bx, by); | |
720 | ctx.lineWidth = 3; | |
721 | ctx.strokeStyle = "yellow"; | |
722 | ctx.stroke(); | |
723 | ||
724 | drawPaths(ctx, "white", jPathSets[1], hx, hy * 0.25, 1, 1, | |
725 | {fillStyle: "red", strokeStyle: "red", lineWidth: 2}); | |
726 | ||
727 | ctx.beginPath(); | |
728 | var bx = hx + 70; | |
729 | var by = 20; | |
730 | var bw = 50; | |
731 | ctx.moveTo(bx, by); | |
732 | ctx.bezierCurveTo(bx, by + 30, bx + bw, by + 30, bx + bw, by); | |
733 | ctx.bezierCurveTo(bx + bw, by + 40, bx, by + 40, bx, by); | |
734 | ctx.fillStyle = "red"; | |
735 | ctx.fill(); | |
736 | ||
737 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2, | |
738 | {fillStyle: "black", strokeStyle: "white", lineWidth: 2}); | |
739 | drawPaths(ctx, "transparent", jPathSets[1], 0, 0, 2, 2, | |
740 | {strokeStyle: "red", lineWidth: 0.5}); | |
741 | } | |
742 | }, | |
743 | { | |
744 | // MOVING BARS | |
745 | draw: function () { | |
746 | ctx.fillStyle = "green"; | |
747 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
748 | var numBars = 10; | |
749 | var barWidth = Math.ceil(canvas.width / numBars); | |
750 | for (var i = 0; i < numBars + 2; i++) { | |
751 | ctx.fillStyle = i % 2 === 0 ? "black": "white"; | |
752 | var offs = (count + 40) % (barWidth * 2); | |
753 | ctx.fillRect(i * barWidth - offs, 0, barWidth, canvas.height); | |
754 | } | |
755 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2); | |
756 | for (var i = 0; i < numBars + 4; i++) { | |
757 | ctx.fillStyle = i % 4 === 0 ? "black": "transparent"; | |
758 | var offs = (count + 40) % (barWidth * 4); | |
759 | ctx.fillRect(i * barWidth - offs, 0, barWidth, canvas.height); | |
760 | } | |
761 | drawPaths(ctx, "transparent", jPathSets[2], 0, 0, 2, 2, | |
762 | function(p) { | |
763 | if (p.title === 'left eye' || | |
764 | p.title === 'right eye' || | |
765 | p.title === 'nose' || | |
766 | p.title === 'lips' || | |
767 | p.title === 'lip line') | |
768 | return {strokeStyle:"#400040", fillStyle:"#faaaaa", | |
769 | lineWidth:0.5}; | |
770 | if (p.title === 'left pupil' || | |
771 | p.title === 'right pupil' || | |
772 | p.title === 'button 1' || p.title === 'button 2') | |
773 | return true; | |
774 | return false; | |
775 | }); | |
776 | } | |
777 | } | |
778 | ], | |
779 | [ | |
780 | // row 5 | |
781 | undefined, | |
782 | undefined, | |
783 | undefined, | |
784 | undefined, | |
785 | undefined, | |
786 | undefined, | |
787 | undefined, | |
788 | undefined, | |
789 | undefined, | |
790 | undefined, | |
791 | undefined, | |
792 | { | |
793 | onenter: function() { | |
794 | setQuotation( | |
795 | "Now there was a Law in the Pyramid, tried and healthful, " + | |
796 | "which held that no male should have freedom to adventure " + | |
797 | "into the Night Land, before the age of twenty-two; " + | |
798 | "<em>and no female ever</em>.", | |
799 | "http://en.wikipedia.org/wiki/The_Night_Land" | |
800 | ); | |
801 | }, | |
802 | mapstyle: zQuotationMapStyle | |
803 | } | |
804 | ], | |
805 | [ | |
806 | // row 6 | |
807 | undefined, | |
808 | undefined, | |
809 | undefined, | |
810 | undefined, | |
811 | undefined, | |
812 | undefined, | |
813 | undefined, | |
814 | undefined, | |
815 | undefined, | |
816 | { | |
817 | onenter: function() { | |
818 | setQuotation( | |
819 | "And pride had we taken of ourselves to perceive those " + | |
820 | "monsters which had most of ugliness and horror to commend " + | |
821 | "them; for, thereby did we stand to have won the game of " + | |
822 | "watching, until such time as a more fearsome Brute be " + | |
823 | "discovered.", | |
824 | "http://en.wikipedia.org/wiki/The_Night_Land" | |
825 | ); | |
826 | }, | |
827 | mapstyle: zQuotationMapStyle | |
828 | }, | |
829 | { | |
830 | // HIGH JITTER 2 | |
831 | onenter: function () { | |
832 | currentJitter = 0; | |
833 | quotation.innerHTML = ''; | |
834 | quotation.style.background = 'transparent'; | |
835 | }, | |
836 | draw: function () { | |
837 | drawPaths(ctx, "gainsboro", jPathSets[1], 0, 0, 2, 2); | |
838 | if (currentJitter < 20) | |
839 | currentJitter += 0.025; | |
840 | } | |
841 | }, | |
842 | { | |
843 | // HIGH JITTER 1 | |
844 | onenter: function () { | |
845 | currentJitter = 4; | |
846 | quotation.innerHTML = ''; | |
847 | quotation.style.background = 'transparent'; | |
848 | }, | |
849 | draw: function () { | |
850 | drawPaths(ctx, "#303030", jPathSets[0], 0, 0, 2, 2); | |
851 | } | |
852 | } | |
853 | ], | |
854 | [ | |
855 | // row 7 (actually 6) | |
856 | undefined, | |
857 | undefined, | |
858 | undefined, | |
859 | undefined, | |
860 | undefined, | |
861 | undefined, | |
862 | undefined, | |
863 | undefined, | |
864 | undefined, | |
865 | { | |
866 | // HIGH JITTER 3 | |
867 | onenter: function () { | |
868 | persPathSet = clonePathSet(pathSets[2]); | |
869 | quotation.innerHTML = ''; | |
870 | quotation.style.background = 'transparent'; | |
871 | }, | |
872 | draw: function () { | |
873 | //var color = "rgba(" + (count % 256) + ",0,0,1.0)"; | |
874 | drawPaths(ctx, "white", persPathSet, 0, 0, 2, 2); | |
875 | // TODO this could be made more efficient | |
876 | // by in-place rewriting of points, but... whateva | |
877 | var newPathSet = []; | |
878 | for (var i = 0; i < persPathSet.length; i++) { | |
879 | newPathSet.push(mapWithJitter(persPathSet[i], 1)); | |
880 | } | |
881 | persPathSet = newPathSet; | |
882 | } | |
883 | } | |
884 | ], | |
885 | [ | |
886 | // row 8 (actually 7) | |
887 | undefined, | |
888 | undefined, | |
889 | undefined, | |
890 | undefined, | |
891 | undefined, | |
892 | undefined, | |
893 | undefined, | |
894 | undefined, | |
895 | undefined, | |
896 | { | |
897 | onenter: function() { | |
898 | setQuotation( | |
899 | "And so went the play; yet with ever, it doth " + | |
900 | "seem to me now, something of a half-known shudder to the " + | |
901 | "heart, and a child's rejoicing unknowingly in that safety " + | |
902 | "which had power to make light the seeming of such matters.", | |
903 | "http://en.wikipedia.org/wiki/The_Night_Land" | |
904 | ); | |
905 | }, | |
906 | mapstyle: zQuotationMapStyle | |
907 | } | |
908 | ] | |
909 | ]; | |
910 | ||
911 | this.getCfg = function(cx, cy) { | |
912 | var g = cmap[cy]; | |
913 | if (g === undefined) return undefined; | |
914 | return g[cx]; | |
915 | ||
916 | }; | |
917 | ||
918 | this.reJitterPaths = function() { | |
919 | for (var i = 0; i <= 2; i++) { | |
920 | var newPaths = []; | |
921 | for (var j = 0; j < pathSets[i].length; j++) { | |
922 | newPaths.push(mapWithJitter(pathSets[i][j], currentJitter)); | |
923 | } | |
924 | jPathSets[i] = newPaths; | |
925 | } | |
926 | }; | |
927 | ||
928 | this.showMap = function(setting) { | |
929 | if (setting === undefined) { | |
930 | mapShown = !mapShown; | |
931 | } else { | |
932 | mapShown = setting; | |
933 | } | |
934 | if (mapShown) { | |
935 | map.style.display = "inline"; | |
936 | quotation.style.display = "none"; | |
937 | } else { | |
938 | map.style.display = "none"; | |
939 | quotation.style.display = "table-cell"; | |
940 | } | |
941 | }; | |
942 | ||
943 | this.drawMap = function() { | |
944 | mapctx.clearRect(0, 0, map.width, map.height); | |
945 | var mapWidth = 14; | |
946 | var mapHeight = cmap.length; | |
947 | var sizeX = 25; | |
948 | var sizeY = 25; | |
949 | ||
950 | var offX = (map.width - (sizeX * mapWidth)) / 2 + sizeX * 0.2; | |
951 | var offY = (map.height - (sizeY * mapHeight)) / 2 + sizeY * 0.2; | |
952 | ||
953 | for (var y = 0; y <= mapHeight; y++) { | |
954 | var g = cmap[y]; | |
955 | if (g !== undefined) { | |
956 | for (var x = 0; x <= mapWidth; x++) { | |
957 | var style = "transparent"; | |
958 | if (g[x] !== undefined) { | |
959 | style = g[x].mapstyle || "rgba(0,0,0,0.5)"; | |
960 | if (x == cx && y == cy) { | |
961 | style = "rgba(255,0,0,0.5)"; | |
962 | } | |
963 | mapctx.fillStyle = style; | |
964 | mapctx.fillRect(x * sizeX + offX, y * sizeY + offY, | |
965 | sizeX * 0.8, sizeY * 0.8); | |
966 | mapctx.lineWidth = 1; | |
967 | mapctx.strokeStyle = "rgba(255,255,255,0.5)"; | |
968 | mapctx.strokeRect(x * sizeX + offX, y * sizeY + offY, | |
969 | sizeX * 0.8, sizeY * 0.8); | |
970 | } | |
971 | } | |
972 | } | |
973 | } | |
974 | }; | |
975 | ||
976 | this.enableArrowButtons = function() { | |
977 | buttons.up.disabled = (this.getCfg(cx, cy-1) === undefined); | |
978 | buttons.down.disabled = (this.getCfg(cx, cy+1) === undefined); | |
979 | buttons.left.disabled = (this.getCfg(cx-1, cy) === undefined); | |
980 | buttons.right.disabled = (this.getCfg(cx+1, cy) === undefined); | |
981 | this.showMap(false); | |
982 | }; | |
983 | ||
984 | this.move = function(dx, dy) { | |
985 | if (this.getCfg(cx+dx, cy+dy) === undefined) return; | |
986 | cx += dx; | |
987 | cy += dy; | |
988 | this.enableArrowButtons(); | |
989 | transitionFromDx = dx; | |
990 | transitionFromDy = dy; | |
991 | transitionCount = 0; | |
992 | count = 0; | |
993 | currentJitter = 0.7; | |
994 | currentJitterRate = 6; | |
995 | ||
996 | var cfg = this.getCfg(cx, cy); | |
997 | if (cfg.onenter !== undefined) { | |
998 | cfg.onenter(); | |
999 | } else { | |
1000 | quotation.innerHTML = ''; | |
1001 | quotation.style.background = 'transparent'; | |
1002 | } | |
1003 | if (cfg.draw === undefined) { | |
1004 | ctx.fillStyle = "black"; | |
1005 | ctx.fillRect(0, 0, canvas.width, canvas.height); | |
1006 | } else { | |
1007 | cfg.draw(); | |
1008 | } | |
1009 | }; | |
1010 | ||
1011 | var drawPaths = function(ctx, style, paths, x, y, sx, sy, where) { | |
1012 | ctx.save(); | |
1013 | ctx.translate(x, y); | |
1014 | ctx.scale(sx || 1, sy || 1); | |
1015 | ctx.fillStyle = style; | |
1016 | ctx.fillRect(0, 0, hx, hy); | |
1017 | for (var p = 0; p < paths.length; p++) { | |
1018 | var path = paths[p]; | |
1019 | var override = where; | |
1020 | if (typeof override === 'function') { | |
1021 | override = override(path); | |
1022 | } | |
1023 | if (override === false) continue; | |
1024 | if (typeof override === 'object') { | |
1025 | path.drawOverride(ctx, override); | |
1026 | } else { | |
1027 | path.draw(ctx, {lineWidth: 0.5}); | |
1028 | } | |
1029 | } | |
1030 | ctx.restore(); | |
1031 | }; | |
1032 | ||
1033 | var foreachPaths = function(ctx, style, paths, x, y, sx, sy, callback) { | |
1034 | ctx.save(); | |
1035 | ctx.translate(x, y); | |
1036 | ctx.scale(sx || 1, sy || 1); | |
1037 | ctx.fillStyle = style; | |
1038 | ctx.fillRect(0, 0, hx, hy); | |
1039 | for (var p = 0; p < paths.length; p++) { | |
1040 | var path = paths[p]; | |
1041 | for (var i = 0; i < path.points.length; i += 2) { | |
1042 | callback(path, path.points[i], path.points[i+1]) | |
1043 | } | |
1044 | } | |
1045 | ctx.restore(); | |
1046 | }; | |
1047 | ||
1048 | var setQuotation = function(text, link) { | |
1049 | link = link || "http://en.wikipedia.org/wiki/Andy_Warhol"; | |
1050 | quotation.innerHTML = '<a href="' + link + '">«' + text + '»</a>'; | |
1051 | quotation.style.background = 'black'; | |
1052 | }; | |
1053 | ||
1054 | this.init = function(c, q, m, b) { | |
1055 | canvas = c; | |
1056 | ctx = canvas.getContext('2d'); | |
1057 | quotation = q; | |
1058 | quotation.innerHTML = ''; | |
1059 | map = m; | |
1060 | buttons = b; | |
1061 | ||
1062 | var $this = this; | |
1063 | ||
1064 | buttons.up.onclick = function() { $this.move(0,-1); }; | |
1065 | buttons.down.onclick = function() { $this.move(0,1); }; | |
1066 | buttons.left.onclick = function() { $this.move(-1,0); }; | |
1067 | buttons.right.onclick = function() { $this.move(1,0); }; | |
1068 | buttons.showMap.onclick = function() { $this.showMap(); }; | |
1069 | ||
1070 | mapctx = map.getContext('2d'); | |
1071 | cx = 0; | |
1072 | cy = 1; | |
1073 | hx = canvas.width / 2; | |
1074 | hy = canvas.height / 2; | |
1075 | this.enableArrowButtons(); | |
1076 | currentJitter = 0.7; | |
1077 | this.reJitterPaths(); | |
1078 | var intervalId = setInterval(function() { | |
1079 | var cfg = $this.getCfg(cx, cy); | |
1080 | if (cfg === undefined) { | |
1081 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
1082 | } else { | |
1083 | if (count % currentJitterRate === 0) { | |
1084 | $this.reJitterPaths(); | |
1085 | } | |
1086 | if (cfg.draw !== undefined) { | |
1087 | cfg.draw(); | |
1088 | } | |
1089 | $this.drawMap(); | |
1090 | count++; | |
1091 | } | |
1092 | }, 16); | |
1093 | }; | |
1094 | }; |