/[suikacvs]/webroot/swe/pages/canvas.html
Suika

Contents of /webroot/swe/pages/canvas.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations) (download) (as text)
Mon Sep 14 06:23:33 2009 UTC (15 years, 2 months ago) by wakaba
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +1 -1 lines
File MIME type: text/html
++ swe/pages/ChangeLog	14 Sep 2009 06:23:13 -0000
	* canvas.html: Set the default page name to "(image)".

2009-09-14  Wakaba  <wakaba@suika.fam.cx>

1 <!DOCTYPE HTML>
2 <html lang=en>
3 <title>Canvas</title>
4 <meta name="viewport" content="width=device-width">
5 <style>
6 body {
7 margin: 0;
8 padding: 0;
9 background: #C0C0C0;
10 }
11 canvas {
12 width: 240px;
13 background: white;
14 }
15
16 a {
17 display: inline-block;
18 min-width: 1em;
19 text-align: center;
20 }
21 menu {
22 position: fixed;
23 bottom: 0;
24 width: 100%;
25 margin: 0;
26 padding: 0;
27 font-size: 8px;
28 }
29
30 [hidden] {
31 display: none;
32 }
33 #panel {
34 position: absolute;
35 left: 20px;
36 width: 200px; /* 240px - 20px * 2 */
37 top: 20px;
38 max-height: 120px; /* 160px - 20px * 2 */
39 overflow: auto;
40 background-color: #C0C0C0;
41 font-size: smaller;
42 }
43 #panel p {
44 margin: 0;
45 padding: 0;
46 }
47 </style>
48
49 <body>
50
51 <canvas width=240 height=160></canvas>
52
53 <section id=panel hidden>
54
55 <p>
56 [<a href="javascript:setProp ('lineWidth', 1); togglePanel ()">1</a>
57 <a href="javascript:setProp ('lineWidth', 2); togglePanel ()">2</a>
58 <a href="javascript:setProp ('lineWidth', 3); togglePanel ()">3</a>
59 <a href="javascript:setProp ('lineWidth', 5); togglePanel ()">5</a>
60 <a href="javascript:setProp ('lineWidth', 10); togglePanel ()">10</a>]
61 </p>
62
63 <p>
64 [<a href="javascript:setProp ('strokeStyle', 'black'); togglePanel ()" style="color: black">black</a>
65 <a href="javascript:setProp ('strokeStyle', 'red'); togglePanel ()" style="color: red">red</a>
66 <a href="javascript:setProp ('strokeStyle', 'green'); togglePanel ()" style="color: green">green</a>
67 <a href="javascript:setProp ('strokeStyle', 'blue'); togglePanel ()" style="color: blue">blue</a>
68 <a href="javascript:setProp ('strokeStyle', 'orange'); togglePanel ()" style="color: orange">orange</a>
69 <a href="javascript:setProp ('strokeStyle', 'yellow'); togglePanel ()" style="color: yellow">yellow</a>
70 <a href="javascript:setProp ('strokeStyle', 'pink'); togglePanel ()" style="color: pink">pink</a>
71 <a href="javascript:setProp ('strokeStyle', 'purple'); togglePanel ()" style="color: purple">purple</a>
72 <a href="javascript:setProp ('strokeStyle', 'gray'); togglePanel ()" style="color: gray">gray</a>
73 <a href="javascript:setProp ('strokeStyle', 'white'); togglePanel ()" style="color: white">white</a>]
74 </p>
75
76 <hr>
77
78 <a id=show-image-page>Show image page</a>
79
80 </section>
81
82 <menu><a href="javascript:togglePanel ()">Panel</a>
83 <a href="javascript:saveImage ()">Save</a>
84 <span id=status></span></menu>
85
86 <script>
87 function $ (id) { return document.getElementById (id) }
88
89 function setStatus (s) {
90 var status = $ ('status');
91 status.innerText = s;
92 status.textContent = s;
93 } // setStatus
94
95 var canvas = document.getElementsByTagName('canvas')[0];
96 var ctx = canvas.getContext('2d');
97 ctx.lineCap = 'round';
98 ctx.lineWidth = 3;
99 ctx.beginPath ();
100
101 var q = (location.search || '').replace (/^\?/, '').split (/[&;]/);
102 var param = {};
103 for (var i = 0; i < q.length; i++) {
104 var p = q[i].split (/=/);
105 param[decodeURIComponent (p[0])] = decodeURIComponent (p[1]);
106 }
107
108 var drawing = false;
109 canvas.onmousedown = function (ev) {
110 drawing = true;
111 ctx.beginPath ();
112 var x = ev.clientX;
113 var y = ev.clientY;
114 ctx.moveTo (x, y);
115 write ('moveTo', x, y);
116 };
117 canvas.onmousemove = function (ev) {
118 if (drawing) {
119 var x = ev.clientX;
120 var y = ev.clientY;
121 ctx.lineTo (x, y);
122 write ('lineTo', x, y);
123 ctx.stroke ();
124 // ctx.closePath ();
125 // ctx.beginPath ();
126 // ctx.moveTo (x, y);
127 }
128 };
129 window.onmouseup = function (ev) {
130 if (!drawing) return;
131 ctx.stroke ();
132 ctx.closePath ();
133 drawing = false;
134 };
135
136 var newEvents = [];
137
138 if (param['input-url']) {
139 newEvents = readRemoteImage (param['input-url']);
140 } else {
141 write ('lineCap', 'round');
142 write ('lineWidth', 3);
143 }
144
145 function write () {
146 setStatus ('Modified');
147 newEvents.push (Array.prototype.join.call (arguments, ','));
148 }
149
150 function setProp (n, v) {
151 ctx[n] = v;
152 write (n, v);
153 }
154
155 function saveImage () {
156 setStatus ('Saving...');
157 var xhr = new XMLHttpRequest ();
158 xhr.open ('POST', param['post-url'], true);
159 xhr.setRequestHeader ('Content-Type', 'application/x-www-form-urlencoded');
160 var e = function (n, v) {
161 return encodeURIComponent (n) + '=' + encodeURIComponent (v);
162 };
163 xhr.onreadystatechange = function () {
164 if (xhr.readyState == 4) {
165 if (xhr.status >= 200 && xhr.status < 400) {
166 setStatus ('Saved');
167 } else {
168 setStatus ('Failed (' + xhr.status + ')');
169 }
170 var location = xhr.getResponseHeader ('Location');
171 if (location) {
172 $('show-image-page').href = location;
173 }
174 var postURL = xhr.getResponseHeader ('X-SW-Post-URL');
175 if (postURL) {
176 param['post-url'] = postURL;
177 }
178 param.hash = xhr.getResponseHeader ('X-SW-Hash');
179 xhr.onreadystate = null;
180 }
181 };
182 xhr.send ([
183 e('text', newEvents.join ("\n")),
184 e('content-type', 'image/x-canvas-instructions+text'),
185 e('hash', param.hash),
186 e('names', param.names || '(image)'),
187 e('no-redirect', 1)
188 ].join ('&'));
189 }
190
191 function readRemoteImage (u) {
192 var xhr = new XMLHttpRequest ();
193 xhr.open ('GET', u, false);
194 xhr.setRequestHeader ('Cache-Control', 'no-cache');
195 xhr.send (null);
196 if (xhr.responseText) {
197 var events = xhr.responseText.split (/\x0A/);
198 if (events.length) {
199 canvas.width = canvas.width; // clear
200 processEvents(events);
201 }
202 var hash = xhr.getResponseHeader ('X-SW-Hash');
203 if (hash) {
204 param.hash = hash;
205 }
206 return events;
207 }
208 return [];
209 }
210
211 function processEvents (events) {
212 for (var i = 0; i < events.length; i++) {
213 var ev = events[i].split (/,/);
214 if (ev[0] == 'lineTo') {
215 var x = parseFloat (ev[1]);
216 var y = parseFloat (ev[2]);
217 ctx.lineTo (x, y);
218 ctx.stroke ();
219 // ctx.closePath ();
220 // ctx.beginPath ();
221 // ctx.moveTo (x, y);
222 } else if (ev[0] == 'moveTo') {
223 var x = parseFloat (ev[1]);
224 var y = parseFloat (ev[2]);
225 ctx.moveTo (x, y);
226 } else if (ev[0] == 'strokeStyle' || ev[0] == 'lineWidth') {
227 ctx.closePath ();
228 ctx.beginPath ();
229 ctx[ev[0]] = ev[1];
230 }
231 }
232 }
233
234 function togglePanel () {
235 if ($('panel').hasAttribute ('hidden')) {
236 $('panel').removeAttribute ('hidden');
237 } else {
238 $('panel').setAttribute ('hidden', '');
239 }
240 }
241
242 </script>

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24