/[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.3 - (show annotations) (download) (as text)
Sun May 24 09:32:18 2009 UTC (15 years, 11 months ago) by wakaba
Branch: MAIN
Changes since 1.2: +1 -1 lines
File MIME type: text/html
typo

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 }
47 #panel p {
48 margin: 0;
49 padding: 0;
50 }
51 </style>
52
53 <body>
54
55 <canvas width=240 height=160></canvas>
56
57 <section id=panel hidden>
58
59 <p>
60 [<a href="javascript:setProp ('lineWidth', 1); togglePanel ()">1</a>
61 <a href="javascript:setProp ('lineWidth', 2); togglePanel ()">2</a>
62 <a href="javascript:setProp ('lineWidth', 3); togglePanel ()">3</a>
63 <a href="javascript:setProp ('lineWidth', 5); togglePanel ()">5</a>
64 <a href="javascript:setProp ('lineWidth', 10); togglePanel ()">10</a>]
65 </p>
66
67 <p>
68 [<a href="javascript:setProp ('strokeStyle', 'black'); togglePanel ()" style="color: black">black</a>
69 <a href="javascript:setProp ('strokeStyle', 'red'); togglePanel ()" style="color: red">red</a>
70 <a href="javascript:setProp ('strokeStyle', 'green'); togglePanel ()" style="color: green">green</a>
71 <a href="javascript:setProp ('strokeStyle', 'blue'); togglePanel ()" style="color: blue">blue</a>
72 <a href="javascript:setProp ('strokeStyle', 'orange'); togglePanel ()" style="color: orange">orange</a>
73 <a href="javascript:setProp ('strokeStyle', 'yellow'); togglePanel ()" style="color: yellow">yellow</a>
74 <a href="javascript:setProp ('strokeStyle', 'pink'); togglePanel ()" style="color: pink">pink</a>
75 <a href="javascript:setProp ('strokeStyle', 'purple'); togglePanel ()" style="color: purple">purple</a>
76 <a href="javascript:setProp ('strokeStyle', 'gray'); togglePanel ()" style="color: gray">gray</a>
77 <a href="javascript:setProp ('strokeStyle', 'white'); togglePanel ()" style="color: white">white</a>]
78 </p>
79
80 </section>
81
82 <menu><a href="javascript:togglePanel ()" class=editor-only>Panel</a>
83 <a href="javascript:savePNG ()" class=editor-only>PNGize</a>
84 <a href="client.html?mode=editor" id=edit-link rel=edit class=viewer-only>Edit</a>
85 <a href="client.html?mode=viewer" id=view-link class=editor-only>View</a>
86 <a href="server.cgi?mode=list" rel=index>List</a>
87 <a href="server.cgi?mode=prev" id=prev-link rel=prev>Prev</a>
88 <a href="server.cgi?mode=next" id=next-link rel=next>Next</a>
89 <a href="client.html?mode=editor" id=clone-link>Clone</a>
90 <a href="client.html?mode=editor">New</a></menu>
91
92 <script>
93 function $ (id) { return document.getElementById (id) }
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 date;
102 var q = (location.search || '').replace (/^\?/, '').split (/[&;]/);
103 var param = {};
104 for (var i = 0; i < q.length; i++) {
105 var p = q[i].split (/=/);
106 param[p[0]] = p[1];
107 }
108 date = parseInt (param.date) || new Date ().valueOf ();
109 var url = 'server.cgi?date=' + date;
110
111 $('edit-link').href += ';date=' + date;
112 $('view-link').href += ';date=' + date;
113 $('prev-link').href += ';date=' + date;
114 $('next-link').href += ';date=' + date;
115 $('clone-link').href += ';import-date=' + date;
116
117 param.mode = param.mode || 'editor';
118 document.body.className = 'mode-' + param.mode;
119
120 var newEvents = [];
121
122 if (param['import-date']) {
123 newEvents = readRemoteImage ('server.cgi?date=' + param['import-date']);
124 }
125
126 if (param.mode == 'viewer') {
127 readRemoteImage ();
128 setInterval (readRemoteImage, 2000);
129 } else {
130 var drawing = false;
131 canvas.onmousedown = function (ev) {
132 drawing = true;
133 ctx.beginPath ();
134 var x = ev.clientX;
135 var y = ev.clientY;
136 ctx.moveTo (x, y);
137 write ('moveTo', x, y);
138 };
139 canvas.onmousemove = function (ev) {
140 if (drawing) {
141 var x = ev.clientX;
142 var y = ev.clientY;
143 ctx.lineTo (x, y);
144 write ('lineTo', x, y);
145 ctx.stroke ();
146 // ctx.closePath ();
147 // ctx.beginPath ();
148 // ctx.moveTo (x, y);
149 }
150 };
151 window.onmouseup = function (ev) {
152 if (!drawing) return;
153 ctx.stroke ();
154 ctx.closePath ();
155 drawing = false;
156 };
157
158 function write () {
159 newEvents.push (Array.prototype.join.call (arguments, ','));
160 }
161
162 readRemoteImage ();
163 setInterval (function () {
164 if (newEvents.length) {
165 var xhr = new XMLHttpRequest ();
166 xhr.open ('POST', url, true);
167 xhr.setRequestHeader ('Content-Type', 'text/plain');
168 xhr.send (newEvents.join (';'));
169 newEvents = [];
170 }
171 }, 2000);
172 }
173
174 function setProp (n, v) {
175 ctx[n] = v;
176 write (n, v);
177 }
178
179 function readRemoteImage (u) {
180 u = u || url;
181 var xhr = new XMLHttpRequest ();
182 xhr.open ('GET', u, false);
183 xhr.setRequestHeader ('Cache-Control', 'no-cache');
184 xhr.send (null);
185 if (xhr.responseText) {
186 var events = xhr.responseText.split (/\x0A/);
187 if (events.length) {
188 canvas.width = canvas.width; // clear
189 processEvents(events);
190 }
191 return events;
192 }
193 return [];
194 }
195
196 function processEvents (events) {
197 for (var i = 0; i < events.length; i++) {
198 var ev = events[i].split (/,/);
199 if (ev[0] == 'lineTo') {
200 var x = parseFloat (ev[1]);
201 var y = parseFloat (ev[2]);
202 ctx.lineTo (x, y);
203 ctx.stroke ();
204 // ctx.closePath ();
205 // ctx.beginPath ();
206 // ctx.moveTo (x, y);
207 } else if (ev[0] == 'moveTo') {
208 var x = parseFloat (ev[1]);
209 var y = parseFloat (ev[2]);
210 ctx.moveTo (x, y);
211 } else if (ev[0] == 'strokeStyle' || ev[0] == 'lineWidth') {
212 ctx.closePath ();
213 ctx.beginPath ();
214 ctx[ev[0]] = ev[1];
215 }
216 }
217 }
218
219 function togglePanel () {
220 if ($('panel').hasAttribute ('hidden')) {
221 $('panel').removeAttribute ('hidden');
222 } else {
223 $('panel').setAttribute ('hidden', '');
224 }
225 }
226
227 function savePNG () {
228 var data = canvas.toDataURL ('image/png');
229 var xhr = new XMLHttpRequest ();
230 xhr.open ('POST', url + ';mode=png', false);
231 xhr.setRequestHeader ('Content-Type', 'text/plain');
232 xhr.send (data);
233 // if (xhr.status == 201) {
234 // location.href = xhr.getResponseHeader ('Location');
235 // }
236 }
237 </script>

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24