/[suikacvs]/webroot/www/canvas/remote/client.html
Suika

Contents of /webroot/www/canvas/remote/client.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations) (download) (as text)
Sun May 24 13:36:58 2009 UTC (15 years, 11 months ago) by wakaba
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +28 -5 lines
File MIME type: text/html
posting to hatena haiku

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 .mode-viewer canvas {
16 width: 100%;
17 }
18 a {
19 display: inline-block;
20 min-width: 1em;
21 text-align: center;
22 }
23 menu {
24 position: fixed;
25 bottom: 0;
26 width: 100%;
27 margin: 0;
28 padding: 0;
29 font-size: 8px;
30 }
31 .mode-editor menu .viewer-only,
32 .mode-viewer menu .editor-only {
33 display: none;
34 }
35 [hidden] {
36 display: none;
37 }
38 #panel {
39 position: absolute;
40 left: 20px;
41 width: 200px; /* 240px - 20px * 2 */
42 top: 20px;
43 max-height: 120px; /* 160px - 20px * 2 */
44 overflow: auto;
45 background-color: #C0C0C0;
46 font-size: smaller;
47 }
48 #panel p {
49 margin: 0;
50 padding: 0;
51 }
52 </style>
53
54 <body>
55
56 <canvas width=240 height=160></canvas>
57
58 <section id=panel hidden>
59
60 <p>
61 [<a href="javascript:setProp ('lineWidth', 1); togglePanel ()">1</a>
62 <a href="javascript:setProp ('lineWidth', 2); togglePanel ()">2</a>
63 <a href="javascript:setProp ('lineWidth', 3); togglePanel ()">3</a>
64 <a href="javascript:setProp ('lineWidth', 5); togglePanel ()">5</a>
65 <a href="javascript:setProp ('lineWidth', 10); togglePanel ()">10</a>]
66 </p>
67
68 <p>
69 [<a href="javascript:setProp ('strokeStyle', 'black'); togglePanel ()" style="color: black">black</a>
70 <a href="javascript:setProp ('strokeStyle', 'red'); togglePanel ()" style="color: red">red</a>
71 <a href="javascript:setProp ('strokeStyle', 'green'); togglePanel ()" style="color: green">green</a>
72 <a href="javascript:setProp ('strokeStyle', 'blue'); togglePanel ()" style="color: blue">blue</a>
73 <a href="javascript:setProp ('strokeStyle', 'orange'); togglePanel ()" style="color: orange">orange</a>
74 <a href="javascript:setProp ('strokeStyle', 'yellow'); togglePanel ()" style="color: yellow">yellow</a>
75 <a href="javascript:setProp ('strokeStyle', 'pink'); togglePanel ()" style="color: pink">pink</a>
76 <a href="javascript:setProp ('strokeStyle', 'purple'); togglePanel ()" style="color: purple">purple</a>
77 <a href="javascript:setProp ('strokeStyle', 'gray'); togglePanel ()" style="color: gray">gray</a>
78 <a href="javascript:setProp ('strokeStyle', 'white'); togglePanel ()" style="color: white">white</a>]
79 </p>
80
81 <hr>
82
83 <p>
84 <a href="javascript:savePNG (); togglePanel ()" class=editor-only>PNGize</a>
85 <a href="javascript:haiku (); togglePanel ()" class=editor-only>Haiku</a>
86 </p>
87
88 <p>
89 <a href="client.html?mode=editor" id=clone-link>Clone</a>
90 <a href="client.html?mode=editor">New</a></menu>
91 </p>
92
93 <p>
94 <a href="server.cgi?mode=list" rel=index>List</a>
95 </p>
96
97 </section>
98
99 <menu><a href="javascript:togglePanel ()" class=editor-only>Panel</a>
100 <a href="client.html?mode=editor" id=edit-link rel=edit class=viewer-only>Edit</a>
101 <a href="client.html?mode=viewer" id=view-link class=editor-only>View</a>
102 <a href="server.cgi?mode=prev" id=prev-link rel=prev>Prev</a>
103 <a href="server.cgi?mode=next" id=next-link rel=next>Next</a></menu>
104
105 <script>
106 function $ (id) { return document.getElementById (id) }
107
108 var canvas = document.getElementsByTagName('canvas')[0];
109 var ctx = canvas.getContext('2d');
110 ctx.lineCap = 'round';
111 ctx.lineWidth = 3;
112 ctx.beginPath ();
113
114 var date;
115 var q = (location.search || '').replace (/^\?/, '').split (/[&;]/);
116 var param = {};
117 for (var i = 0; i < q.length; i++) {
118 var p = q[i].split (/=/);
119 param[p[0]] = p[1];
120 }
121 date = parseInt (param.date) || new Date ().valueOf ();
122 var url = 'server.cgi?date=' + date;
123
124 $('edit-link').href += ';date=' + date;
125 $('view-link').href += ';date=' + date;
126 $('prev-link').href += ';date=' + date;
127 $('next-link').href += ';date=' + date;
128 $('clone-link').href += ';import-date=' + date;
129
130 param.mode = param.mode || 'editor';
131 document.body.className = 'mode-' + param.mode;
132
133 var newEvents = [];
134
135 if (param['import-date']) {
136 newEvents = readRemoteImage ('server.cgi?date=' + param['import-date']);
137 }
138
139 if (param.mode == 'viewer') {
140 readRemoteImage ();
141 setInterval (readRemoteImage, 2000);
142 } else {
143 var drawing = false;
144 canvas.onmousedown = function (ev) {
145 drawing = true;
146 ctx.beginPath ();
147 var x = ev.clientX;
148 var y = ev.clientY;
149 ctx.moveTo (x, y);
150 write ('moveTo', x, y);
151 };
152 canvas.onmousemove = function (ev) {
153 if (drawing) {
154 var x = ev.clientX;
155 var y = ev.clientY;
156 ctx.lineTo (x, y);
157 write ('lineTo', x, y);
158 ctx.stroke ();
159 // ctx.closePath ();
160 // ctx.beginPath ();
161 // ctx.moveTo (x, y);
162 }
163 };
164 window.onmouseup = function (ev) {
165 if (!drawing) return;
166 ctx.stroke ();
167 ctx.closePath ();
168 drawing = false;
169 };
170
171 function write () {
172 newEvents.push (Array.prototype.join.call (arguments, ','));
173 }
174
175 readRemoteImage ();
176 setInterval (function () {
177 if (newEvents.length) {
178 var xhr = new XMLHttpRequest ();
179 xhr.open ('POST', url, true);
180 xhr.setRequestHeader ('Content-Type', 'text/plain');
181 xhr.send (newEvents.join (';'));
182 newEvents = [];
183 }
184 }, 2000);
185 }
186
187 function setProp (n, v) {
188 ctx[n] = v;
189 write (n, v);
190 }
191
192 function readRemoteImage (u) {
193 u = u || url;
194 var xhr = new XMLHttpRequest ();
195 xhr.open ('GET', u, false);
196 xhr.setRequestHeader ('Cache-Control', 'no-cache');
197 xhr.send (null);
198 if (xhr.responseText) {
199 var events = xhr.responseText.split (/\x0A/);
200 if (events.length) {
201 canvas.width = canvas.width; // clear
202 processEvents(events);
203 }
204 return events;
205 }
206 return [];
207 }
208
209 function processEvents (events) {
210 for (var i = 0; i < events.length; i++) {
211 var ev = events[i].split (/,/);
212 if (ev[0] == 'lineTo') {
213 var x = parseFloat (ev[1]);
214 var y = parseFloat (ev[2]);
215 ctx.lineTo (x, y);
216 ctx.stroke ();
217 // ctx.closePath ();
218 // ctx.beginPath ();
219 // ctx.moveTo (x, y);
220 } else if (ev[0] == 'moveTo') {
221 var x = parseFloat (ev[1]);
222 var y = parseFloat (ev[2]);
223 ctx.moveTo (x, y);
224 } else if (ev[0] == 'strokeStyle' || ev[0] == 'lineWidth') {
225 ctx.closePath ();
226 ctx.beginPath ();
227 ctx[ev[0]] = ev[1];
228 }
229 }
230 }
231
232 function togglePanel () {
233 if ($('panel').hasAttribute ('hidden')) {
234 $('panel').removeAttribute ('hidden');
235 } else {
236 $('panel').setAttribute ('hidden', '');
237 }
238 }
239
240 function savePNG () {
241 var data = canvas.toDataURL ('image/png');
242 var xhr = new XMLHttpRequest ();
243 xhr.open ('POST', url + ';mode=png', false);
244 xhr.setRequestHeader ('Content-Type', 'text/plain');
245 xhr.send (data);
246 // if (xhr.status == 201) {
247 // location.href = xhr.getResponseHeader ('Location');
248 // }
249 }
250
251 function haiku () {
252 var purl = url.replace (/server\.cgi/, 'proxy.php');
253 var data = canvas.toDataURL ('image/png');
254 var xhr = new XMLHttpRequest ();
255 xhr.open ('POST', purl + ';mode=haiku', true);
256 xhr.setRequestHeader ('Content-Type', 'text/plain');
257 xhr.setRequestHeader ('X-Data-URL', data);
258 xhr.send (null);
259 }
260 </script>

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24