/[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 - (hide 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 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    
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 wakaba 1.3 e('names', param.names || '(image)'),
187 wakaba 1.1 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