Another experiment, this one closer to an esolang interpreter.
--HG--
rename : javascript/canvas2.html => javascript/canvas3.html
rename : javascript/canvas2.js => javascript/canvas3.js
catseye
12 years ago
0 | <!DOCTYPE html> | |
1 | <head> | |
2 | <meta charset="utf-8"> | |
3 | <title>HTML5 Canvas experiment #3</title> | |
4 | <script src="http://code.jquery.com/jquery-1.8.1.min.js"></script> | |
5 | <script src="playfield.js"></script> | |
6 | <script src="canvas3.js"></script> | |
7 | <script> | |
8 | $(document).ready(function() { | |
9 | CanvasExperiment3($('#canvas')[0], $('#textarea'), $('#button')).start(); | |
10 | }); | |
11 | </script> | |
12 | <style> | |
13 | #canvas { border: 1px solid blue; } | |
14 | </style> | |
15 | </head> | |
16 | <body> | |
17 | ||
18 | <h1>HTML5 Canvas experiment #3</h1> | |
19 | ||
20 | <textarea id="textarea" rows="10" cols="40"> | |
21 | </textarea> | |
22 | ||
23 | <button id="button" value="Load">Load</button> | |
24 | ||
25 | <canvas id="canvas" width="400" height="400"> | |
26 | Your browser doesn't support displaying an HTML5 canvas. | |
27 | </canvas> | |
28 | ||
29 | </body> |
0 | function CanvasExperiment3(canvas, textarea, button) { | |
1 | var self = {}; | |
2 | var p; | |
3 | var interval_id; | |
4 | ||
5 | self.draw = function() { | |
6 | var ctx = canvas.getContext('2d'); | |
7 | ||
8 | ctx.clearRect(0, 0, canvas.width, canvas.height); | |
9 | ctx.textBaseline = "top"; | |
10 | ||
11 | var height = 20; | |
12 | ctx.font = height + "px monospace"; | |
13 | var width = ctx.measureText("@").width; | |
14 | ||
15 | p.foreach(function (x, y, value) { | |
16 | ctx.fillText(value, x * width, y * height); | |
17 | if (Math.random() > 0.95) { | |
18 | ctx.strokeStyle = "green"; | |
19 | ctx.strokeRect(x * width, y * height, width, height); | |
20 | } | |
21 | }); | |
22 | } | |
23 | ||
24 | self.start = function() { | |
25 | p = Playfield(); | |
26 | self.draw(); | |
27 | interval_id = setInterval(self.draw, 500); | |
28 | button.click(function() { | |
29 | p.load(0, 0, textarea.val()); | |
30 | self.draw(); | |
31 | }); | |
32 | } | |
33 | ||
34 | return self; | |
35 | } |
0 | 0 | function Playfield() { |
1 | 1 | var self = {} |
2 | 2 | var store = {} |
3 | var min_x; | |
4 | var min_y; | |
5 | var max_x; | |
6 | var max_y; | |
3 | self.min_x = undefined; | |
4 | self.min_y = undefined; | |
5 | self.max_x = undefined; | |
6 | self.max_y = undefined; | |
7 | 7 | |
8 | 8 | /* |
9 | 9 | * Cells are undefined if they were never written to. |
13 | 13 | } |
14 | 14 | |
15 | 15 | self.put = function(x, y, value) { |
16 | if (min_x === undefined || x < min_x) min_x = x; | |
17 | if (max_x === undefined || x > max_x) max_x = x; | |
18 | if (min_y === undefined || y < min_y) min_y = y; | |
19 | if (max_y === undefined || y > max_y) max_y = y; | |
16 | if (self.min_x === undefined || x < self.min_x) self.min_x = x; | |
17 | if (self.max_x === undefined || x > self.max_x) self.max_x = x; | |
18 | if (self.min_y === undefined || y < self.min_y) self.min_y = y; | |
19 | if (self.max_y === undefined || y > self.max_y) self.max_y = y; | |
20 | 20 | store[x+','+y] = value; |
21 | } | |
22 | ||
23 | /* | |
24 | * Load a string into the playfield. | |
25 | * The string may be multiline, with newline (ASCII 10) | |
26 | * characters delimiting lines. ASCII 13 is ignored. | |
27 | * A space in the string does not write anything into | |
28 | * the playfield. | |
29 | */ | |
30 | self.load = function(x, y, string) { | |
31 | var lx = x; | |
32 | var ly = y; | |
33 | for (var i = 0; i < string.length; i++) { | |
34 | var c = string.charAt(i); | |
35 | if (c === '\n') { | |
36 | lx = x; | |
37 | ly++; | |
38 | } else if (c === '\r') { | |
39 | } else if (c === ' ') { | |
40 | lx++; | |
41 | } else { | |
42 | self.put(lx, ly, c); | |
43 | lx++; | |
44 | } | |
45 | } | |
21 | 46 | } |
22 | 47 | |
23 | 48 | /* |
24 | 49 | * fun is a callback which takes three parameters: |
25 | 50 | * x, y, and value. |
51 | * This function ensures a particular order. | |
26 | 52 | */ |
27 | 53 | self.foreach = function(fun) { |
28 | for (var y = min_y; y <= max_y; y++) { | |
29 | for (var x = min_x; x <= max_x; x++) { | |
54 | for (var y = self.min_y; y <= self.max_y; y++) { | |
55 | for (var x = self.min_x; x <= self.max_x; x++) { | |
30 | 56 | var key = x+','+y; |
31 | 57 | var value = store[key]; |
32 | 58 | if (value === undefined) |