/[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 - (hide 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 wakaba 1.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 wakaba 1.4 font-size: smaller;
47 wakaba 1.1 }
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 wakaba 1.3 <a href="javascript:setProp ('lineWidth', 2); togglePanel ()">2</a>
63 wakaba 1.1 <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 wakaba 1.4 <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 wakaba 1.1 </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 wakaba 1.4 <a href="server.cgi?mode=next" id=next-link rel=next>Next</a></menu>
104 wakaba 1.1
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 wakaba 1.2 $('clone-link').href += ';import-date=' + date;
129 wakaba 1.1
130     param.mode = param.mode || 'editor';
131     document.body.className = 'mode-' + param.mode;
132    
133 wakaba 1.2 var newEvents = [];
134    
135     if (param['import-date']) {
136     newEvents = readRemoteImage ('server.cgi?date=' + param['import-date']);
137     }
138    
139 wakaba 1.1 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 wakaba 1.2 function readRemoteImage (u) {
193     u = u || url;
194 wakaba 1.1 var xhr = new XMLHttpRequest ();
195 wakaba 1.2 xhr.open ('GET', u, false);
196 wakaba 1.1 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 wakaba 1.2 return events;
205 wakaba 1.1 }
206 wakaba 1.2 return [];
207 wakaba 1.1 }
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 wakaba 1.2 }
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 wakaba 1.4 }
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 wakaba 1.1 }
260     </script>

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24