git @ Cat's Eye Technologies HTML5-Gewgaws / afe5618
A gewgaw is indentified by its dir; its "main" source is index.js. Chris Pressey 8 years ago
85 changed file(s) with 5206 addition(s) and 5206 deletion(s). Raw diff Collapse all Expand all
3434
3535 You ought to be able to say something like this to start any of these gewgaws:
3636
37 <script src="some-gewgaw.js"></script>
37 <script src="index.js"></script>
3838 <script>
3939 launch('../path/to/scripts', 'element_id', config);
4040 </script>
+0
-116
a-minimalist-critique/a-minimalist-critique.js less more
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 }
99 <div id="container"></div>
1010
1111 </body>
12 <script src="a-minimalist-critique.js"></script>
12 <script src="index.js"></script>
1313 <script>
1414 launch('../common-yoob.js-0.11/', 'container');
1515 </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
-277
a-non-random-walk/a-non-random-walk.js less more
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 }
1616 <div id="container"></div>
1717
1818 </body>
19 <script src="a-non-random-walk.js"></script>
19 <script src="index.js"></script>
2020 <script>
2121 launch('../common-yoob.js-0.11/', 'container');
2222 </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
-161
art-restoration-simulator/art-restoration-simulator.js less more
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 }
2121 <div id="container"></div>
2222
2323 </body>
24 <script src="art-restoration-simulator.js"></script>
24 <script src="index.js"></script>
2525 <script>
2626 launch('../common-yoob.js-0.11/', 'container');
2727 </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
-148
black-hole-poem/black-hole-poem.js less more
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 };
1919 <div id="container"></div>
2020
2121 </body>
22 <script src="black-hole-poem.js"></script>
22 <script src="index.js"></script>
2323 <script>
2424 launch('../common-yoob.js-0.11/', 'container');
2525 </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
-61
cheshire-text/cheshire-text.js less more
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 }
99 <div id="container"></div>
1010
1111 </body>
12 <script src="cheshire-text.js"></script>
12 <script src="index.js"></script>
1313 <script>
1414 launch('../common-yoob.js-0.11/', 'container');
1515 </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
-139
chzrxl/chzrxl.js less more
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 };
1616 <div id="container"></div>
1717
1818 </body>
19 <script src="chzrxl.js"></script>
19 <script src="index.js"></script>
2020 <script>
2121 launch('../common-yoob.js-0.11/', 'container');
2222 </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
-118
circus-xamulus/circus-xamulus.js less more
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 };
99 <div id="container"></div>
1010
1111 </body>
12 <script src="circus-xamulus.js"></script>
12 <script src="index.js"></script>
1313 <script>
1414 launch('../common-yoob.js-0.11/', 'container');
1515 </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
-290
cyclobots/cyclobots.js less more
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 };
3434 </header>
3535
3636 </body>
37 <script src="cyclobots.js"></script>
37 <script src="index.js"></script>
3838 <script>
3939 launch('../common-yoob.js-0.11/', 'container');
4040 </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
-133
eine-kleine-glitchfraktal/eine-kleine-glitchfraktal.js less more
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 };
99 <div id="container"></div>
1010
1111 </body>
12 <script src="eine-kleine-glitchfraktal.js"></script>
12 <script src="index.js"></script>
1313 <script>
1414 launch('../common-yoob.js-0.11/', 'container');
1515 </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
-117
fibonacci-spiral/fibonacci-spiral.js less more
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 };
1616 <div id="container"></div>
1717
1818 </body>
19 <script src="fibonacci-spiral.js"></script>
19 <script src="index.js"></script>
2020 <script>
2121 launch('../common-yoob.js-0.11/', 'container');
2222 </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
-203
fingerspelling/fingerspelling.js less more
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 };
1010 <div id="container"></div>
1111
1212 </body>
13 <script src="fingerspelling.js"></script>
13 <script src="index.js"></script>
1414 <script>
1515 launch('../common-yoob.js-0.11/', 'container');
1616 </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
-217
heronsis-hermnonicii/heronsis-hermnonicii.js less more
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 }
1616 <div id="container"></div>
1717
1818 </body>
19 <script src="heronsis-hermnonicii.js"></script>
19 <script src="index.js"></script>
2020 <script>
2121 launch('../common-yoob.js-0.11/', 'container');
2222 </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
-114
hirsute-miasma/hirsute-miasma.js less more
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 };
1616 <div id="container"></div>
1717
1818 </body>
19 <script src="hirsute-miasma.js"></script>
19 <script src="index.js"></script>
2020 <script>
2121 launch('../common-yoob.js-0.11/', 'container');
2222 </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
-206
hypongtrochoid/hypongtrochoid.js less more
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 }
1818 <div id="container"></div>
1919
2020 </body>
21 <script src="hypongtrochoid.js"></script>
21 <script src="index.js"></script>
2222 <script>
2323 launch('../common-yoob.js-0.11/', 'container');
2424 </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 }
1616 <div id="container"></div>
1717
1818 </body>
19 <script src="kolakoski-kurve.js"></script>
19 <script src="index.js"></script>
2020 <script>
2121 launch('../common-yoob.js-0.11/', 'container');
2222 </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
-154
kolakoski-kurve/kolakoski-kurve.js less more
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 };
2121 </div>
2222
2323 </body>
24 <script src="markov-font.js"></script>
24 <script src="index.js"></script>
2525 <script>
2626 launch('../common-yoob.js-0.11/', 'container', {
2727 // 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
-198
markov-font/markov-font.js less more
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 };
1818 <div id="container"></div>
1919
2020 </body>
21 <script src="multicolouralism.js"></script>
21 <script src="index.js"></script>
2222 <script>
2323 launch('../common-yoob.js-0.11/', 'container');
2424 </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
-133
multicolouralism/multicolouralism.js less more
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 }
1313 <div id="container"></div>
1414
1515 </body>
16 <script src="noise-to-signal-1.js"></script>
16 <script src="index.js"></script>
1717 <script>
1818 launch('../common-yoob.js-0.11/', 'container');
1919 </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
-139
noise-to-signal-1/noise-to-signal-1.js less more
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 };
1818 <div id="container"></div>
1919
2020 </body>
21 <script src="prairie.js"></script>
21 <script src="index.js"></script>
2222 <script>
2323 launch('../common-yoob.js-0.11/', 'container', {
2424 '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
-79
prairie/prairie.js less more
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 }
1818 <div id="container"></div>
1919
2020 </body>
21 <script src="progression.js"></script>
21 <script src="index.js"></script>
2222 <script>
2323 launch('../common-yoob.js-0.11/', 'container');
2424 </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
-59
progression/progression.js less more
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 }
1212 <div id="container"></div>
1313
1414 </body>
15 <script src="radialjective.js"></script>
15 <script src="index.js"></script>
1616 <script>
1717 launch('../common-yoob.js-0.11/', 'container');
1818 </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
-113
radialjective/radialjective.js less more
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 };
99 <div id="container"></div>
1010
1111 </body>
12 <script src="tentacles-undamped.js"></script>
12 <script src="index.js"></script>
1313 <script>
1414 launch('../common-yoob.js-0.11/', 'container');
1515 </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
-118
tentacles-undamped/tentacles-undamped.js less more
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 };
1313 </div>
1414
1515 </body>
16 <script src="text-uniquifier.js"></script>
16 <script src="index.js"></script>
1717 <script>
1818 launch('../common-yoob.js-0.11/', 'control_panel');
1919 </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 = "&nbsp;&nbsp;";
22 container.appendChild(span);
23 var puncSensitive = yoob.makeCheckbox(
24 container, true, "Punctuation-sensitive"
25 );
26 var preserve = yoob.makeSelect(
27 container, "&nbsp; 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
-118
text-uniquifier/text-uniquifier.js less more
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 = "&nbsp;&nbsp;";
22 container.appendChild(span);
23 var puncSensitive = yoob.makeCheckbox(
24 container, true, "Punctuation-sensitive"
25 );
26 var preserve = yoob.makeSelect(
27 container, "&nbsp; 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 };
1919 <div id="container"></div>
2020
2121 </body>
22 <script src="the-frame.js"></script>
22 <script src="index.js"></script>
2323 <script>
2424 launch('../common-yoob.js-0.11/', 'container', {
2525 '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
-151
the-frame/the-frame.js less more
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 };
1313 </div>
1414
1515 </body>
16 <script src="the-judgment-of-paris.js"></script>
16 <script src="index.js"></script>
1717 <script>
1818 launch('../common-yoob.js-0.11/', 'control_panel');
1919 </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
-173
the-judgment-of-paris/the-judgment-of-paris.js less more
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 };
1212 <div id="container"></div>
1313
1414 </body>
15 <script src="two-fifty-six.js"></script>
15 <script src="index.js"></script>
1616 <script>
1717 launch('../common-yoob.js-0.11/', 'container');
1818 </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
-241
two-fifty-six/two-fifty-six.js less more
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 }
99 <div id="container"></div>
1010
1111 </body>
12 <script src="uncle-ankur.js"></script>
12 <script src="index.js"></script>
1313 <script>
1414 launch('../common-yoob.js-0.11/', 'container');
1515 </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
-106
uncle-ankur/uncle-ankur.js less more
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 };
1515 <div id="container"></div>
1616
1717 </body>
18 <script src="woman-on-film.js"></script>
18 <script src="index.js"></script>
1919 <script>
2020 launch('../common-yoob.js-0.11/', 'container');
2121 </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
-1095
woman-on-film/woman-on-film.js less more
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 };