index.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="apple-mobile-web-app-capable" content="yes" />
  5. <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
  6. <meta charset="UTF-8">
  7. <meta name="theme-color" content="#4b75ff">
  8. <link rel="stylesheet" href="../script/semantic/semantic.min.css">
  9. <link rel="stylesheet" href="../script/ao.css">
  10. <script src="../script/jquery.min.js"></script>
  11. <script src="../script/ao_module.js"></script>
  12. <script src="../script/semantic/semantic.min.js"></script>
  13. <script src="qr/qrious.min.js"></script>
  14. <title>IMUS Label Maker</title>
  15. <style>
  16. body{
  17. background-color:white;
  18. }
  19. @font-face {
  20. font-family: 'TaipeiSansTCBeta';
  21. src: url("font/TaipeiSansTCBeta-Regular.ttf");
  22. }
  23. </style>
  24. </head>
  25. <body>
  26. <br><br>
  27. <div class="ui container">
  28. <div class="ui basic segment">
  29. <h2 class="ui header">
  30. IMUS Label Maker
  31. <div class="sub header">Generate a new label for the latest project</div>
  32. </h2>
  33. </div>
  34. <div class="ui segment">
  35. <h3>Settings and Properties</h3>
  36. <p>Width & Height</p>
  37. <div class="ui right labeled input">
  38. <input type="text" placeholder="Width" onchange="updateCanvasWidth(this.value);">
  39. <div class="ui basic label">
  40. mm
  41. </div>
  42. </div>
  43. <div class="ui right labeled input">
  44. <input type="text" placeholder="Height" onchange="updateCanvasHeight(this.value);">
  45. <div class="ui basic label">
  46. mm
  47. </div>
  48. </div>
  49. <br><br>
  50. <p>Product Title</p>
  51. <div class="ui fluid input">
  52. <input type="text" placeholder="Title" onchange="updateTitle(this.value);">
  53. </div>
  54. <br><br>
  55. <p>Product Subtitle</p>
  56. <div class="ui fluid input">
  57. <input type="text" placeholder="Subtitle" onchange="updateSubtitle(this.value);">
  58. </div>
  59. <br><br>
  60. <p>Techical Specification (Seperate by comma)</p>
  61. <div class="ui fluid input">
  62. <input type="text" placeholder="Specification" onchange="updateTechSpec(this.value);">
  63. </div>
  64. <br><br>
  65. <p>Project Codename</p>
  66. <div class="ui fluid input">
  67. <input type="text" placeholder="Codename" onchange="updateProjcetCodename(this.value);">
  68. </div>
  69. <div class="ui divider"></div>
  70. <p>Warning Labels</p>
  71. <div class="ui segment" id="warninglabels">
  72. <div style="padding:8px;">
  73. <div class="ui checkbox">
  74. <input type="checkbox" name="disposable.png">
  75. <label>Disposable</label>
  76. </div>
  77. </div>
  78. <div style="padding:8px;">
  79. <div class="ui checkbox">
  80. <input type="checkbox" name="do-not-touch.png">
  81. <label>Do not Touch</label>
  82. </div>
  83. </div>
  84. <div style="padding:8px;">
  85. <div class="ui checkbox">
  86. <input type="checkbox" name="do-not-stack.png">
  87. <label>Do not Stack</label>
  88. </div>
  89. </div>
  90. <div style="padding:8px;">
  91. <div class="ui checkbox">
  92. <input type="checkbox" name="fragile.png">
  93. <label>Fragile</label>
  94. </div>
  95. </div>
  96. <div style="padding:8px;">
  97. <div class="ui checkbox">
  98. <input type="checkbox" name="handle-with-care.png">
  99. <label>Handle with care</label>
  100. </div>
  101. </div>
  102. <div style="padding:8px;">
  103. <div class="ui checkbox">
  104. <input type="checkbox" name="hot-surface.png">
  105. <label>Hot Surface</label>
  106. </div>
  107. </div>
  108. <div style="padding:8px;">
  109. <div class="ui checkbox">
  110. <input type="checkbox" name="kepp-dry.png">
  111. <label>Keep Dry</label>
  112. </div>
  113. </div>
  114. <div style="padding:8px;">
  115. <div class="ui checkbox">
  116. <input type="checkbox" name="li-ion.png">
  117. <label>Contain Li-ion Battery</label>
  118. </div>
  119. </div>
  120. <div style="padding:8px;">
  121. <div class="ui checkbox">
  122. <input type="checkbox" name="no-fire.png">
  123. <label>Do not dispose in Fire</label>
  124. </div>
  125. </div>
  126. <div style="padding:8px;">
  127. <div class="ui checkbox">
  128. <input type="checkbox" name="protect-from-heat.png">
  129. <label>Do not expose to Sunlight</label>
  130. </div>
  131. </div>
  132. <div style="padding:8px;">
  133. <div class="ui checkbox">
  134. <input type="checkbox" name="raspberry-pi.png">
  135. <label>Contain Raspberry Pi</label>
  136. </div>
  137. </div>
  138. <div style="padding:8px;">
  139. <div class="ui checkbox">
  140. <input type="checkbox" name="require-recycle.jpg">
  141. <label>Require Recycle</label>
  142. </div>
  143. </div>
  144. <div style="padding:8px;">
  145. <div class="ui checkbox">
  146. <input type="checkbox" name="solar-power.png">
  147. <label>Solar Powered</label>
  148. </div>
  149. </div>
  150. <div style="padding:8px;">
  151. <div class="ui checkbox">
  152. <input type="checkbox" name="this-side-up.png">
  153. <label>This Side Up</label>
  154. </div>
  155. </div>
  156. <div style="padding:8px;">
  157. <div class="ui checkbox">
  158. <input type="checkbox" name="wifi.png">
  159. <label>WiFi Included</label>
  160. </div>
  161. </div>
  162. </div>
  163. </div>
  164. <div class="ui divider"></div>
  165. <p>Label Preview</p>
  166. <canvas id="labelcanvas" style="border: 1px solid black;"></canvas>
  167. <p>CopyRight imuslab 2020 - 2021, All Right Reserved</p>
  168. <p>This is a label generator for imuslab standard product description label. All label generated can be used free of charge and be modified as you like. However, it is critical to keep track of each products with a uniquid codename (and QR code which will be generated automatically) for future warehouse management purposes.</p>
  169. <br><br>
  170. </div>
  171. <script>
  172. var dpcm = 118.11; //Convert pixel to mm, mm * dpcm = pixel on screen
  173. var canvas = document.getElementById("labelcanvas");
  174. var ctx = canvas.getContext("2d");
  175. //Default Values
  176. var itemTitle = "樣本機 A100";
  177. var itemSubtitle = "研究用樣本機,只供內部測試用途";
  178. var specText = "Specification";
  179. var techSpec = ["迷你核融合反應堆", "128Qbit 量子計算模組", "1.2TB DDR8 記憶體", "1kAH 聚合物鋰離子電池", "CocaCola Plus 1.2L (冷卻用)"]
  180. var projectCodename = "PROTO-A100_1/1/2021";
  181. var warningLabels = [];
  182. function renderBasicElements(){
  183. //Fill background
  184. ctx.fillStyle = "#ffffff";
  185. ctx.fillRect(0, 0, canvas.width, canvas.height);
  186. //Render title bar
  187. ctx.fillStyle = "#242424";
  188. var defaultOffset = [canvas.width * 0.04, canvas.height * 0.06];
  189. ctx.fillRect(0, defaultOffset[1], 20, 140);
  190. //Render main title
  191. ctx.font ="40px TaipeiSansTCBeta";
  192. ctx.textBaseline = 'top';
  193. ctx.fillText(itemTitle, defaultOffset[0] + 10, defaultOffset[1] + 22);
  194. //Render subtitle
  195. ctx.font ="25px TaipeiSansTCBeta";
  196. ctx.fillText(itemSubtitle, defaultOffset[0] + 10, defaultOffset[1] + 72);
  197. //Update offset for specification
  198. if (canvas.height * 0.33 - canvas.height * 0.06 < 220){
  199. defaultOffset = [canvas.width * 0.08, canvas.height * 0.43];
  200. }else{
  201. defaultOffset = [canvas.width * 0.08, canvas.height * 0.33];
  202. }
  203. //Render spec horizontal bar
  204. ctx.fillText(specText, defaultOffset[0], defaultOffset[1] - 30);
  205. ctx.fillRect(defaultOffset[0], defaultOffset[1], canvas.width * 0.3, 3);
  206. //Render the specification list
  207. for (var i =0; i < techSpec.length; i++){
  208. ctx.fillText(techSpec[i], defaultOffset[0] + 10, defaultOffset[1] + 20 + 35 * i);
  209. }
  210. //Render the QR Code
  211. var qrcodeSize = 250;
  212. qrcodeContent = generateQRCode(projectCodename, qrcodeSize);
  213. var img = new Image;
  214. img.onload = function(){
  215. ctx.drawImage(img,canvas.width - qrcodeSize, canvas.height - qrcodeSize - 40);
  216. ctx.font ="18px TaipeiSansTCBeta";
  217. ctx.fillText(projectCodename, canvas.width - qrcodeSize + 25, canvas.height - 60);
  218. };
  219. img.src = qrcodeContent;
  220. //Render warning labels
  221. for (var i =0; i < warningLabels.length; i++){
  222. let base_image = new Image();
  223. let thisOffsetCounter = i;
  224. base_image.src = './labels/' + warningLabels[thisOffsetCounter];
  225. base_image.onload = function(){
  226. ctx.drawImage(base_image, 10 + thisOffsetCounter * 85, canvas.height - 120, 80, 80);
  227. }
  228. }
  229. }
  230. function generateQRCode(qrcontent, size=500){
  231. var qr = new QRious();
  232. qr.set({
  233. padding: 25,
  234. size: size,
  235. value: qrcontent
  236. });
  237. return qr.toDataURL();
  238. }
  239. setTimeout(function(){
  240. defaultInit();
  241. }, 1000);
  242. function defaultInit(){
  243. clearCanvas();
  244. $("#labelcanvas").css("height", parseInt(70 / 10 * dpcm))
  245. canvas.height = $("#labelcanvas").height();
  246. $("#labelcanvas").css("width", parseInt(50 / 10 * dpcm))
  247. canvas.width = $("#labelcanvas").width();
  248. renderCanvas();
  249. }
  250. function renderCanvas(){
  251. renderBasicElements();
  252. }
  253. function clearCanvas(){
  254. ctx.clearRect(0, 0, canvas.width, canvas.height);
  255. }
  256. //Functions related to updating
  257. function updateCanvasWidth(value){
  258. clearCanvas();
  259. $("#labelcanvas").css("width", parseInt(value / 10 * dpcm))
  260. canvas.width = $("#labelcanvas").width();
  261. renderCanvas();
  262. }
  263. function updateCanvasHeight(value){
  264. clearCanvas();
  265. $("#labelcanvas").css("height", parseInt(value / 10 * dpcm))
  266. canvas.height = $("#labelcanvas").height();
  267. renderCanvas();
  268. }
  269. function updateTechSpec(value){
  270. clearCanvas();
  271. techSpec = value.split(",");
  272. renderCanvas();
  273. }
  274. function updateProjcetCodename(value){
  275. clearCanvas();
  276. projectCodename = value;
  277. renderCanvas();
  278. }
  279. function updateTitle(value){
  280. clearCanvas();
  281. itemTitle = value;
  282. renderCanvas();
  283. }
  284. function updateSubtitle(value){
  285. clearCanvas();
  286. itemSubtitle = value;
  287. renderCanvas();
  288. }
  289. $("input").each(function(){
  290. if ($(this).attr("type") == "checkbox"){
  291. $(this).on("change", function(data){
  292. if ($(this)[0].checked == true){
  293. warningLabels.push($(this).attr("name"));
  294. }else{
  295. const index = warningLabels.indexOf($(this).attr("name"));
  296. if (index > -1) {
  297. warningLabels.splice(index, 1);
  298. }
  299. }
  300. clearCanvas();
  301. renderCanvas();
  302. })
  303. }
  304. });
  305. </script>
  306. </body>
  307. </html>