diff --git a/.gitignore b/.gitignore index 2985a47..cff3c37 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ fonts/EngraversGothic-Regular-webfont.* fonts/kbd-custom.* jsonl.min.js jsonl.js +*.sublime-workspace *~ diff --git a/CONTRIB.md b/CONTRIB.md index 1556c57..4964d36 100644 --- a/CONTRIB.md +++ b/CONTRIB.md @@ -27,5 +27,6 @@ The following third-party software packages were used in the creation of keyboar * [URLON](https://github.com/vjeux/URLON) (URL Object Notation) * [Jison](http://zaach.github.io/jison/) (JavaScript parser generator) * [Hint.css](http://kushagragour.in/lab/hint/) (CSS-only tooltips) +* [doT.js](http://olado.github.io/doT/) (fast micro-templating) * [Font Awesome](http://fortawesome.github.io/Font-Awesome/) * [C64 TrueType Font](http://style64.org/c64-truetype) font (by [Style64.org](https://www.style64.org)) diff --git a/css/kb.css b/css/kb.css new file mode 100644 index 0000000..b9f247b --- /dev/null +++ b/css/kb.css @@ -0,0 +1 @@ +@font-face{font-family:'engravers_gothic_fsregular';src:url("/fonts/EngraversGothic-Regular-webfont.eot");src:url("/fonts/EngraversGothic-Regular-webfont.eot?#iefix") format('embedded-opentype'),url("/fonts/EngraversGothic-Regular-webfont.woff") format('woff'),url("/fonts/EngraversGothic-Regular-webfont.ttf") format('truetype'),url("/fonts/EngraversGothic-Regular-webfont.svg#engravers_gothic_fsregular") format('svg');font-weight:'normal';font-style:'normal'}@font-face{font-family:'C64ProMono';src:url("/fonts/C64_Pro_Mono-STYLE.eot");src:url("/fonts/C64_Pro_Mono-STYLE.eot?#iefix") format('embedded-opentype'),url("/fonts/C64_Pro_Mono-STYLE.woff") format('woff'),url("/fonts/C64_Pro_Mono-STYLE.ttf") format('truetype'),url("/fonts/C64_Pro_Mono-STYLE.svg#C64ProMono") format('svg');font-weight:'normal';font-style:'normal'}@font-face{font-family:'C64Pro';src:url("/fonts/C64_Pro-STYLE.eot");src:url("/fonts/C64_Pro-STYLE.eot?#iefix") format('embedded-opentype'),url("/fonts/C64_Pro-STYLE.woff") format('woff'),url("/fonts/C64_Pro-STYLE.ttf") format('truetype'),url("/fonts/C64_Pro-STYLE.svg#C64Pro") format('svg');font-weight:'normal';font-style:'normal'}html,body{height:100%;font-family:"Segoe UI","Arial","Helvetica",sans-serif;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.body{margin:10px}.nav,.pagination,.carousel,.panel-title a{cursor:pointer}#wrap{min-height:100%;height:auto !important;height:100%;margin:0 auto -70px;padding:0 0 60px;}#footer{height:70px;background-color:#f5f5f5}#keyboard{padding:9px;position:relative;border:solid 1px #ddd;border-radius:6px;background-color:#eee;min-height:56px;box-sizing:content-box;margin-top:10px;margin-bottom:10px}#keyboard div{position:absolute;border-color:#000;box-sizing:border-box;background-clip:padding-box}#keyboard .hover .keyborder{border-color:#008000 !important;border-style:solid}#keyboard .selected .keyborder{border-color:#f00 !important;border-style:solid}#keyboard .ghosted{opacity:.5}.keylabel>div{display:table-cell;position:static !important}.keylabel3>div,.keylabel4>div,.keylabel6>div,.keylabel8>div{text-align:right}.keylabel7>div,.keylabel8>div{vertical-align:middle}.keylabel2>div,.keylabel4>div{vertical-align:bottom}.keylabel5,.keylabel6{top:100%;margin-top:-1px;font-size:10px !important;white-space:nowrap;overflow:hidden}.keylabel1.centerx-true>div,.keylabel2.centerx-true>div,.keylabel5.centerf-true>div,.keylabel7.centerx-true>div{text-align:center}.keylabel1.centery-true>div,.keylabel3.centery-true>div{vertical-align:middle}.keylabel.textsize1{font-size:8px;line-height:1em}.keylabel.textsize2{font-size:10px;line-height:1em}.keylabel.textsize3{font-size:12px;line-height:1em}.keylabel.textsize4{font-size:14px;line-height:1em}.keylabel.textsize5{font-size:16px;line-height:1em}.keylabel.textsize6{font-size:18px;line-height:1em}.keylabel.textsize7{font-size:20px;line-height:1em}.keylabel.textsize8{font-size:22px;line-height:1em}.keylabel.textsize9{font-size:24px;line-height:1em}.keylabels{font-family:"Helvetica","Arial",sans-serif}.keylabel hr{display:inline}.keylabel hr:before{position:relative;display:block;overflow:hidden;white-space:nowrap;content:"\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500"}.SA .keylabels,.DSA .keylabels{font-family:'engravers_gothic_fsregular';}.DSA .keylabel5,.DSA .keylabel6,.SA .keylabel5,.SA .keylabel6{margin-top:-1px;font-size:9px !important}.DCS .keytop,.OEM .keytop{background:linear-gradient(to right,rgba(0,0,0,0) 0%,rgba(0,0,0,0.102) 40%,rgba(0,0,0,0.102) 60%,rgba(0,0,0,0) 100%);background-repeat:no-repeat}.DSA .keytop,.SA .keytop{background:radial-gradient(ellipse at center,rgba(0,0,0,0.102) 0%,rgba(0,0,0,0.102) 10%,rgba(0,0,0,0) 100%);background-repeat:no-repeat}.DCS.SPACE .keytop,.OEM.SPACE .keytop,.DSA.SPACE .keytop,.SA.SPACE .keytop{background:linear-gradient(to bottom,rgba(0,0,0,0.102) 0%,rgba(0,0,0,0) 20%,rgba(0,0,0,0) 40%,rgba(0,0,0,0.102) 100%);background-repeat:no-repeat}.DSA.DISH .keytop,.DSA.HOMING .keytop,.SA.HOMING .keytop{background:radial-gradient(circle,rgba(0,0,0,0.11) 50%,rgba(0,0,0,0.039) 60%);background-repeat:no-repeat}.HOMING .keytop .keylabels{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAYAAABhYU3QAAAAGElEQVQI12P4//+/ODGYAUwwMAThwyA1ACUKJ4H2Fi17AAAAAElFTkSuQmCC");background-repeat:no-repeat;background-position:center 90%}.DSA.HOMING .keytop .keylabels,.SA.HOMING .keytop .keylabels{background-image:none}span.PETSCII{font-family:"C64ProMono";font-size:6px !important;border:solid 1px;letter-spacing:0;padding:0;margin:0}#swatches{list-style-type:none}.swatch{display:inline-block;position:relative;width:16px;height:32px;border:solid 1px #888;margin-right:-1px;margin-bottom:-6px;padding:0}#swatches.disabled .swatch{background-color:#ebebe4 !important}#swatches [data-hint]:after{white-space:nowrap}.swatch .highlight{display:none}.swatch.selected-bg .highlight.bg{display:block;z-index:100;width:6px;height:6px;border:solid 1px #000;background:#fff;opacity:.75;position:absolute;left:7px;top:23px}.swatch.selected-fg .highlight.fg{display:block;z-index:100;width:6px;height:6px;border:solid 1px #fff;background:#000;opacity:.75;position:absolute;left:1px;top:23px}.hidden{display:none}.error{border:solid 2px #d9534f}#selectionRectangle{position:absolute;border:dashed 2px #f00}#rotationCrosshairs{display:none;position:absolute;margin:0;padding:0;font-size:25px;line-height:23px;width:25px;height:25px;color:#000;text-shadow:-1px 0 #fff,0 1px #fff,1px 0 #fff,0 -1px #fff}#rawdata,#rawdata-error,#noteseditor{font-family:"Consolas","Courier New","Courier",monospace}#rawdata{width:100%}#rawdata-error{white-space:pre}#tab-content{border-left:1px solid #ddd;border-right:1px solid #ddd;border-bottom:1px solid #ddd;padding-top:15px;padding-bottom:15px;margin-left:0}#properties.row{padding-left:30px}.hint--rounded:after{width:300px}.hint:after,[data-hint]:after{white-space:pre-line}.hint:before,.hint:after,[data-hint]:before,[data-hint]:after{-webkit-transition:.1s ease;-moz-transition:.1s ease;transition:.1s ease}.modal-xl .modal-dialog{width:80vw}.modal-xxl .modal-dialog{width:90vw}.markdownDialog .modal-dialog{margin:30 auto}.markdownDialog .modal-header{height:55px}.markdownDialog .modal-footer{height:74px;margin-top:0}.markdownDialog .modal-body{padding-bottom:15px;height:calc(100vh - 205px) !important;overflow-y:auto !important}.drag-over{border:dotted 3px #f00 !important;box-sizing:border-box}@media print{html,body{overflow:hidden;height:100%;margin:0 !important;padding:0 !important}#wrap > .navbar,#wrap > .body > .btn-group,#keyboard ~ *,#keyboard + *,#footer,#helpDialog,#markdownDialog{display:none;margin:0 !important;padding:0 !important}div.body{margin:0 !important;padding:0 !important}a{color:#000;text-decoration:none}#keyboard{border:none;background-color:inherit !important;transform:scale(.75,.75);position:absolute !important;left:0;top:0;padding-left:0;padding-top:0}}.navbar-right{margin-right:0}.form-horizontal .form-inline,.form-horizontal > .form-group.form-group-sm > .form-outdent{margin-left:-15px}.form-horizontal .form-inline .form-group{margin-left:0;margin-right:0}.form-group{margin-bottom:2px}.form-control.input-sm,.input-group-sm > .form-control{height:26px;padding:2px}.input-group-sm > .input-group-btn > .btn{height:26px;padding:2px;min-width:16px}.input-group-sm > .input-group-addon{height:26px;padding:2px;min-width:16px}.form-horizontal .form-group-sm .checkbox{padding-top:3px;min-height:26px}#swap-colors{position:absolute;top:11px;left:200px;z-index:1}.color-name{display:inline-block;min-width:3em;font-size:10px;white-space:nowrap}/*# sourceMappingURL=kb.css.map */ \ No newline at end of file diff --git a/css/kb.css.map b/css/kb.css.map new file mode 100644 index 0000000..78583aa --- /dev/null +++ b/css/kb.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../kb.css"],"names":[],"mappings":"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","file":"kb.css"} \ No newline at end of file diff --git a/js/doT.min.js b/js/doT.min.js new file mode 100644 index 0000000..8fe800e --- /dev/null +++ b/js/doT.min.js @@ -0,0 +1,8 @@ +/* Laura Doktorova https://github.com/olado/doT */ +(function(){function p(b,a,d){return("string"===typeof a?a:a.toString()).replace(b.define||h,function(a,c,e,g){0===c.indexOf("def.")&&(c=c.substring(4));c in d||(":"===e?(b.defineParams&&g.replace(b.defineParams,function(a,b,l){d[c]={arg:b,text:l}}),c in d||(d[c]=g)):(new Function("def","def['"+c+"']="+g))(d));return""}).replace(b.use||h,function(a,c){b.useParams&&(c=c.replace(b.useParams,function(a,b,c,l){if(d[c]&&d[c].arg&&l)return a=(c+":"+l).replace(/'|\\/g,"_"),d.__exp=d.__exp||{},d.__exp[a]= +d[c].text.replace(new RegExp("(^|[^\\w$])"+d[c].arg+"([^\\w$])","g"),"$1"+l+"$2"),b+"def.__exp['"+a+"']"}));var e=(new Function("def","return "+c))(d);return e?p(b,e,d):e})}function k(b){return b.replace(/\\('|\\)/g,"$1").replace(/[\r\t\n]/g," ")}var f={version:"1.0.3",templateSettings:{evaluate:/\{\{([\s\S]+?(\}?)+)\}\}/g,interpolate:/\{\{=([\s\S]+?)\}\}/g,encode:/\{\{!([\s\S]+?)\}\}/g,use:/\{\{#([\s\S]+?)\}\}/g,useParams:/(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g, +define:/\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,defineParams:/^\s*([\w$]+):([\s\S]+)/,conditional:/\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,iterate:/\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,varname:"it",strip:!0,append:!0,selfcontained:!1,doNotSkipEncoded:!1},template:void 0,compile:void 0},m;f.encodeHTMLSource=function(b){var a={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},d=b?/[&<>"'\/]/g:/&(?!#?\w+;)|<|>|"|'|\//g;return function(b){return b? +b.toString().replace(d,function(b){return a[b]||b}):""}};m=function(){return this||(0,eval)("this")}();"undefined"!==typeof module&&module.exports?module.exports=f:"function"===typeof define&&define.amd?define(function(){return f}):m.doT=f;var r={start:"'+(",end:")+'",startencode:"'+encodeHTML("},s={start:"';out+=(",end:");out+='",startencode:"';out+=encodeHTML("},h=/$^/;f.template=function(b,a,d){a=a||f.templateSettings;var n=a.append?r:s,c,e=0,g;b=a.use||a.define?p(a,b,d||{}):b;b=("var out='"+(a.strip? +b.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):b).replace(/'|\\/g,"\\$&").replace(a.interpolate||h,function(b,a){return n.start+k(a)+n.end}).replace(a.encode||h,function(b,a){c=!0;return n.startencode+k(a)+n.end}).replace(a.conditional||h,function(b,a,c){return a?c?"';}else if("+k(c)+"){out+='":"';}else{out+='":c?"';if("+k(c)+"){out+='":"';}out+='"}).replace(a.iterate||h,function(b,a,c,d){if(!a)return"';} } out+='";e+=1;g=d||"i"+e;a=k(a);return"';var arr"+ +e+"="+a+";if(arr"+e+"){var "+c+","+g+"=-1,l"+e+"=arr"+e+".length-1;while("+g+"div { display: table-cell; position: static !important; } +.keylabel3>div, .keylabel4>div, .keylabel6>div, .keylabel8>div { text-align: right; } +.keylabel7>div, .keylabel8>div { vertical-align: middle; } +.keylabel2>div, .keylabel4>div { vertical-align: bottom; } +.keylabel5, .keylabel6 { top: 100%; margin-top: -1px; font-size: 10px !important; white-space: nowrap; overflow: hidden;} +.keylabel1.centerx-true>div, .keylabel2.centerx-true>div, .keylabel5.centerf-true>div, .keylabel7.centerx-true>div { text-align: center; } +.keylabel1.centery-true>div, .keylabel3.centery-true>div { vertical-align: middle; } -/* The external border of the keycap */ -.keyborder { - position: absolute; - border-radius: 5px; - border: solid 1px black; - -webkit-box-sizing:content-box; - -moz-box-sizing:content-box; - box-sizing:content-box; +for i in (1..9) { + .keylabel.textsize{i} { + font-size: (6+2*i)px; + line-height: 1em; + } } -.keyborder.inner { opacity: 0.1; border-radius: 4px; } - -.hover .keyborder { border-color: green; } -.selected .keyborder { border-color: red; } -.ghosted { opacity: 0.4; } - -/* The sides of the cap (darker) */ -.keybg { - position: absolute; - border-radius: 5px; - -webkit-box-sizing:content-box; - -moz-box-sizing:content-box; - box-sizing:content-box; +.keylabels { font-family: "Helvetica", "Arial", sans-serif; } +.keylabel hr { display: inline; } +.keylabel hr:before { + position: relative; + display: block; + overflow: hidden; + white-space: nowrap; + content: "\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500"; } -/* The face of the cap */ -.keyfg { - font-family: "Helvetica", "Arial", sans-serif; - position: absolute; - border-radius: 3px; - display:table-cell; - -webkit-box-sizing:content-box; - -moz-box-sizing:content-box; - box-sizing:content-box; +/* Keycap-Profile Modifications */ +.SA .keylabels, .DSA .keylabels { + font-family: 'engravers_gothic_fsregular'; /* substitute for Gorton Modified */ } -.keyfg .keylabel.textsize1 { font-size: 8px; line-height: 1em; } -.keyfg .keylabel.textsize2 { font-size: 10px; line-height: 1em; } -.keyfg .keylabel.textsize3 { font-size: 12px; line-height: 1em; } -.keyfg .keylabel.textsize4 { font-size: 14px; line-height: 1em; } -.keyfg .keylabel.textsize5 { font-size: 16px; line-height: 1em; } -.keyfg .keylabel.textsize6 { font-size: 18px; line-height: 1em; } -.keyfg .keylabel.textsize7 { font-size: 20px; line-height: 1em; } -.keyfg .keylabel.textsize8 { font-size: 22px; line-height: 1em; } -.keyfg .keylabel.textsize9 { font-size: 24px; line-height: 1em; } -.keyfg .keylabel hr { display: inline; } -.keyfg .keylabel hr:before { - position: relative; - display: block; - overflow: hidden; - white-space: nowrap; - content: "\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500\2500"; -} - -.DCS .keyfg, .OEM .keyfg { - background: -moz-linear-gradient(left, rgba(0,0,0,0) 0%, rgba(0,0,0,0.1) 40%, rgba(0,0,0,0.1) 60%, rgba(0,0,0,0) 100%); - background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(0,0,0,0)), color-stop(40%,rgba(0,0,0,0.1)), color-stop(60%,rgba(0,0,0,0.1)), color-stop(100%,rgba(0,0,0,0))); - background: -webkit-linear-gradient(left, rgba(0,0,0,0) 0%,rgba(0,0,0,0.1) 40%,rgba(0,0,0,0.1) 60%,rgba(0,0,0,0) 100%); - background: -o-linear-gradient(left, rgba(0,0,0,0) 0%,rgba(0,0,0,0.1) 40%,rgba(0,0,0,0.1) 60%,rgba(0,0,0,0) 100%); - background: -ms-linear-gradient(left, rgba(0,0,0,0) 0%,rgba(0,0,0,0.1) 40%,rgba(0,0,0,0.1) 60%,rgba(0,0,0,0) 100%); - background: linear-gradient(to right, rgba(0,0,0,0) 0%,rgba(0,0,0,0.1) 40%,rgba(0,0,0,0.1) 60%,rgba(0,0,0,0) 100%); - background-repeat: no-repeat; + +.DSA .keylabel5, .DSA .keylabel6, .SA .keylabel5, .SA .keylabel6 { margin-top: -1px; font-size: 9px !important; } +.DCS .keytop, .OEM .keytop { + background: linear-gradient(to right, #00000000 0%, #0000001A 40%, #0000001A 60%, #00000000 100%); + background-repeat: no-repeat; } -.DSA .keyborder.inner, .DSA .keyfg { margin-top: 3px; border-radius: 8px; } -.SA .keyborder.inner, .SA .keyfg { margin-top: 1px; border-radius: 5px; } -.DSA .keyfg, .SA .keyfg { - font-family: 'engravers_gothic_fsregular'; /* substitute for Gorton Modified */ - background: -moz-radial-gradient(center, ellipse cover, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0.1) 10%, rgba(0,0,0,0) 100%); - background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(0,0,0,0.1)), color-stop(10%,rgba(0,0,0,0.1)), color-stop(100%,rgba(0,0,0,0))); - background: -webkit-radial-gradient(center, ellipse cover, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0.1) 10%,rgba(0,0,0,0) 100%); - background: -o-radial-gradient(center, ellipse cover, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0.1) 10%,rgba(0,0,0,0) 100%); - background: -ms-radial-gradient(center, ellipse cover, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0.1) 10%,rgba(0,0,0,0) 100%); - background: radial-gradient(ellipse at center, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0.1) 10%,rgba(0,0,0,0) 100%); - background-repeat: no-repeat; +.DSA .keytop, .SA .keytop { + background: radial-gradient(ellipse at center, #0000001A 0%, #0000001A 10%, #00000000 100%); + background-repeat: no-repeat; } -.DCS.SPACE .keyfg, .OEM.SPACE .keyfg, .DSA.SPACE .keyfg, .SA.SPACE .keyfg { - background: -moz-linear-gradient(top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 20%, rgba(0,0,0,0) 40%, rgba(0,0,0,0.1) 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(0,0,0,0.1)), color-stop(20%, rgba(0,0,0,0)), color-stop(40%, rgba(0,0,0,0)), color-stop(100%, rgba(0,0,0,0.1))); - background: -webkit-linear-gradient(top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 20%, rgba(0,0,0,0) 40%, rgba(0,0,0,0.1) 100%); - background: -o-linear-gradient(top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 20%, rgba(0,0,0,0) 40%, rgba(0,0,0,0.1) 100%); - background: -ms-linear-gradient(top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 20%, rgba(0,0,0,0) 40%, rgba(0,0,0,0.1) 100%); - background: linear-gradient(to bottom, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 20%, rgba(0,0,0,0) 40%, rgba(0,0,0,0.1) 100%); - background-repeat: no-repeat; +.DCS.SPACE .keytop, .OEM.SPACE .keytop, .DSA.SPACE .keytop, .SA.SPACE .keytop { + background: linear-gradient(to bottom, #0000001A 0%, #00000000 20%, #00000000 40%, #0000001A 100%); + background-repeat: no-repeat; } -.DSA.DISH .keyfg, .DSA.HOMING .keyfg, .SA.HOMING .keyfg { - background: -moz-radial-gradient(circle, rgba(0,0,0,0.11) 50%, rgba(0,0,0,0.04) 60%); - background: -webkit-gradient(radial, center center, 50%, center center, 60%, from(rgba(0,0,0,0.12)), to(rgba(0,0,0,0.04))); - background: -webkit-radial-gradient(circle, rgba(0,0,0,0.11) 50%, rgba(0,0,0,0.04) 60%); - background: -o-radial-gradient(circle, rgba(0,0,0,0.11) 50%, rgba(0,0,0,0.04) 60%); - background: -ms-radial-gradient(circle, rgba(0,0,0,0.11) 50%, rgba(0,0,0,0.04) 60%); - background: radial-gradient(circle, rgba(0,0,0,0.11) 50%, rgba(0,0,0,0.04) 60%); - background-repeat: no-repeat; +.DSA.DISH .keytop, .DSA.HOMING .keytop, .SA.HOMING .keytop { + background: radial-gradient(circle, #0000001C 50%, #0000000A 60%); + background-repeat: no-repeat; } -.HOMING .keyfg .keylabels { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAYAAABhYU3QAAAAGElEQVQI12P4//+/ODGYAUwwMAThwyA1ACUKJ4H2Fi17AAAAAElFTkSuQmCC); +.HOMING .keytop .keylabels { + background-image: url("nub.png"); background-repeat: no-repeat; background-position: center 90%; } -.DSA.HOMING .keyfg .keylabels, .SA.HOMING .keyfg .keylabels { background-image: none; } +.DSA.HOMING .keytop .keylabels, .SA.HOMING .keytop .keylabels { background-image: none; } span.PETSCII { - font-family: "C64 Pro Mono"; - font-size: 6px !important; - border: solid 1px; - letter-spacing: 0px; - padding: 0; - margin: 0; + font-family: "C64ProMono"; + font-size: 6px !important; + border: solid 1px; + letter-spacing: 0px; + padding: 0; + margin: 0; } -/* Key labels */ -.keylabels { display: table; } -.keylabel { display: table-row; position: absolute; left:2px; top:2px; right:2px; bottom:2px; } -.keylabel > div { display: table-cell; } -.keylabel3>div, .keylabel4>div, .keylabel6>div, .keylabel8>div { text-align: right; } -.keylabel7>div, .keylabel8>div { vertical-align: middle; } -.keylabel2>div, .keylabel4>div { vertical-align: bottom; } -.keylabel5, .keylabel6 { top:100%; margin-top:0px; font-size: 10px !important; white-space:nowrap; overflow: hidden;} -.DSA .keylabel5, .DSA .keylabel6, .SA .keylabel5, .SA .keylabel6 { margin-top:-1px; font-size: 9px !important; } -.keylabel1.centerx-true>div, .keylabel2.centerx-true>div, .keylabel5.centerf-true>div, .keylabel7.centerx-true>div { text-align: center; } -.keylabel1.centery-true>div, .keylabel3.centery-true>div { vertical-align: middle; } - /* color swatches */ -#swatches { - list-style-type: none; - -webkit-margin-before: 0em; - -webkit-margin-after: 0em; - -webkit-margin-start: 0px; - -webkit-margin-end: 0px; - -webkit-padding-start: 0px; -} +#swatches { list-style-type: none; } .swatch { - display: inline-block; - position:relative; - width: 16px; - height: 32px; - border:solid 1px #888; - margin-right:-1px; - margin-bottom:-6px; - padding:0px; + display: inline-block; + position: relative; + width: 16px; + height: 32px; + border: solid 1px #888; + margin-right: -1px; + margin-bottom: -6px; + padding: 0px; } #swatches.disabled .swatch { background-color: rgb(235,235,228) !important; } #swatches [data-hint]:after { white-space: nowrap; } -.swatch .highlight { display:none; } -.swatch.selected-bg .highlight.bg { display:block; z-index:100; width: 6px; height: 6px; border: solid 1px black; background: white; opacity; 0.75; position:absolute; left:7px; top:23px; } -.swatch.selected-fg .highlight.fg { display:block; z-index:100; width: 6px; height: 6px; border: solid 1px white; background: black; opacity; 0.75; position:absolute; left:1px; top:23px; } +.swatch .highlight { display: none; } +.swatch.selected-bg .highlight.bg { display: block; z-index: 100; width: 6px; height: 6px; border: solid 1px black; background: white; opacity: 0.75; position: absolute; left: 7px; top: 23px; } +.swatch.selected-fg .highlight.fg { display: block; z-index: 100; width: 6px; height: 6px; border: solid 1px white; background: black; opacity: 0.75; position: absolute; left: 1px; top: 23px; } /* general styles */ .hidden { display: none; } .error { border: solid 2px rgb(217,83,79); } #selectionRectangle { position: absolute; border: dashed 2px red; } -#rotationCrosshairs { - display: none; - position: absolute; - margin: 0px; - padding: 0px; - font-size: 25px; - line-height: 23px; - width: 25px; - height: 25px; - color: black; - text-shadow: -1px 0 white, 0 1px white, 1px 0 white, 0 -1px white; +#rotationCrosshairs { + display: none; + position: absolute; + margin: 0px; + padding: 0px; + font-size: 25px; + line-height: 23px; + width: 25px; + height: 25px; + color: black; + text-shadow: -1px 0 white, 0 1px white, 1px 0 white, 0 -1px white; } #rawdata, #rawdata-error, #noteseditor { font-family: "Consolas", "Courier New", "Courier", monospace; } @@ -256,49 +180,43 @@ span.PETSCII { padding-bottom: 15px; margin-left: 0px; } -#properties.row { padding-left:30px; } - -/*Help Dialog*/ -.modal-xl .modal-dialog { width:80vw; } -.modal-xxl .modal-dialog { width:90vw; } +#properties.row { padding-left: 30px; } /* Tooltip modifications */ .hint--rounded:after { width: 300px; } .hint:after, [data-hint]:after { white-space: pre-line; } .hint:before, .hint:after, [data-hint]:before, [data-hint]:after { -webkit-transition: 0.1s ease; -moz-transition: 0.1s ease; transition: 0.1s ease; } -#swap-colors { position: absolute; top: 11px; left: 200px; z-index: 1; } -.color-name { display: inline-block; min-width: 3em; font-size: 10px; white-space: nowrap; } +/* Help Dialog */ +.modal-xl .modal-dialog { width: 80vw; } +.modal-xxl .modal-dialog { width: 90vw; } /* Our "README" dialog; we want the body of the dialog itself to be scrollable */ .markdownDialog .modal-dialog { margin: 30 auto; } /*60px*/ .markdownDialog .modal-header { height: 55px; } .markdownDialog .modal-footer { height: 74px; margin-top: 0px; } .markdownDialog .modal-body { - padding-bottom: 15px; - height: calc(100vh - 205px) !important; - overflow-y: auto !important; + padding-bottom: 15px; + height: calc(100vh - 205px) !important; + overflow-y: auto !important; } .drag-over { border: dotted 3px red !important; box-sizing: border-box; } /* Only show the keyboard layout itself when printing */ @media print { - html, body { overflow:hidden; height:100%; margin: 0 !important; padding: 0 !important; } + html, body { overflow: hidden; height: 100%; margin: 0 !important; padding: 0 !important; } #wrap > .navbar, #wrap > .body > .btn-group, #keyboard ~ *, #keyboard + *, #footer, #helpDialog, #markdownDialog { display: none; margin: 0 !important; padding: 0 !important; } div.body { margin: 0 !important; padding: 0 !important; } a { color: black; text-decoration: none; } #keyboard { - border: none; - background-color: inherit !important; - transform:scale(0.75,0.75); - -moz-transform:scale(0,75,0.75); - -ms-transform:scale(0,75,0.75); - -webkit-transform:scale(0.75,0.75); - position: absolute !important; - left: 0px; - top: 0px; - padding-left: 0px; padding-top: 0px; + border: none; + background-color: inherit !important; + transform: scale(0.75,0.75); + position: absolute !important; + left: 0px; + top: 0px; + padding-left: 0px; padding-top: 0px; } } @@ -312,4 +230,7 @@ span.PETSCII { .form-control.input-sm, .input-group-sm > .form-control { height: 26px; padding: 2px; } .input-group-sm > .input-group-btn > .btn { height: 26px; padding: 2px; min-width: 16px; } .input-group-sm > .input-group-addon { height: 26px; padding: 2px; min-width: 16px; } -.form-horizontal .form-group-sm .checkbox { padding-top: 3px; min-height:26px; } +.form-horizontal .form-group-sm .checkbox { padding-top: 3px; min-height: 26px; } + +#swap-colors { position: absolute; top: 11px; left: 200px; z-index: 1; } +.color-name { display: inline-block; min-width: 3em; font-size: 10px; white-space: nowrap; } diff --git a/kb.html b/kb.html index 51a1cbc..5d9fd1a 100644 --- a/kb.html +++ b/kb.html @@ -12,7 +12,7 @@ All rights reserved. - + @@ -27,6 +27,7 @@ All rights reserved. + @@ -552,7 +553,7 @@ Footer Copyright © 2013-2015 — Ian Prest (and contributors)
All rights reserved. (LICENSE)

-
+
Help & keyboard shortcuts
Found a bug?
Code hosted on GitHub
@@ -693,6 +694,10 @@ Options Dialog
+ + + + + + + \ No newline at end of file diff --git a/kb.js b/kb.js index 643a335..336d9e0 100644 --- a/kb.js +++ b/kb.js @@ -203,7 +203,7 @@ }); if($scope.keyboard.meta.name || $scope.keyboard.meta.author) bottom += 32; - $scope.kbHeight = bottom + 8; + $scope.kbHeight = bottom; }; // Given a key, generate the HTML needed to render it diff --git a/kb.sublime-project b/kb.sublime-project new file mode 100644 index 0000000..3046ce1 --- /dev/null +++ b/kb.sublime-project @@ -0,0 +1,35 @@ +{ + "folders": + [ + { + "name": "Root", + "path": "." + } + ], + "settings": + { + "tab_size": 2, + "translate_tabs_to_spaces": true, + "build_system": "Automatic", + + //SublimeOnSaveBuild package (optional) + "filename_filter": "\\.(css|js|sass|less|scss)$", + "build_on_save": 1 + }, + "build_systems": + [ + { + "name": "Stylus.KB", + "cmd": ["stylus", "--out", "css", "-c", "-m", "--inline", "--with", "{limit:1024}", "$file" ], + "windows": { "cmd": ["stylus.cmd", "--out", "css", "-c", "-m", "--inline", "--with", "{limit:1024}", "$file" ] }, + "selector": "source.css, source.stylus", + "working_dir" : "$project_path" + }, + { + "name": "Make.KB", + "cmd": ["cmd", "/c", "dir"], + "selector": "source.js, text.html", + "working_dir" : "$project_path" + } + ] +} diff --git a/nub.png b/nub.png new file mode 100644 index 0000000..1f4895f Binary files /dev/null and b/nub.png differ diff --git a/render.js b/render.js index 19a679e..f8e8ffc 100644 --- a/render.js +++ b/render.js @@ -3,17 +3,37 @@ var $renderKey = {}; "use strict"; // Some predefined sizes for our caps: - // - cap == size of 1 unit, e.g., 0.75", or 19.05mm is standard - // - spacing == distance from edge of unit to cap, e.g., (0.75" - 0.715")/2 (for DCS) - // - margin == distance from edge of cap (at bottom) to edge of cap (at top), e.g., (0.715" - 0.470")/2 (for DCS) - // - padding == distance between text & edge of cap; should match CSS - // - strokeWidth == thickness of the outline strokes; should match CSS - // - roundInner/roundOuter == corner roundness for inner/outer borders; should match CSS - // - scaleFactor == scale between unit type and actual numbers used + // - unit == size of 1 unit, e.g., 0.75", or 19.05mm is standard + // - keySpacing == distance from edge of unit-square to keycap, e.g., (0.75" - 0.715")/2 (for DCS) + // - bevelMargin == distance from edge of keycap (at bottom) to edge of keycap (at top), e.g., (0.715" - 0.470")/2 (for DCS) + // - padding == distance between text & edge of keycap + // - strokeWidth == thickness of the outline strokes + // - roundInner/roundOuter == corner roundness for inner/outer borders var unitSizes = { - px : { cap: 54, padding: 2, margin: 6, spacing: 1, strokeWidth: 1, roundOuter: 5, roundInner: 3, scaleFactor: 1 }, // pixels - mm : { cap: 1905, padding: 0, margin: 311.15, spacing: 44.45, strokeWidth: 20, roundOuter: 100, roundInner: 200, scaleFactor: 100 } // 1/100 mm + px : { + unit : 54, + strokeWidth: 1, + "" : { keySpacing: 0, bevelMargin: 6, bevelOffsetY: 3, padding: 3, roundOuter: 5, roundInner: 3 }, + "DCS" : { keySpacing: 0, bevelMargin: 6, bevelOffsetY: 3, padding: 3, roundOuter: 5, roundInner: 3 }, + "DSA" : { keySpacing: 0, bevelMargin: 6, bevelOffsetY: 0, padding: 3, roundOuter: 5, roundInner: 8 }, + "SA" : { keySpacing: 0, bevelMargin: 6, bevelOffsetY: 2, padding: 3, roundOuter: 5, roundInner: 5 } + }, + mm : { + unit: 19.05, + strokeWidth: 0.20, + "" : { keySpacing: 0.4445, bevelMargin: 3.1115, padding: 0, roundOuter: 1.0, roundInner: 2.0 }, + "DCS" : { keySpacing: 0.4445, bevelMargin: 3.1115, padding: 0, roundOuter: 1.0, roundInner: 2.0 }, + "DSA" : { keySpacing: 0.4445, bevelMargin: 3.1115, padding: 0, roundOuter: 1.0, roundInner: 2.0 }, + "SA" : { keySpacing: 0.4445, bevelMargin: 3.1115, padding: 0, roundOuter: 1.0, roundInner: 2.0 } + } }; + ["px","mm"].forEach(function(unit) { + ["","DCS","DSA", "SA"].forEach(function(profile) { + unitSizes[unit][profile].unit = unitSizes[unit].unit; + unitSizes[unit][profile].strokeWidth = unitSizes[unit].strokeWidth; + }); + unitSizes[unit].OEM = unitSizes[unit].DCS; // same, for now + }); // Lighten a color by the specified amount function lightenColor(color,mod) { @@ -22,146 +42,152 @@ var $renderKey = {}; return c.sRGB8(); } - function capsize(sizes,size) { return (size*sizes.cap) - (2*sizes.spacing); }; + function getProfile(key) { + return (/\b(SA|DSA|DCS|OEM)\b/.exec(key.profile) || [""])[0]; + } + function getRenderParms(key, sizes) { var parms = {}; - parms.capwidth = capsize(sizes,key.width); - parms.capwidth2 = capsize(sizes,key.width2); - parms.capheight = capsize(sizes,key.height); - parms.capheight2 = capsize(sizes,key.height2); - parms.capx = capsize(sizes,key.x) + sizes.margin; - parms.capx2 = capsize(sizes,key.x+key.x2)+sizes.margin; - parms.capy = capsize(sizes,key.y) + sizes.margin; - parms.capy2 = capsize(sizes,key.y+key.y2)+sizes.margin; - parms.jShaped = (parms.capwidth2 !== parms.capwidth) || (parms.capheight2 !== parms.capheight) || (parms.capx2 !== parms.capx) || (parms.capy2 !== parms.capy); - parms.innerPadding = (2*sizes.margin) + (2*sizes.padding); - parms.borderStyle = key.ghost ? "keyborder ghosted" : "keyborder"; - parms.bgStyle = key.ghost ? "keybg ghosted" : "keybg"; + + parms.jShaped = (key.width !== key.width2) || (key.height !== key.height2) || key.x2 || key.y2; + + // Overall dimensions of the unit square(s) that the cap occupies + parms.capwidth = sizes.unit * key.width; + parms.capheight = sizes.unit * key.height; + parms.capx = sizes.unit * key.x; + parms.capy = sizes.unit * key.y; + if(parms.jShaped) { + parms.capwidth2 = sizes.unit * key.width2; + parms.capheight2 = sizes.unit * key.height2; + parms.capx2 = sizes.unit * (key.x + key.x2); + parms.capy2 = sizes.unit * (key.y + key.y2); + } + + // Dimensions of the outer part of the cap + parms.outercapwidth = parms.capwidth - sizes.keySpacing*2; + parms.outercapheight = parms.capheight - sizes.keySpacing*2; + parms.outercapx = parms.capx + sizes.keySpacing; + parms.outercapy = parms.capy + sizes.keySpacing; + if(parms.jShaped) { + parms.outercapy2 = parms.capy2 + sizes.keySpacing; + parms.outercapx2 = parms.capx2 + sizes.keySpacing; + parms.outercapwidth2 = parms.capwidth2 - sizes.keySpacing*2; + parms.outercapheight2 = parms.capheight2 - sizes.keySpacing*2; + } + + // Dimensions of the top of the cap + parms.innercapwidth = parms.outercapwidth - sizes.bevelMargin*2; + parms.innercapheight = parms.outercapheight - sizes.bevelMargin*2; + parms.innercapx = parms.outercapx + sizes.bevelMargin; + parms.innercapy = parms.outercapy + sizes.bevelMargin - sizes.bevelOffsetY; + if(parms.jShaped) { + parms.innercapwidth2 = parms.outercapwidth2 - sizes.bevelMargin*2; + parms.innercapheight2 = parms.outercapheight2 - sizes.bevelMargin*2; + parms.innercapx2 = parms.outercapx2 + sizes.bevelMargin; + parms.innercapy2 = parms.outercapy2 + sizes.bevelMargin - sizes.bevelOffsetY; + } + + // Dimensions of the text part of the cap + parms.textcapwidth = parms.innercapwidth - sizes.padding*2; + parms.textcapheight = parms.innercapheight - sizes.padding*2; + parms.textcapx = parms.innercapx + sizes.padding; + parms.textcapy = parms.innercapy + sizes.padding; + parms.darkColor = key.color; parms.lightColor = lightenColor($color.hex(key.color), 1.2).hex(); - key.centerx = key.align&1 ? true : false; - key.centery = key.align&2 ? true : false; - key.centerf = key.align&4 ? true : false; - return parms; - } - - function getKeyBounds(key, sizes, parms) { - var bounds = {}; // Rotation matrix about the origin - bounds.origin_x = capsize(sizes,key.rotation_x)+sizes.margin; - bounds.origin_y = capsize(sizes,key.rotation_y)+sizes.margin; - var mat = Math.transMatrix(bounds.origin_x, bounds.origin_y).mult(Math.rotMatrix(key.rotation_angle)).mult(Math.transMatrix(-bounds.origin_x, -bounds.origin_y)); + parms.origin_x = sizes.unit * key.rotation_x; + parms.origin_y = sizes.unit * key.rotation_y; + var mat = Math.transMatrix(parms.origin_x, parms.origin_y).mult(Math.rotMatrix(key.rotation_angle)).mult(Math.transMatrix(-parms.origin_x, -parms.origin_y)); // Construct the *eight* corner points, transform them, and determine the transformed bbox. - bounds.rect = { x:parms.capx, y:parms.capy, w:parms.capwidth, h:parms.capheight, x2:parms.capx+parms.capwidth, y2:parms.capy+parms.capheight }; - bounds.rect2 = { x:parms.capx2, y:parms.capy2, w:parms.capwidth2, h:parms.capheight2, x2:parms.capx2+parms.capwidth2, y2:parms.capy2+parms.capheight2 }; - bounds.bbox = { x:9999999, y:9999999, x2:-9999999, y2:-9999999 }; + parms.rect = { x:parms.capx, y:parms.capy, w:parms.capwidth, h:parms.capheight, x2:parms.capx+parms.capwidth, y2:parms.capy+parms.capheight }; + parms.rect2 = parms.jShaped ? { x:parms.capx2, y:parms.capy2, w:parms.capwidth2, h:parms.capheight2, x2:parms.capx2+parms.capwidth2, y2:parms.capy2+parms.capheight2 } : parms.rect; + parms.bbox = { x:9999999, y:9999999, x2:-9999999, y2:-9999999 }; var corners = [ - {x:bounds.rect.x, y:bounds.rect.y}, - {x:bounds.rect.x, y:bounds.rect.y2}, - {x:bounds.rect.x2, y:bounds.rect.y}, - {x:bounds.rect.x2, y:bounds.rect.y2}, - {x:bounds.rect2.x, y:bounds.rect2.y}, - {x:bounds.rect2.x, y:bounds.rect2.y2}, - {x:bounds.rect2.x2, y:bounds.rect2.y}, - {x:bounds.rect2.x2, y:bounds.rect2.y2}, + {x:parms.rect.x, y:parms.rect.y}, + {x:parms.rect.x, y:parms.rect.y2}, + {x:parms.rect.x2, y:parms.rect.y}, + {x:parms.rect.x2, y:parms.rect.y2} ]; + if(parms.jShaped) corners.push( + {x:parms.rect2.x, y:parms.rect2.y}, + {x:parms.rect2.x, y:parms.rect2.y2}, + {x:parms.rect2.x2, y:parms.rect2.y}, + {x:parms.rect2.x2, y:parms.rect2.y2} + ); for(var i = 0; i < corners.length; ++i) { corners[i] = mat.transformPt(corners[i]); - bounds.bbox.x = Math.min(bounds.bbox.x, corners[i].x); - bounds.bbox.y = Math.min(bounds.bbox.y, corners[i].y); - bounds.bbox.x2 = Math.max(bounds.bbox.x2, corners[i].x); - bounds.bbox.y2 = Math.max(bounds.bbox.y2, corners[i].y); + parms.bbox.x = Math.min(parms.bbox.x, corners[i].x); + parms.bbox.y = Math.min(parms.bbox.y, corners[i].y); + parms.bbox.x2 = Math.max(parms.bbox.x2, corners[i].x); + parms.bbox.y2 = Math.max(parms.bbox.y2, corners[i].y); } - bounds.bbox.w = bounds.bbox.x2 - bounds.bbox.x; - bounds.bbox.h = bounds.bbox.y2 - bounds.bbox.y; + parms.bbox.w = parms.bbox.x2 - parms.bbox.x; + parms.bbox.h = parms.bbox.y2 - parms.bbox.y; - return bounds; + return parms; } + function STYLE(style) { + var html = ""; + for(var key in style) { + if(style.hasOwnProperty(key)) { + html += key + ":" + style[key].toString(); + if(typeof style[key] === 'number') html += "px"; + html += ';'; + } + } + return html; + } + + function DIV(style, className, content) { + var html = "
") - .format(key.rotation_angle, bounds.origin_x, bounds.origin_y); - } - - var div = "
\n"; - - // The border - html += div.format(parms.capwidth, parms.capheight, parms.capx, parms.capy, parms.darkColor, parms.borderStyle); - if(parms.jShaped) { - html += div.format(parms.capwidth2, parms.capheight2, parms.capx2, parms.capy2, parms.darkColor, parms.borderStyle); - } - // The key edges - html += div.format(parms.capwidth, parms.capheight, parms.capx+1, parms.capy+1, parms.darkColor, parms.bgStyle); - if(parms.jShaped) { - html += div.format(parms.capwidth2, parms.capheight2, parms.capx2+1, parms.capy2+1, parms.darkColor, parms.bgStyle); - } - - if(!key.ghost) { - // The top of the cap - var divInner = "
\n"; - html += divInner.format( parms.capwidth-parms.innerPadding, parms.capheight-parms.innerPadding, parms.capx+sizes.margin, parms.capy+(sizes.margin/2), parms.lightColor, sizes.padding ); - if(parms.jShaped && !key.stepped) { - html += divInner.format( parms.capwidth2-parms.innerPadding, parms.capheight2-parms.innerPadding, parms.capx2+sizes.margin, parms.capy2+(sizes.margin/2), parms.lightColor, sizes.padding ); - } - - var maxWidth = parms.capwidth-(2*sizes.margin); - var maxHeight = parms.capheight-(2*sizes.margin); - var divFg = "
\n" - if(parms.jShaped && !key.stepped) { - maxWidth = Math.max(parms.capwidth,parms.capwidth2)-(2*sizes.margin); - maxHeight = Math.max(parms.capheight,parms.capheight2)-(2*sizes.margin); - html += divFg.format( parms.capwidth2-parms.innerPadding, parms.capheight2-parms.innerPadding, parms.capx2+sizes.margin+1, parms.capy2+(sizes.margin/2)+1, parms.lightColor, sizes.padding, maxWidth, maxHeight, Math.min(parms.capx,parms.capx2)-parms.capx2, Math.min(parms.capy,parms.capy2)-parms.capy2 ); - html += "
"; - } - html += divFg.format( parms.capwidth-parms.innerPadding, parms.capheight-parms.innerPadding, parms.capx+sizes.margin+1, parms.capy+(sizes.margin/2)+1, parms.lightColor, sizes.padding, maxWidth, maxHeight, Math.min(parms.capx,parms.capx2)-parms.capx, Math.min(parms.capy,parms.capy2)-parms.capy ); - - // The key labels - html += "
" /*left:{2}px; top:{3}px*/ - .format(parms.capwidth-parms.innerPadding, parms.capheight-parms.innerPadding, parms.capx+sizes.margin+1, parms.capy+(sizes.margin/2)+1); - key.labels.forEach(function(label,i) { - if(label && label !== "" && !(key.align&$renderKey.noRenderText[i])) { - var sanitizedLabel = '
'; - try { sanitizedLabel = $sanitize(label.replace(/<([^a-zA-Z\/]|$)/,"<$1")); } catch(e) {} - var textColor = i < key.text.length ? key.text[i] : key.text[0]; - if(!textColor) textColor = key.text[0]; - var textColorLight = lightenColor($color.hex(textColor), 1.2).hex(); - html += "
{0}
\n" - .format(sanitizedLabel, i===4||i===5 ? textColor : textColorLight, i+1, parms.capwidth-parms.innerPadding, parms.capheight-parms.innerPadding, - key.centerx, key.centery, key.centerf, i>0 ? key.fontheight2 : key.fontheight); - } - }); - html += "
"; - } - return html; + return html_t(key, $sanitize, lightenColor); }; // Given a key, generate the SVG needed to render it @@ -169,16 +195,15 @@ var $renderKey = {}; // Update bbox var parms = getRenderParms(key, sizes); - var bounds = getKeyBounds(key, sizes, parms); - bbox.x = Math.min(bbox.x, bounds.bbox.x); - bbox.y = Math.min(bbox.y, bounds.bbox.y); - bbox.x2 = Math.max(bbox.x2, bounds.bbox.x2); - bbox.y2 = Math.max(bbox.y2, bounds.bbox.y2); + bbox.x = Math.min(bbox.x, parms.bbox.x); + bbox.y = Math.min(bbox.y, parms.bbox.y); + bbox.x2 = Math.max(bbox.x2, parms.bbox.x2); + bbox.y2 = Math.max(bbox.y2, parms.bbox.y2); // Generate the SVG var svg = "\n"; if(key.rotation_angle) { - svg = "\n".format(key.rotation_angle, bounds.origin_x, bounds.origin_y); + svg = "\n".format(key.rotation_angle, parms.origin_x, parms.origin_y); } var rectStrokeAndFill = ("\n" + @@ -199,20 +224,20 @@ var $renderKey = {}; } if(!key.ghost) { - // The top of the cap - svg += rectStrokeAndFill.format( parms.capwidth-(2*sizes.margin), parms.capheight-(2*sizes.margin), parms.capx+sizes.margin+1, parms.capy+(sizes.margin/2)+1, parms.lightColor, "keyborder inner", roundInner ); + // The top of the keycap + svg += rectStrokeAndFill.format( parms.capwidth-(2*sizes.bevelMargin), parms.capheight-(2*sizes.bevelMargin), parms.capx+sizes.bevelMargin+1, parms.capy+(sizes.bevelMargin/2)+1, parms.lightColor, "keyborder inner", roundInner ); if(parms.jShaped && !key.stepped) { - svg += rectStrokeAndFill.format( parms.capwidth2-(2*sizes.margin), parms.capheight2-(2*sizes.margin), parms.capx2+sizes.margin+1, parms.capy2+(sizes.margin/2)+1, parms.lightColor, "keyborder inner", roundInner ); + svg += rectStrokeAndFill.format( parms.capwidth2-(2*sizes.bevelMargin), parms.capheight2-(2*sizes.bevelMargin), parms.capx2+sizes.bevelMargin+1, parms.capy2+(sizes.bevelMargin/2)+1, parms.lightColor, "keyborder inner", roundInner ); } - var maxWidth = parms.capwidth-(2*sizes.margin); - var maxHeight = parms.capheight-(2*sizes.margin); + var maxWidth = parms.capwidth-(2*sizes.bevelMargin); + var maxHeight = parms.capheight-(2*sizes.bevelMargin); if(parms.jShaped && !key.stepped) { - maxWidth = Math.max(parms.capwidth,parms.capwidth2)-(2*sizes.margin); - maxHeight = Math.max(parms.capheight,parms.capheight2)-(2*sizes.margin); - svg += rectFill.format( parms.capwidth2-(2*sizes.margin), parms.capheight2-(2*sizes.margin), parms.capx2+sizes.margin+1, parms.capy2+(sizes.margin/2)+1, parms.lightColor, "keyfg", roundInner ); + maxWidth = Math.max(parms.capwidth,parms.capwidth2)-(2*sizes.bevelMargin); + maxHeight = Math.max(parms.capheight,parms.capheight2)-(2*sizes.bevelMargin); + svg += rectFill.format( parms.capwidth2-(2*sizes.bevelMargin), parms.capheight2-(2*sizes.bevelMargin), parms.capx2+sizes.bevelMargin+1, parms.capy2+(sizes.bevelMargin/2)+1, parms.lightColor, "keyfg", roundInner ); } - svg += rectFill.format( parms.capwidth-(2*sizes.margin), parms.capheight-(2*sizes.margin), parms.capx+sizes.margin+1, parms.capy+(sizes.margin/2)+1, parms.lightColor, "keyfg", roundInner ); + svg += rectFill.format( parms.capwidth-(2*sizes.bevelMargin), parms.capheight-(2*sizes.bevelMargin), parms.capx+sizes.bevelMargin+1, parms.capy+(sizes.bevelMargin/2)+1, parms.lightColor, "keyfg", roundInner ); //TODO//key labels } @@ -223,19 +248,18 @@ var $renderKey = {}; $renderKey.fullSVG = function(keys, metadata) { // Render all the keys var units = "px"; - var sizes = unitSizes[units]; var bbox = { x: 99999999, y:99999999, x2:-99999999, y2:-99999999 }; var keysSVG = ""; keys.forEach(function(key) { - keysSVG += $renderKey.svg(key, bbox, sizes); + keysSVG += $renderKey.svg(key, bbox, unitSizes[units][getProfile(key)]); }); // Wrap with SVG boilerplate var kbdMargin = 10, kbdPadding = 5; - var width = bbox.x2 + sizes.margin*2 + kbdMargin*2 + kbdPadding*2; - var height = bbox.y2 + sizes.margin*2 + kbdMargin*2 + kbdPadding*2; + var width = bbox.x2 + kbdMargin*2 + kbdPadding*2; + var height = bbox.y2 + kbdMargin*2 + kbdPadding*2; var svg = "\n" - .format( width/sizes.scaleFactor, height/sizes.scaleFactor, width, height, units); + .format( width, height, width, height, units); // styles svg += "