UNPKG

40.7 kBJavaScriptView Raw
1/**
2* Sutton SignWriting SignMaker 2022
3* https://github.com/sutton-signwriting/signmaker
4* Copyright (c) 2007-2021, Steve Slevinski
5* SignMaker is released under the MIT License.
6*/
7var isApp = false;
8
9var isiFrame = (window.location !== window.parent.location);
10
11function receiveMessage(event) {
12 setS(event.data);
13}
14// event listener for message event
15window.addEventListener("message", receiveMessage, false);
16
17//translations
18var t;
19var allSignLang = {};
20allSignLang['alphabet']=Object.keys(defmessages).filter(function(key){return (key.slice(0,4)=="sgn_");});
21var signLang={};
22signLang['alphabet'] = allSignLang['alphabet'].slice(0);
23function checkSignLang(type) {
24 //type=alphabet or other
25 if (!allSignLang[type].length) return;
26 var key = allSignLang[type].shift();
27 var url = 'config/' + type + "/" + type + '-' + key.slice(4) + '.js';
28 var xhr = new XMLHttpRequest();
29 xhr.open('HEAD', url, true);
30 xhr.onload = function (e) {
31 if (xhr.status == 404) {
32 var index = signLang[type].indexOf(key);
33 if (index > -1) {
34 signLang[type].splice(index, 1);
35 }
36 }
37 checkSignLang(type);
38 };
39 xhr.onerror = function (e) {
40 var index = signLang[type].indexOf(key);
41 if (index > -1) {
42 signLang[type].splice(index, 1);
43 }
44 checkSignLang(type);
45 };
46 xhr.send(null);
47}
48
49function tt(args){
50 text = t.apply(this,arguments);
51 text = text.replace(/@@/g,'');
52 return m.trust(ssw.svg(text) || '<p>' + text + '</p>');
53}
54
55window.onresize = function (){
56 m.redraw();
57}
58
59function setS(obj){
60 Object.keys(obj).map( key => {
61 val = obj[key];
62 if (S[key] == val) return;
63 switch (key) {
64 case 'ui':
65 if(t && val==S['ui']) return;
66 var msg = messages[val];
67 if (!msg) {
68 val='en';
69 msg = messages[val];
70 }
71 S['ui']=val;
72 for (var attr in defmessages) { if(!msg[attr]) msg[attr]=defmessages[attr];}
73 t = libTranslate.getTranslationFunction(msg);
74 break;
75 case 'alphabet':
76 S['alphabet']=val;
77 classie.addClass(document.body,"waiting");
78 var js = document.createElement("script");
79 js.type = "text/javascript";
80 delete window.alphabet;
81 if (val == 'iswa' || val == ''){
82 js.src = "config/alphabet.js?" + Date.now();
83 } else {
84 js.src = "config/alphabet/alphabet-" + val + ".js?" + Date.now();
85 }
86 document.getElementsByTagName('head')[0].appendChild(js);
87 var jsCheck = setInterval(function(){
88 if (window.alphabet && palette){
89 classie.removeClass(document.body,"waiting");
90 palette.vm.init();
91 palette.vm.select();
92 m.redraw();
93 clearInterval(jsCheck);
94 }
95 },100);
96 break;
97 case 'fsw':
98 S['fsw'] = val;
99 signmaker && signmaker.vm.fsw(val);
100 break;
101 case 'charsets':
102 S['charsets'] = val;
103 console.log("charset to hash?");
104 break;
105 case 'swu':
106 val = decodeURI(val)
107 S['swu'] = val;
108 signmaker && signmaker.vm.swu(val);
109 break;
110 case 'styling':
111 S['styling'] = val;
112 break;
113 case 'grid':
114 S['grid'] = val;
115 break;
116 case 'skin':
117 S['skin'] = val;
118 document.body.className=val;
119 break;
120 case 'tab':
121 S['tab'] = val;
122 break;
123 }
124 })
125 m.redraw();
126}
127
128//state
129var S = { // state
130 'ui': undefined,
131 'alphabet': undefined,
132 'fsw': undefined,
133 'charsets': undefined,
134 'swu': undefined,
135 'styling': undefined,
136 'grid': undefined,
137 'skin': undefined,
138 'tab': undefined
139}
140
141var D = { // defaults
142 'ui': 'en',
143 'alphabet': 'iswa',
144 'grid': '1',
145 'tab': ''
146}
147
148function hash(){
149 S['fsw'] = signmaker.vm.fswnorm();
150 if (S['charsets']) S['swu'] = signmaker.vm.swunorm();
151 return "?" + Object.keys(S).map(function(key){
152 return (S[key] && (D[key] != S[key]))?key+"="+S[key]:undefined
153 }).filter(item => item !== undefined).join("&");
154}
155function hashSet(){
156 // history.replaceState(null, null, document.location.pathname + '#' + hash);
157 history.pushState(null, null, document.location.pathname + '#' + hash());
158 // window.location.hash = hash;
159}
160
161window.onhashchange = hashChange;
162function hashChange(event){
163 var parts;
164 var hashed = {}
165 var iloc = window.location.href.indexOf('#?');
166 if (iloc>-1) {
167 var hashes = decodeURI(window.location.href.slice(iloc + 2)).split('&');
168 for(var i = 0; i < hashes.length; i++) {
169 parts = hashes[i].split('=');
170 if (parts[0]) hashed[parts[0]] = parts[1];
171 }
172 }
173
174 hashed = {...D, ...hashed}
175 Object.keys(hashed).forEach(key => {
176 if (!(key in S)) {
177 hashed[key] = undefined;
178 }
179 })
180 setS(hashed);
181}
182
183
184
185hashChange();
186
187// SIGNMAKER
188////////////
189var dlFile = null;
190var spatials = {};
191
192spatials.Symbol = function(data) {
193 this.key = m.prop(data.key);
194 this.x = m.prop(data.x);
195 this.y = m.prop(data.y);
196 this.selected = m.prop(true);
197};
198
199spatials.List = Array;
200
201
202var signmaker = {};
203
204// vm
205signmaker.vm = {
206 midWidth: 125,
207 midHeight: 125,
208 new: function(){
209 signmaker.vm.list=new spatials.List();
210 signmaker.vm.sort=[];
211 signmaker.vm.history = ['{"list":[],"sort":[]'];
212 signmaker.vm.cursor = 0;
213 },
214 save: function(){
215 if (isiFrame){
216 parent.postMessage({'signmaker': 'save', 'swu': signmaker.vm.swunorm(), 'fsw': signmaker.vm.fswnorm()},"*")
217 } else {
218 hashSet();
219 console.log(window.location.href)
220 }
221 },
222 share: function(){
223 if (navigator.share) {
224 navigator.share({'url': document.location.href})
225 } else {
226 console.log(window.location.href);
227 }
228 },
229 demo: function(){
230 window.location = "./demo.html#" + hash();
231 },
232 cancel: function(){
233 if (isiFrame){
234 parent.postMessage({'signmaker': 'cancel'},"*")
235 }
236 //signmaker.vm.clear();
237 palette.vm.action = false;
238 },
239 fswlive: function(){
240 var fsw = 'M500x500';
241 if (signmaker.vm.sort.length) fsw = "A" + signmaker.vm.sort.join('') + fsw;
242 if (signmaker.vm.list.length){
243 for (var i=0; i < signmaker.vm.list.length; i++) {
244 fsw += signmaker.vm.list[i].key() + signmaker.vm.list[i].x() + 'x' + signmaker.vm.list[i].y();
245 }
246 var bbox = ssw.bbox(ssw.max(fsw)).split(' ');
247 fsw = fsw.replace("M500x500","M" + bbox[1] + 'x' + bbox[3]);
248 }
249 return fsw=="M500x500"?'':fsw;
250 },
251 swulive: function(){
252 return ssw.fsw2swu(signmaker.vm.fswlive());
253 },
254 swunorm: function(){
255 return ssw.fsw2swu(signmaker.vm.fswnorm());
256 },
257 fswnorm: function(){
258 return ssw.norm(signmaker.vm.fswlive());
259 },
260 fsw: function(fsw,silent){
261 if (typeof(fsw)!='undefined') {
262 fsw = ssw.sign(fsw);
263 var syms = fsw.match(/S[1-3][0-9a-f]{2}[0-5][0-9a-f][0-9]{3}x[0-9]{3}/g) || [];
264 signmaker.vm.list = new spatials.List();
265 for (var i=0; i < syms.length; i++) {
266 signmaker.vm.list.push(new spatials.Symbol({key:syms[i].slice(0,6),x:parseInt(syms[i].slice(6,9)),y:parseInt(syms[i].slice(10,13))}))
267 }
268 syms = fsw.match(/A(S[1-3][0-9a-f]{2}[0-5][0-9a-f])+/) || [];
269 if (syms.length) {
270 signmaker.vm.sort= syms[0].slice(1).match(/.{6}/g);
271 } else {
272 signmaker.vm.sort = [];
273 }
274 signmaker.vm.addhistory(silent);
275 signmaker.vm.selnone();
276
277 }
278 return signmaker.vm.fswlive();
279 },
280 fswraw: '',
281 fswview: function(fsw){
282 if (typeof(fsw)!='undefined') {
283 signmaker.vm.fswraw = fsw;
284 signmaker.vm.swuraw = '';
285 fsw = ssw.parse(fsw,"fsw")["fsw"];
286 signmaker.vm.fsw(fsw,true);
287 if (fsw==signmaker.vm.fswraw) {
288 signmaker.vm.fswraw = '';
289 } else {
290 fsw = signmaker.vm.fswraw;
291 }
292 } else {
293 fsw = signmaker.vm.fswraw || signmaker.vm.fswnorm();
294 }
295 return fsw;
296 },
297 swu: function(swu,silent){
298 if (swu!='undefined') {
299 signmaker.vm.fsw(ssw.swu2fsw(swu),silent);
300 } else {
301 fsw = 'M500x500';
302 if (signmaker.vm.sort.length) fsw = "A" + signmaker.vm.sort.join('') + fsw;
303 for (var i=0; i < signmaker.vm.list.length; i++) {
304 fsw += signmaker.vm.list[i].key() + signmaker.vm.list[i].x() + 'x' + signmaker.vm.list[i].y();
305 }
306 }
307 },
308 swuraw: '',
309 swuview: function(swu){
310 if (typeof(swu)!='undefined') {
311 signmaker.vm.swuraw = swu;
312 signmaker.vm.fswraw = '';
313 swu = ssw.parse(swu,"swu")["swu"];
314 signmaker.vm.swu(swu,true);
315 if (swu==signmaker.vm.swuraw) {
316 signmaker.vm.swuraw = '';
317 } else {
318 swu = signmaker.vm.swuraw;
319 }
320 } else {
321 swu = signmaker.vm.swuraw || signmaker.vm.swunorm();
322 }
323 return swu;
324 },
325 styling: m.prop(''),
326 dlpng: function(){
327 var canvas = ssw.canvas(signmaker.vm.fswnorm()+signmaker.vm.styling(),{size: signmaker.vm.size(), pad: signmaker.vm.pad(), line: signmaker.vm.linecolor(), fill: signmaker.vm.fillcolor(), back: signmaker.vm.backcolor(), colorize: signmaker.vm.colorize()});
328 var data = canvas.toDataURL("image/png");
329 var link = document.getElementById('downloadlink');
330 link.href = data;
331 link.download=("sign") + ".png" ;
332 link.click();
333 },
334 dlsvg: function(){
335 var svg = ssw.svg(signmaker.vm.fswnorm()+signmaker.vm.styling(),{
336 size: signmaker.vm.size(),
337 pad: signmaker.vm.pad(),
338 line: signmaker.vm.linecolor(),
339 fill: signmaker.vm.fillcolor(),
340 back: signmaker.vm.backcolor(),
341 colorize: signmaker.vm.colorize(),
342 copy: (signmaker.vm.chars == "swu")?"opt":''
343 });
344
345 var data = new Blob([svg], {type: 'image/svg+xml'});
346 if (dlFile !== null) {
347 window.URL.revokeObjectURL(dlFile);
348 }
349 dlFile = window.URL.createObjectURL(data);
350 var link = document.getElementById('downloadlink');
351 link.href = dlFile;
352 link.download=("sign") + ".svg" ;
353 link.click();
354 },
355 size: m.prop('1'),
356 pad: m.prop('0'),
357 linecolor: m.prop('black'),
358 fillcolor: m.prop('white'),
359 backcolor: m.prop(''),
360 colorize: m.prop(''),
361 center: function(){
362 signmaker.vm.fsw(ssw.norm(signmaker.vm.fsw()));
363 },
364 list: new spatials.List(),
365 sort: [],
366 history: ['{"list":[],"sort":[]'],
367 cursor: 0,
368 addhistory: function(silent){
369 if (!silent) {
370 signmaker.vm.fswraw = '';
371 signmaker.vm.swuraw = '';
372 }
373 var history ={list:signmaker.vm.list,sort:signmaker.vm.sort};
374 var newhist = JSON.stringify(history).replace(/true/g,'false');
375 if (newhist != signmaker.vm.history[signmaker.vm.cursor]){
376 signmaker.vm.cursor++;
377 signmaker.vm.history = signmaker.vm.history.slice(0,signmaker.vm.cursor);
378 signmaker.vm.history.push(newhist);
379 hashSet();
380 }
381 },
382 undo: function(){
383 if (signmaker.vm.cursor<=0) return;
384 signmaker.vm.cursor--;
385 var history = JSON.parse(signmaker.vm.history[signmaker.vm.cursor]);
386 var syms = history['list'];
387 signmaker.vm.list = new spatials.List();
388 for (var i=0; i < syms.length; i++) {
389 signmaker.vm.list.push(new spatials.Symbol({key:syms[i]['key'],x:syms[i]['x'],y:syms[i]['y']}))
390 }
391 signmaker.vm.selnone();
392 signmaker.vm.sort = history['sort'];
393 m.redraw();
394 },
395 redo: function(){
396 if ((signmaker.vm.cursor+1)>=signmaker.vm.history.length) return;
397 signmaker.vm.cursor++;
398 var history = JSON.parse(signmaker.vm.history[signmaker.vm.cursor]);
399 var syms = history['list'];
400 signmaker.vm.list = new spatials.List();
401 for (var i=0; i < syms.length; i++) {
402 signmaker.vm.list.push(new spatials.Symbol({key:syms[i]['key'],x:syms[i]['x'],y:syms[i]['y']}))
403 }
404 signmaker.vm.selnone();
405 signmaker.vm.sort = history['sort'];
406 m.redraw();
407 },
408 add: function(symbol) {
409 signmaker.vm.selnone();
410 if (symbol) {
411 signmaker.vm.list.push(new spatials.Symbol(symbol));
412 }
413 signmaker.vm.addhistory();
414 m.redraw();
415 },
416 addSeq: function(key,position) {
417 signmaker.vm.sort.splice(position, 0, key);
418 signmaker.vm.addhistory();
419 m.redraw();
420 },
421 selnone: function() {
422 for (var i=0; i < signmaker.vm.list.length; i++) {
423 signmaker.vm.list[i].selected(false);
424 }
425 },
426 copy: function() {
427 var len = signmaker.vm.list.length;
428 for (var i=0; i < len; i++) {
429 if (signmaker.vm.list[i].selected()){
430 var symbol = signmaker.vm.list[i];
431 signmaker.vm.add({key:symbol.key(),x:symbol.x()+10,y:symbol.y()+10});
432 }
433 }
434 signmaker.vm.addhistory();
435 m.redraw();
436 },
437 delete: function() {
438 for (var i=0; i < signmaker.vm.list.length; i++) {
439 if (signmaker.vm.list[i].selected()){
440 signmaker.vm.list.splice(i,1);
441 }
442 }
443 signmaker.vm.addhistory();
444 m.redraw();
445 },
446 clear: function() {
447 signmaker.vm.list = new spatials.List();
448 signmaker.vm.sort=[];
449 signmaker.vm.addhistory();
450 m.redraw();
451 },
452 variation: function(step) {
453 for (var i=0; i < signmaker.vm.list.length; i++) {
454 if (signmaker.vm.list[i].selected()){
455 signmaker.vm.list[i].key(ssw.scroll(signmaker.vm.list[i].key(),step));
456 }
457 }
458 signmaker.vm.addhistory();
459 m.redraw();
460 },
461 mirror: function() {
462 for (var i=0; i < signmaker.vm.list.length; i++) {
463 if (signmaker.vm.list[i].selected()){
464 signmaker.vm.list[i].key(ssw.mirror(signmaker.vm.list[i].key()));
465 }
466 }
467 signmaker.vm.addhistory();
468 m.redraw();
469 },
470 fill: function(step) {
471 for (var i=0; i < signmaker.vm.list.length; i++) {
472 if (signmaker.vm.list[i].selected()){
473 signmaker.vm.list[i].key(ssw.fill(signmaker.vm.list[i].key(),step));
474 }
475 }
476 signmaker.vm.addhistory();
477 m.redraw();
478 },
479 over: function() {
480 var len = signmaker.vm.list.length;
481 for (var i=0; i < len; i++) {
482 if (signmaker.vm.list[i].selected()){
483 var symbol = signmaker.vm.list[i];
484 signmaker.vm.add({key:symbol.key(),x:symbol.x(),y:symbol.y()});
485 signmaker.vm.list.splice(i,1);
486 len--;
487 }
488 }
489 signmaker.vm.addhistory();
490 m.redraw();
491 },
492 rotate: function(step) {
493 for (var i=0; i < signmaker.vm.list.length; i++) {
494 if (signmaker.vm.list[i].selected()){
495 signmaker.vm.list[i].key(ssw.rotate(signmaker.vm.list[i].key(),step));
496 }
497 }
498 signmaker.vm.addhistory();
499 m.redraw();
500 },
501 select: function(step) {
502 if (!signmaker.vm.list.length) return;
503 var sel = 0;
504 for (var i=0; i < signmaker.vm.list.length; i++) {
505 if (signmaker.vm.list[i].selected()){
506 sel = i;
507 }
508 }
509 sel += step;
510 if (sel<0) sel = signmaker.vm.list.length-1;
511 if (sel>=signmaker.vm.list.length) sel = 0;
512 signmaker.vm.selnone();
513 signmaker.vm.list[sel].selected(true);
514 m.redraw();
515 },
516 move: function(x,y) {
517 for (var i=0; i < signmaker.vm.list.length; i++) {
518 if (signmaker.vm.list[i].selected()){
519 signmaker.vm.list[i].x(signmaker.vm.list[i].x()+x);
520 signmaker.vm.list[i].y(signmaker.vm.list[i].y()+y);
521 }
522 }
523 signmaker.vm.addhistory();
524 m.redraw();
525 }
526};
527signmaker.controller = function(){
528// signmaker.vm.init();
529};
530
531function sbDragEnd( draggie,e,p ) {
532 var sb = document.getElementById("signbox");
533 var drag = draggie.dragPoint;
534 if (overlap(draggie.element,sb)){
535 signmaker.vm.list[draggie.element.index].x(signmaker.vm.list[draggie.element.index].x() + drag.x);
536 signmaker.vm.list[draggie.element.index].y(signmaker.vm.list[draggie.element.index].y() + drag.y);
537 signmaker.vm.addhistory();
538 m.redraw();
539 } else {
540 var seq = document.getElementById("sequence");
541 if (overlap(draggie.element,seq)){
542 var position = parseInt(draggie.position.y / (window.innerHeight/20));
543 var key = signmaker.vm.list[draggie.element.index].key();
544 signmaker.vm.addSeq(key,position);
545 }
546 draggie.element.style.left = (parseInt(draggie.element.style.left) - drag.x) + 'px';
547 draggie.element.style.top = (parseInt(draggie.element.style.top) - drag.y) + 'px';
548 }
549}
550
551function sbDragStart( draggie ){
552 signmaker.vm.selnone();
553 signmaker.vm.list[draggie.element.index].selected(true);
554}
555
556function seqDragEnd( draggie,e,p ) {
557 var position1 = parseInt(draggie.startPoint.y / (window.innerHeight/20));
558 var position2 = parseInt((draggie.startPoint.y+draggie.dragPoint.y) / (window.innerHeight/20));
559 draggie.element.style.left = (parseInt(draggie.element.style.left) - draggie.dragPoint.x) + 'px';
560 draggie.element.style.top = (parseInt(draggie.element.style.top) - draggie.dragPoint.y) + 'px';
561 if (position1<signmaker.vm.sort.length){
562 if (position1!=position2){
563 signmaker.vm.sort.splice(position2, 0, signmaker.vm.sort.splice(position1, 1)[0]);
564 } else {
565 signmaker.vm.sort.splice(position1,1);
566 }
567 signmaker.vm.addhistory();
568 m.redraw();
569 }
570}
571
572signmaker.view = function(ctrl){
573
574 var clientWidth = document.getElementById('signmaker').clientWidth*.90
575 var clientHeight = document.getElementById('signmaker').clientHeight*.5;
576 signmaker.vm.midWidth = parseInt(clientWidth/2);
577 signmaker.vm.midHeight = parseInt(clientHeight/2);
578 var bbox = ssw.bbox(ssw.max(signmaker.vm.fsw())).split(" ");
579 //check if bbox is outside of display
580 if (bbox.length==4){
581 if (bbox[0]<510-signmaker.vm.midWidth || bbox[1]>490+signmaker.vm.midWidth) { // left or right
582 signmaker.vm.midWidth = signmaker.vm.midWidth + 500 - parseInt((parseInt(bbox[0])+parseInt(bbox[1]))/2);
583 }
584 if (bbox[2]<510-signmaker.vm.midHeight || bbox[3]>490+signmaker.vm.midHeight) { // top or bottom
585 signmaker.vm.midHeight = signmaker.vm.midHeight + 500 - parseInt((parseInt(bbox[2])+parseInt(bbox[3]))/2);
586 }
587 }
588 var grid = '';
589 switch (S['grid'] || "0") {
590 case "0":
591 break;
592 case "1":
593 grid = '<svg width="' + clientWidth + '" height="' + clientHeight + '" viewBox="0 0 ' + clientWidth + ' ' + clientHeight + '" xmlns="http://www.w3.org/2000/svg" version="1.1">';
594 grid += '<g stroke="gray" >';
595 grid += '<line x1="0" y1="' + signmaker.vm.midHeight + '" x2="' + clientWidth + '" y2="' + signmaker.vm.midHeight + '" stroke-width="1" />';
596 grid += '<line y1="0" x1="' + signmaker.vm.midWidth + '" y2="' + clientHeight + '" x2="' + signmaker.vm.midWidth + '" stroke-width="1" />';
597 grid += '</g>';
598 grid += '</svg>';
599 break;
600 case "2":
601 grid = '<svg width="' + clientWidth + '" height="' + clientHeight + '" viewBox="0 0 ' + clientWidth + ' ' + clientHeight + '" xmlns="http://www.w3.org/2000/svg" version="1.1">';
602 grid += '<g stroke="lightgray" >';
603 var startH = signmaker.vm.midHeight % 10;
604 var startW = signmaker.vm.midWidth % 10;
605 for (var w=startW;w<clientWidth;w+=10){
606 grid += '<line y1="0" x1="' + w + '" y2="' + clientHeight + '" x2="' + w + '" stroke-width="1" />';
607 }
608 for (var h=startH;h<clientHeight;h+=10){
609 grid += '<line x1="0" y1="' + h + '" x2="' + clientWidth + '" y2="' + h + '" stroke-width="1" />';
610 }
611 grid += '</g>';
612 grid += '<g stroke="gray" >';
613 grid += '<line x1="0" y1="' + signmaker.vm.midHeight + '" x2="' + clientWidth + '" y2="' + signmaker.vm.midHeight + '" stroke-width="1" />';
614 grid += '<line y1="0" x1="' + signmaker.vm.midWidth + '" y2="' + clientHeight + '" x2="' + signmaker.vm.midWidth + '" stroke-width="1" />';
615 grid += '</g>';
616 grid += '</svg>';
617 break;
618 }
619 var editor = [m('div',{id:"signbox"},[
620 m("div",m.trust(grid)),
621 signmaker.vm.list.map(function(symbol, index) {
622 return m("div"
623 , {
624 "class": symbol.selected() ? "selected" : "",
625 style:{
626 left: (parseInt(symbol.x())-500+signmaker.vm.midWidth).toString() + 'px',
627 top: (parseInt(symbol.y())-500+signmaker.vm.midHeight).toString() + 'px'
628 },
629 config: function(element, isInitialized) {
630 element.index=index;
631 if (!isInitialized) {
632 var draggie = new Draggabilly(element,{containment:"#signmaker"});
633 draggie.on( 'dragStart', sbDragStart );
634 draggie.on( 'dragEnd', sbDragEnd );
635 }
636 }
637 },m.trust(ssw.svg(symbol.key())));
638 })
639 ]),
640 m('div',{id:"sequence"},
641 signmaker.vm.sort.concat('').map(function(key) {
642 return m("div.sort"
643 , {
644 config: function(element, isInitialized) {
645 element.key=key;
646 if (!isInitialized) {
647 var draggie = new Draggabilly(element,{containment:"#sequence"});
648 draggie.on( 'dragEnd', seqDragEnd );
649 }
650 }
651 },m.trust(ssw.svg(key)));
652 }))
653 ];
654
655 var currentTab;
656 switch (S['tab']) {
657 case '': // signmaker commands
658 currentTab = [
659 m("div.cmdslim.clickable.",{onclick: signmaker.vm.move.bind(signmaker.vm,-1,0)},tt('moveLeft')),
660 m('div.cmdslim.clickable',{onclick: signmaker.vm.move.bind(signmaker.vm,0,-1)},tt('moveUp')),
661 m('div.cmdslim.clickable',{onclick: signmaker.vm.move.bind(signmaker.vm,0,1)},tt('moveDown')),
662 m('div.cmdslim.clickable',{onclick: signmaker.vm.move.bind(signmaker.vm,1,0)},tt('moveRight')),
663 m('div',{style:"clear:both;height:0%"}),
664 m('div.cmd.clickable',{onclick: signmaker.vm.copy},tt("copy")),
665 m('div.cmd.clickable',{onclick: signmaker.vm.mirror},tt('mirror')),
666 m('div.cmd.clickable',{onclick: signmaker.vm.center},tt('center')),
667 m('div.cmd.clickable',{onclick: signmaker.vm.delete},tt('delete')),
668 m('div.cmd.clickable',{onclick: signmaker.vm.rotate.bind(signmaker.vm,-1)},tt('rotateCCW')),
669 m('div.cmd.clickable',{onclick: signmaker.vm.rotate.bind(signmaker.vm,1)},tt('rotateCW')),
670 m('div.cmd.clickable',{onclick: signmaker.vm.select.bind(signmaker.vm,1)},tt('selectNext')),
671 m('div.cmd',{"class": (signmaker.vm.cursor<=0)?"disabled":"clickable",onclick: signmaker.vm.undo}, tt('undo')),
672 m('div.cmd.clickable',{onclick: signmaker.vm.fill.bind(signmaker.vm,-1)},tt('fillPrev')),
673 m('div.cmd.clickable',{onclick: signmaker.vm.fill.bind(signmaker.vm,1)},tt('fillNext')),
674 m('div.cmd.clickable',{onclick: signmaker.vm.select.bind(signmaker.vm,-1)},tt('selectPrev')),
675 m('div.cmd',{"class": ((signmaker.vm.cursor+1)>=signmaker.vm.history.length)?"disabled":"clickable",onclick: signmaker.vm.redo},tt('redo')),
676 m('div.cmd.clickable',{onclick: signmaker.vm.variation.bind(signmaker.vm,-1)},tt('variationPrev')),
677 m('div.cmd.clickable',{onclick: signmaker.vm.variation.bind(signmaker.vm,1)},tt('variationNext')),
678 m('div.cmd.clickable',{onclick: signmaker.vm.over},tt('placeOver')),
679 m('div.cmd.clickable',{onclick: signmaker.vm.clear},tt('clearAll'))
680 ];
681 break;
682 case 'png':
683 currentTab = [
684 m('div.cmd',{"class": (S['tab'] == 'png') ? "selected" : "unselected",onclick: () => setS({'tab':'png'})},tt("pngImage")),
685 m('div.cmd',{"class": (S['tab'] == 'svg') ? "selected" : "unselected",onclick: () => setS({'tab':'svg'})},tt("svgImage")),
686 m('div.cmdslim',tt('size')
687 ),
688 m('div.cmdslim',
689 m("input",{id:"size",value:signmaker.vm.size(),oninput:m.withAttr('value',signmaker.vm.size)})
690 ),
691 m('div.cmdslim',tt('pad')
692 ),
693 m('div.cmdslim',
694 m("input",{id:"pad",value:signmaker.vm.pad(),oninput:m.withAttr('value',signmaker.vm.pad)})
695 ),
696 m('div.cmdslim',tt('line')
697 ),
698 m('div.cmdslim',
699 m("input",{id:"line",value:signmaker.vm.linecolor(),oninput:m.withAttr('value',signmaker.vm.linecolor)})
700 ),
701 m('div.cmdslim',tt('fill')
702 ),
703 m('div.cmdslim',
704 m("input",{id:"fill",value:signmaker.vm.fillcolor(),oninput:m.withAttr('value',signmaker.vm.fillcolor)})
705 ),
706 m('div.cmdslim',tt('background')
707 ),
708 m('div.cmdslim',
709 m("input",{id:"back",value:signmaker.vm.backcolor(),oninput:m.withAttr('value',signmaker.vm.backcolor)})
710 ),
711 m('div.cmdslim',tt('colorize')
712 ),
713 m('div.cmdslim',
714 m("input",{id:"colorize",type:"checkbox",checked:signmaker.vm.colorize(),onclick:m.withAttr('checked',signmaker.vm.colorize)})
715 ),
716 m('div.cmdrow',
717 m("p.fsw","Styling: "),
718 m("input",{id:"styling",value:signmaker.vm.styling(),oninput:m.withAttr("value",signmaker.vm.styling)})
719 ),
720 isApp?'':m('div.cmd.clickable',{onclick: signmaker.vm.dlpng},tt('download')),
721 ];
722 var canvas = ssw.canvas(signmaker.vm.fswnorm()+signmaker.vm.styling(),{size: signmaker.vm.size(), pad: signmaker.vm.pad(), line: signmaker.vm.linecolor(), fill: signmaker.vm.fillcolor(), back: signmaker.vm.backcolor(), colorize: signmaker.vm.colorize()});
723 var data = canvas?canvas.toDataURL("image/png"):"";
724 editor = m('div',{id:"signbox"},
725 m('div.mid',
726 m('img',{src:data,value:("sign") + ".png"})
727 )
728 );
729 break;
730 case "svg":
731 currentTab = [
732 m('div.cmd',{"class": (S['tab'] == 'png') ? "selected" : "unselected",onclick: () => setS({'tab':'png'})},tt("pngImage")),
733 m('div.cmd',{"class": (S['tab'] == 'svg') ? "selected" : "unselected",onclick: () => setS({'tab':'svg'})},tt("svgImage")),
734 m('div.cmdslim',tt('size')
735 ),
736 m('div.cmdslim',
737 m("input",{id:"size",value:signmaker.vm.size(),oninput:m.withAttr('value',signmaker.vm.size)})
738 ),
739 m('div.cmdslim',tt('pad')
740 ),
741 m('div.cmdslim',
742 m("input",{id:"pad",value:signmaker.vm.pad(),oninput:m.withAttr('value',signmaker.vm.pad)})
743 ),
744 m('div.cmdslim',tt('line')
745 ),
746 m('div.cmdslim',
747 m("input",{id:"line",value:signmaker.vm.linecolor(),oninput:m.withAttr('value',signmaker.vm.linecolor)})
748 ),
749 m('div.cmdslim',tt('fill')
750 ),
751 m('div.cmdslim',
752 m("input",{id:"fill",value:signmaker.vm.fillcolor(),oninput:m.withAttr('value',signmaker.vm.fillcolor)})
753 ),
754 m('div.cmdslim',tt('background')
755 ),
756 m('div.cmdslim',
757 m("input",{id:"back",value:signmaker.vm.backcolor(),oninput:m.withAttr('value',signmaker.vm.backcolor)})
758 ),
759 m('div.cmdslim',tt('colorize')
760 ),
761 m('div.cmdslim',
762 m("input",{id:"colorize",type:"checkbox",checked:signmaker.vm.colorize(),onclick:m.withAttr('checked',signmaker.vm.colorize)})
763 ),
764 m('div.cmdrow',
765 m("p.fsw","Styling: "),
766 m("input",{id:"styling",value:signmaker.vm.styling(),oninput:m.withAttr("value",signmaker.vm.styling)})
767 ),
768 isApp?'':m('div.cmd.clickable',{onclick: signmaker.vm.dlsvg},tt('download')),
769 ];
770 var svg = ssw.svg(signmaker.vm.fswnorm()+signmaker.vm.styling(),{
771 size: signmaker.vm.size(),
772 pad: signmaker.vm.pad(),
773 line: signmaker.vm.linecolor(),
774 fill: signmaker.vm.fillcolor(),
775 back: signmaker.vm.backcolor(),
776 colorize: signmaker.vm.colorize(),
777 copy: (signmaker.vm.chars == "swu")?"opt":''
778 });
779 editor = m('div',{id:"signbox"},
780 m('div.mid',
781 m.trust(svg)
782 )
783 );
784 break;
785 case "more":
786 var alphaSignLang = signLang['alphabet'].map(function(key){
787 return t(key) + '\t' + key.slice(4);
788 });
789 alphaSignLang.sort();
790 currentTab = [
791 m('div.cmd',{"class": (S['tab'] == 'png') ? "selected" : "unselected",onclick: () => setS({'tab':'png'})},tt("pngImage")),
792 m('div.cmd',{"class": (S['tab'] == 'svg') ? "selected" : "unselected",onclick: () => setS({'tab':'svg'})},tt("svgImage")),
793 m('div.cmdslim',tt('userInterface')
794 ),
795 m('div.cmdlong',
796 m('select', {id: 'language',onchange:function(e){setS({'ui':e.target.value});}},
797 m('optgroup',
798 Object.keys(messages).map(function(key){
799 return m('option',{value: key,selected:(key==S['ui'])},messages[key]['language']);
800 })
801 )
802 )
803 ),
804 m('div.cmdslim',tt('alphabet')
805 ),
806 m('div.cmdlong',
807 m('select', {id: 'alphaLang',onchange:function(e){setS({'alphabet':e.target.value});}},
808 m('optgroup',
809 m('option',{value:''},t('iswa2010')),
810 alphaSignLang.map(function(val){
811 var vals = val.split('\t');
812 return m('option',{value: vals[1],selected:(vals[1]==S['alphabet'])},vals[0]);
813 })
814 )
815 )
816 ),
817 m('div.cmdslim',tt('grid')
818 ),
819 m('div.cmdslim.clickable',{"class": (S['grid']=="0") ? "checked" : "unchecked",onclick: function(){setS({'grid':"0"});}},tt('grid0')),
820 m('div.cmdslim.clickable',{"class": (S['grid']=="1") ? "checked" : "unchecked",onclick: function(){setS({'grid':"1"});}},tt('grid1')),
821 m('div.cmdslim.clickable',{"class": (S['grid']=="2") ? "checked" : "unchecked",onclick: function(){setS({'grid':"2"});}},tt('grid2')),
822 m('div.cmdslim',tt('skin')
823 ),
824 m('div.cmdslim.clickable',{"class": (S['skin']=="" || S['skin']==undefined) ? "checked" : "unchecked",onclick: function(){setS({'skin': ''});}},tt('blackOnWhite')),
825 m('div.cmdslim.clickable',{"class": (S['skin']=="inverse") ? "checked" : "unchecked",onclick: function(){setS({'skin': 'inverse'});}},tt('whiteOnBlack')),
826 m('div.cmdslim.clickable',{"class": (S['skin']=="colorful") ? "checked" : "unchecked",onclick: function(){setS({'skin': 'colorful'});}},tt('colorful')),
827 m('div.cmdrow',
828 m("p.fsw","FSW:"),
829 m("input",{"class": (signmaker.vm.fswraw && (signmaker.vm.fswraw != signmaker.vm.fswlive()))?'warning':'',id:"fsw",value:signmaker.vm.fswview(),oninput:m.withAttr("value",signmaker.vm.fswview)})
830 ),
831 m('div', {"class":(signmaker.vm.chars=="fsw")?'cmdrow':'cmdfull'},
832 m("p.swu","SWU:"),
833 m("input",{"class": (signmaker.vm.swuraw && (signmaker.vm.swuraw != signmaker.vm.swulive()))?'warning':'',id:"swu",value:signmaker.vm.swuview(),oninput:m.withAttr("value",signmaker.vm.swuview)})
834 ),
835 m('div.cmdrow',
836 m("p.fsw","Styling: "),
837 m("input",{id:"styling",value:signmaker.vm.styling(),oninput:m.withAttr("value",signmaker.vm.styling)})
838 ),
839 ]
840 break;
841
842 }
843
844 return [
845 editor,
846 m('div',{id:"command"},[
847 m('div.cmd.edit',{"class": (S['tab'] == '') ? "selected" : "unselected",onclick: () => setS({'tab':''})},tt("editTab")),
848 m('div.cmd',{"class": (S['tab'] =='more') ? "selected" : "unselected",onclick: () => setS({'tab':'more'})},tt("moreTab")),
849 currentTab
850 ])
851 ]
852};
853
854
855// PALETTE
856//////////
857var palette = {}; //app namespace
858//model
859palette.structure = function(){
860 return window.alphabet;
861};
862
863palette.vm = {};
864
865palette.vm.init = function(){
866 this.source = palette.structure();
867 this.action = false;
868}
869
870palette.vm.select = function(group,base,lower){
871 var key;
872 this.group = group || '';
873 this.base = base || '';
874 this.lower = !!lower;
875
876 if (this.base && !this.lower){
877 var key1 = this.base.slice(0,4) + "08";
878 var key2 = this.base.slice(0,4) + "18";
879 this.mirror = (ssw.size(key1) || ssw.size(key2))
880 this.grid=[[],[],[],[],[],[],[],[]];
881 for (var f=0;f<6;f++){
882 for (var r=0;r<8;r++){
883 key=this.base.slice(0,4) + f + r;
884 this.grid[r].push(key);
885 }
886 }
887 } else if (this.base && this.lower){
888 this.mirror = true;
889 this.grid=[[],[],[],[],[],[],[],[]];
890 for (var f=0;f<6;f++){
891 for (var r=8;r<16;r++){
892 key=this.base.slice(0,4) + f + r.toString(16);
893 this.grid[(r-8)].push(key);
894 }
895 }
896 } else if (this.group){
897 this.mirror = false;
898 this.grid=[[],[],[],[],[],[],[],[],[],[]];
899 var cnt=0;
900 for (var i=0; i<this.source[this.group].length;i++){
901 key = this.source[this.group][i];
902 this.grid[(cnt++%10)].push(key);
903 }
904 for (var i=cnt; i<60;i++){
905 this.grid[(i%10)].push('');
906 }
907 } else {
908 this.mirror=false;
909 this.grid=[[],[],[],[],[],[],[],[],[],[]];
910 var cnt=0;
911 for (key in this.source){
912 if (palette.vm.dialing){
913 var start = window.alphabet[key][0];
914 var end = window.alphabet[key].slice(-1)[0]
915 if (!ssw.results(query+"R" + start.slice(1,4) + 't' + end.slice(1,4),text).length) {
916 key='';
917 }
918 }
919 this.grid[(cnt++%10)].push(key);
920 }
921 for (var i=cnt; i<60;i++){
922 this.grid[(i%10)].push('');
923 }
924 }
925}
926
927palette.controller = function(){
928 palette.vm.init();
929 palette.vm.select();
930}
931
932palette.click = function(key){
933 if (palette.vm.base){
934 return;
935 } else if (palette.vm.group){
936 palette.vm.select(palette.vm.group,key);
937 } else {
938 palette.vm.select(key);
939 }
940};
941
942palette.undo = function(){
943 return {
944 "class": palette.vm.dialhist.length || palette.vm.group?"clickable":"disabled",
945 onclick: function(){
946 if (palette.vm.base){
947 palette.vm.select(palette.vm.group);
948 } else if (palette.vm.group){
949 palette.vm.select();
950 }
951 }
952 }
953}
954palette.top = function(){
955 return {
956 onclick: function(){
957 palette.vm.select();
958 }
959 };
960};
961palette.previous = function(){
962 return {
963 onclick: function(){
964 if (palette.vm.base){
965 palette.vm.select(palette.vm.group);
966 } else {
967 palette.vm.select();
968 }
969 }
970 };
971};
972palette.mirror = function(){
973 return {
974 "class": palette.vm.dialing==3?"smaller":'',
975 onclick: function(){
976 palette.vm.select(palette.vm.group,palette.vm.base,!palette.vm.lower);
977 }
978 };
979};
980
981//view
982
983// gets the offset of an element relative to the document
984function getOffset( el ) {
985 var offset = el?el.getBoundingClientRect():{top:0,left:0};
986 return { top : offset.top + (window.pageYOffset || window.document.documentElement.scrollTop), left : offset.left + (window.pageXOffset || window.document.documentElement.scrollLeft) }
987}
988
989function overlap(el1, el2){
990 if (!el2) return false;
991 var offset1 = getOffset( el1 ), width1 = el1.offsetWidth, height1 = el1.offsetHeight,
992 offset2 = getOffset( el2 ), width2 = el2.offsetWidth, height2 = el2.offsetHeight;
993 if (!(offset2.left > offset1.left + width1 - width1/2 || offset2.left + width2 < offset1.left + width1/2 || offset2.top > offset1.top + height1 - height1/2 || offset2.top + height2 < offset1.top + height1/2 )){
994 return true;
995 } else {
996 return false;
997 }
998}
999
1000function palDragEnd( draggie,e,p ) {
1001 var sb = document.getElementById("signbox");
1002 if (overlap(draggie.element,sb)){
1003 var offset1 = getOffset( draggie.element ),
1004 offset2 = getOffset( sb );
1005 var symbol = {key:draggie.element.key,x: parseInt(500-signmaker.vm.midWidth+1+offset1.left-offset2.left),y: parseInt(500-signmaker.vm.midHeight+offset1.top-offset2.top)};
1006 signmaker.vm.add(symbol);
1007 } else {
1008 var seq = document.getElementById("sequence");
1009 if (overlap(draggie.element,seq)){
1010 var position = parseInt((draggie.startPoint.y+draggie.dragPoint.y) / (window.innerHeight/20));
1011 var key = draggie.element.key;
1012 signmaker.vm.addSeq(key,position);
1013 }
1014 }
1015
1016 draggie.element.style.top=0;
1017 draggie.element.style.left=0;
1018 draggie.element.topleft=false;
1019 classie.remove(draggie.element,"topleft");
1020 var drag = draggie.dragPoint;
1021 if ( drag.x === 0 && drag.y === 0 ) {
1022 palette.click(draggie.element.key);
1023 m.redraw();
1024 }
1025}
1026
1027function palDragMove( draggie ){
1028 if (!draggie.element.topleft){
1029 draggie.element.topleft=true;
1030 classie.add(draggie.element,"topleft");
1031 }
1032}
1033
1034palette.view = function(ctrl){
1035 var tooltip = palette.vm.base?'':palette.vm.group?'base_':'group_';
1036 return [
1037 palette.vm.action?[
1038 m('div.btn.clickable.save',{onclick: signmaker.vm.save},tt("save")),
1039 navigator.share?m('div.btn.clickable.share',{onclick: signmaker.vm.share},tt("share")):'',
1040 m('div.btn.clickable.demo',{onclick: signmaker.vm.demo},tt("demo")),
1041 m('div.btn.clickable.cancel',{onclick: signmaker.vm.cancel},tt("cancel")),
1042 ]:[
1043 m('div.btn.clickable.save',{onclick: signmaker.vm.save},tt("save")),
1044 palette.vm.mirror?'':m("div.btn.clickable",palette.top(),tt("top")),
1045 m("div.btn.clickable",palette.previous(),tt("previous")),
1046 palette.vm.mirror?m("div.btn",palette.mirror(),tt("mirror")):'',
1047 m('div.btn.clickable.save',{onclick: () => palette.vm.action = !palette.vm.action},tt("...")),
1048 ],
1049 palette.vm.grid.map(function(row){
1050 return m("div.row",{"class":palette.vm.dialing?"smaller":''},row.map(function(key){
1051 return m("div"
1052 , {
1053 title: tooltip?t(tooltip + key.slice(0,4)):'',
1054 config: function(element, isInitialized) {
1055 element.key=key;
1056 if (!isInitialized) {
1057 var draggie = new Draggabilly(element);
1058 draggie.on( 'dragMove', palDragMove );
1059 draggie.on( 'dragEnd', palDragEnd );
1060 }
1061 }
1062 },m.trust(ssw.svg(key)));
1063 }));
1064 })
1065 ];
1066};
1067
1068
1069addEventListener("keydown", function(event){
1070 if (event.target==document.body){
1071 var code = event.charCode || event.keyCode;
1072 for (var i=0; i<keyboard['prevent'].length; i++){
1073 if (code === keyboard['prevent'][i]){
1074 event.preventDefault();
1075 }
1076 }
1077 return false;
1078 }
1079});
1080
1081function initApp(){
1082 m.mount(document.getElementById("palette"), palette);
1083 m.mount(document.getElementById("signmaker"), signmaker);
1084}
1085
1086var cssCheck;
1087window.onload = function () {
1088 if (S['swu']) {
1089 signmaker.vm.swu(S['swu'])
1090 } else if (S['fsw']) {
1091 signmaker.vm.fsw(S['fsw'])
1092 }
1093 var cnt = 0;
1094 if (!!ssw.size("S10000")){
1095 initApp();
1096 } else {
1097 classie.addClass(document.body,"waiting");
1098 var page = document.body.innerHTML;
1099 cssCheck = setInterval(function(){
1100 if (ssw.size("S10000")){
1101 classie.removeClass(document.body,"waiting");
1102 document.body.innerHTML = page;
1103 clearInterval(cssCheck);
1104 initApp();
1105 //secondary call for Android default browser
1106 //setTimeout(function(){ initApp(); }, 100);
1107 } else {
1108 document.getElementById('dots').innerHTML=Array(1+parseInt(((cnt++)%40)/10)).join('.');
1109 }
1110 },100);
1111 document.body.innerHTML = '<h2>' + t('loadFont') + ' <span id="dots"></span>' + '</h2>';
1112 }
1113
1114
1115}
1116// https://keycode.info
1117checkKeyboard = function (event,name){
1118 if (event.target==document.body){
1119 var code = event.charCode || event.keyCode;
1120 var checks = keyboard[name];
1121 var checking;
1122 var act;
1123 if (!(checks[0] instanceof Array)){
1124 checks = [checks];
1125 }
1126 for (var i=0; i < checks.length; i++) {
1127 checking = checks[i]
1128 if (checking[0] == code){
1129 act = true;
1130 checking = checking.slice(1);
1131 for (check in checking){
1132 if (!event[checking[check]]){
1133 act = false;
1134 break;
1135 }
1136 }
1137 if (act) return true;
1138 }
1139 }
1140 return false;
1141 }
1142}
1143addEventListener("keyup", function(event) {
1144 var x = event.charCode || event.keyCode;
1145 if (checkKeyboard(event,"left10")){ signmaker.vm.move(-10,0);} else
1146 if (checkKeyboard(event,"up10")){ signmaker.vm.move(0,-10);} else
1147 if (checkKeyboard(event,"right10")){ signmaker.vm.move(10,0);} else
1148 if (checkKeyboard(event,"down10")){ signmaker.vm.move(0,10);} else
1149 if (checkKeyboard(event,"left")){ signmaker.vm.move(-1,0);} else
1150 if (checkKeyboard(event,"up")){ signmaker.vm.move(0,-1);} else
1151 if (checkKeyboard(event,"right")){ signmaker.vm.move(1,0);} else
1152 if (checkKeyboard(event,"down")){ signmaker.vm.move(0,1);} else
1153 if (checkKeyboard(event,"selectBack")){ signmaker.vm.select(-1);} else
1154 if (checkKeyboard(event,"selectNext")){ signmaker.vm.select(1);} else
1155 if (checkKeyboard(event,"escape")){ if (S['tab'] == 'more') {setS({'tab':''});} else {setS({'tab':'more'})} }else
1156 if (checkKeyboard(event,"delete")){ signmaker.vm.delete();} else
1157 if (checkKeyboard(event,"redo")){ signmaker.vm.redo();} else
1158 if (checkKeyboard(event,"undo")){ signmaker.vm.undo();} else
1159 if (checkKeyboard(event,"rotateBack")){ signmaker.vm.rotate(-1);} else
1160 if (checkKeyboard(event,"rotateNext")){ signmaker.vm.rotate(1);} else
1161 if (checkKeyboard(event,"variationBack")){ signmaker.vm.variation(-1);} else
1162 if (checkKeyboard(event,"variationNext")){ signmaker.vm.variation(1);} else
1163 if (checkKeyboard(event,"mirror")){ signmaker.vm.mirror();} else
1164 if (checkKeyboard(event,"fillBack")){ signmaker.vm.fill(-1);} else
1165 if (checkKeyboard(event,"fillNext")){ signmaker.vm.fill(1);} else
1166 if (checkKeyboard(event,"recenter")){ signmaker.vm.center();}
1167
1168 if (event.preventDefault) event.preventDefault();
1169 return false;
1170});
\No newline at end of file