From fa5d2906c0075e7e0a937c0019c02492494565e8 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Wed, 9 Dec 2020 15:21:02 +0800 Subject: [PATCH] Change sample artwork --- docs/0.bootstrap.js | 2 +- docs/assets/samples/attributions.txt | 22 ---------------------- docs/assets/samples/spaceships.png | Bin 5754 -> 0 bytes docs/assets/samples/tank-unit-preview.png | Bin 0 -> 9888 bytes 4 files changed, 1 insertion(+), 23 deletions(-) delete mode 100644 docs/assets/samples/attributions.txt delete mode 100644 docs/assets/samples/spaceships.png create mode 100644 docs/assets/samples/tank-unit-preview.png diff --git a/docs/0.bootstrap.js b/docs/0.bootstrap.js index cc91e5e..7496600 100644 --- a/docs/0.bootstrap.js +++ b/docs/0.bootstrap.js @@ -43,7 +43,7 @@ eval("\"use strict\";\n// Instantiate WebAssembly module\nvar wasmExports = __we /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vtracer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vtracer */ \"../pkg/vtracer_webapp.js\");\n\n\nlet runner;\nconst canvas = document.getElementById('frame');\nconst ctx = canvas.getContext('2d');\nconst svg = document.getElementById('svg');\nconst img = new Image();\nconst progress = document.getElementById('progressbar');\nconst progressregion = document.getElementById('progressregion');\nlet mode = 'spline', clustering_mode = 'color';\n\n// Hide canas and svg on load\ncanvas.style.display = 'none';\nsvg.style.display = 'none';\n\n// Paste from clipboard\ndocument.addEventListener('paste', function (e) {\n\tif (e.clipboardData) {\n\t\tvar items = e.clipboardData.items;\n\t\tif (!items) return;\n\n\t\t//access data directly\n\t\tfor (var i = 0; i < items.length; i++) {\n\t\t\tif (items[i].type.indexOf(\"image\") !== -1) {\n\t\t\t\t//image\n\t\t\t\tvar blob = items[i].getAsFile();\n\t\t\t\tvar URLObj = window.URL || window.webkitURL;\n\t\t\t\tvar source = URLObj.createObjectURL(blob);\n\t\t\t\tsetSourceAndRestart(source);\n\t\t\t}\n\t\t}\n\t\te.preventDefault();\n\t}\n});\n\n// Download as SVG\ndocument.getElementById('export').addEventListener('click', function (e) {\n const blob = new Blob([new XMLSerializer().serializeToString(svg)], {type: 'octet/stream'}),\n url = window.URL.createObjectURL(blob);\n\n this.href = url;\n this.target = '_blank';\n\n this.download = 'export-' + new Date().toISOString().slice(0, 19).replace(/:/g, '').replace('T', ' ') + '.svg';\n});\n\n// Store template config\nvar presetConfigs = [\n {\n src: 'assets/samples/K1_drawing.jpg',\n clustering_mode: 'binary',\n filter_speckle: 4,\n color_precision: 6,\n layer_difference: 16,\n mode: 'spline',\n corner_threshold: 60,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://commons.wikimedia.org/wiki/File:K1_drawing.jpg',\n credit: 'Wikimedia',\n },\n {\n src: 'assets/samples/Cityscape Sunset_DFM3-01.jpg',\n clustering_mode: 'color',\n filter_speckle: 4,\n color_precision: 8,\n layer_difference: 25,\n mode: 'spline',\n corner_threshold: 60,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://www.vecteezy.com/vector-art/227400-beautiful-cityscape-at-sunset',\n credit: 'Building Vectors by Vecteezy',\n },\n {\n src: 'assets/samples/Gum Tree Vector.jpg',\n clustering_mode: 'color',\n filter_speckle: 4,\n color_precision: 8,\n layer_difference: 28,\n mode: 'spline',\n corner_threshold: 60,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://www.vecteezy.com/vector-art/172177-gum-tree-vector',\n credit: 'Nature Vectors by Vecteezy',\n },\n {\n src: 'assets/samples/vectorstock_31191940.png',\n clustering_mode: 'color',\n filter_speckle: 8,\n color_precision: 7,\n layer_difference: 64,\n mode: 'spline',\n corner_threshold: 60,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://www.vectorstock.com/royalty-free-vector/dessert-poster-design-with-chocolate-cake-mousses-vector-31191940',\n credit: 'Vector image by VectorStock / vectorstock',\n },\n {\n src: 'assets/samples/angel-luciano-LATYeZyw88c-unsplash-s.jpg',\n clustering_mode: 'color',\n filter_speckle: 10,\n color_precision: 8,\n layer_difference: 48,\n mode: 'spline',\n corner_threshold: 180,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://unsplash.com/photos/LATYeZyw88c',\n credit: 'Photo by Angel Luciano on Unsplash',\n },\n {\n src: 'assets/samples/spaceships.png',\n clustering_mode: 'color',\n filter_speckle: 0,\n color_precision: 8,\n layer_difference: 0,\n mode: 'none',\n corner_threshold: 180,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://opengameart.org/content/spaceships-1',\n credit: 'Photo by wuhu on opengameart.org',\n },\n];\n\n// Insert gallery items dynamically\nfor (let i = 0; i < presetConfigs.length; i++) {\n\tdocument.getElementById('galleryslider').innerHTML += \n\t`
  • \n\t
    \n\t\t\n\t\t\t\n\t\t\n\t
    \n\t
  • `;\n document.getElementById('credits-modal-content').innerHTML += \n `

    ${presetConfigs[i].credit}

    `;\n}\n\n// Function to load a given config WITHOUT restarting\nfunction loadConfig(config) {\n\tmode = config.mode;\n\tclustering_mode = config.clustering_mode;\n\n\tglobalcorner = config.corner_threshold;\n\tdocument.getElementById('cornervalue').innerHTML = globalcorner;\n\tdocument.getElementById('corner').value = globalcorner;\n\t\n\tgloballength = config.length_threshold;\n\tdocument.getElementById('lengthvalue').innerHTML = globallength;\n\tdocument.getElementById('length').value = globallength;\n\t\n\tglobalsplice = config.splice_threshold;\n\tdocument.getElementById('splicevalue').innerHTML = globalsplice;\n\tdocument.getElementById('splice').value = globalsplice;\n\n\tglobalfilterspeckle = config.filter_speckle;\n\tdocument.getElementById('filterspecklevalue').innerHTML = globalfilterspeckle;\n\tdocument.getElementById('filterspeckle').value = globalfilterspeckle;\n\n\tglobalcolorprecision = config.color_precision;\n\tdocument.getElementById('colorprecisionvalue').innerHTML = globalcolorprecision;\n\tdocument.getElementById('colorprecision').value = globalcolorprecision;\n\n\tgloballayerdifference = config.layer_difference;\n\tdocument.getElementById('layerdifferencevalue').innerHTML = globallayerdifference;\n\tdocument.getElementById('layerdifference').value = globallayerdifference;\n\n}\n\n// Choose template from gallery\nlet chooseGalleryButtons = document.querySelectorAll('.galleryitem a');\nchooseGalleryButtons.forEach(item => {\n\titem.addEventListener('click', function (e) {\n\t\t// Load preset template config\n\t\tlet i = Array.prototype.indexOf.call(chooseGalleryButtons, item);\n\t\tif (presetConfigs.length > i) {\n\t\t\tloadConfig(presetConfigs[i]);\n\t\t}\n\n\t\t// Set source as specified\n\t\tsetSourceAndRestart(this.firstElementChild.src);\n\t});\n});\n\n// Upload button\nvar imageSelect = document.getElementById('imageSelect'),\nimageInput = document.getElementById('imageInput'); \nimageSelect.addEventListener('click', function (e) {\n imageInput.click();\n e.preventDefault();\n});\n\nimageInput.addEventListener('change', function (e) {\n setSourceAndRestart(this.files[0]);\n});\n\n// Drag-n-Drop\nvar drop = document.getElementById('drop');\nvar droptext = document.getElementById('droptext');\ndrop.addEventListener('dragenter', function (e) {\n if (e.preventDefault) e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n droptext.classList.add('hovering');\n return false;\n});\n\ndrop.addEventListener('dragleave', function (e) {\n if (e.preventDefault) e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n droptext.classList.remove('hovering');\n return false;\n});\n\ndrop.addEventListener('dragover', function (e) {\n if (e.preventDefault) e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n droptext.classList.add('hovering');\n return false;\n});\n\ndrop.addEventListener('drop', function (e) {\n if (e.preventDefault) e.preventDefault();\n droptext.classList.remove('hovering');\n setSourceAndRestart(e.dataTransfer.files[0]);\n return false;\n});\n\n// Get Input from UI controls\nvar globalcorner = parseInt(document.getElementById('corner').value),\n globallength = parseFloat(document.getElementById('length').value),\n globalsplice = parseInt(document.getElementById('splice').value),\n globalfilterspeckle = parseInt(document.getElementById('filterspeckle').value),\n globalcolorprecision = parseInt(document.getElementById('colorprecision').value),\n globallayerdifference = parseInt(document.getElementById('layerdifference').value);\n\n// Load past inputs from localStorage\n/*\nif (localStorage.VSsettings) {\n var settings = JSON.parse(localStorage.VSsettings);\n document.getElementById('cornervalue').innerHTML = document.getElementById('corner').value = globalcorner = settings.globalcorner;\n document.getElementById('lengthvalue').innerHTML = document.getElementById('length').value = globallength = settings.globallength;\n document.getElementById('splicevalue').innerHTML = document.getElementById('splice').value = globalsplice = settings.globalsplice;\n}\n*/\n\ndocument.getElementById('none').addEventListener('click', function (e) {\n mode = 'none';\n restart();\n}, false);\n\ndocument.getElementById('polygon').addEventListener('click', function (e) {\n mode = 'polygon';\n restart();\n}, false);\n\ndocument.getElementById('spline').addEventListener('click', function (e) {\n mode = 'spline';\n restart();\n}, false);\n\ndocument.getElementById('clustering-binary').addEventListener('click', function (e) {\n clustering_mode = 'binary';\n restart();\n}, false);\n\ndocument.getElementById('clustering-color').addEventListener('click', function (e) {\n clustering_mode = 'color';\n restart();\n}, false);\n\ndocument.getElementById('filterspeckle').addEventListener('change', function (e) {\n globalfilterspeckle = parseInt(this.value);\n document.getElementById('filterspecklevalue').innerHTML = this.value;\n restart();\n});\n\ndocument.getElementById('colorprecision').addEventListener('change', function (e) {\n globalcolorprecision = parseInt(this.value);\n document.getElementById('colorprecisionvalue').innerHTML = this.value;\n restart();\n});\n\ndocument.getElementById('layerdifference').addEventListener('change', function (e) {\n globallayerdifference = parseInt(this.value);\n document.getElementById('layerdifferencevalue').innerHTML = this.value;\n restart();\n});\n\ndocument.getElementById('corner').addEventListener('change', function (e) {\n globalcorner = parseInt(this.value);\n document.getElementById('cornervalue').innerHTML = this.value;\n restart();\n});\n\ndocument.getElementById('length').addEventListener('change', function (e) {\n globallength = parseFloat(this.value);\n document.getElementById('lengthvalue').innerHTML = this.value;\n restart();\n});\n\ndocument.getElementById('splice').addEventListener('change', function (e) {\n globalsplice = parseInt(this.value);\n document.getElementById('splicevalue').innerHTML = this.value;\n restart();\n});\n\n// Save inputs before unloading\n/*\nwindow.addEventListener('beforeunload', function () {\n localStorage.VSsettings = JSON.stringify({\n globalcorner: globalcorner,\n globallength: globallength,\n globalsplice: globalsplice,\n });\n});\n*/\n\nfunction setSourceAndRestart(source) {\n img.src = source instanceof File ? URL.createObjectURL(source) : source;\n img.onload = function () {\n svg.setAttribute('viewBox', `0 0 ${img.naturalWidth} ${img.naturalHeight}`);\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n restart();\n }\n // Show display\n canvas.style.display = 'block';\n svg.style.display = 'block';\n // Hide upload text\n droptext.style.display = 'none';\n}\n\nfunction restart() {\n document.getElementById('clustering-binary').classList.remove('selected');\n document.getElementById('clustering-color').classList.remove('selected');\n document.getElementById('clustering-' + clustering_mode).classList.add('selected');\n Array.from(document.getElementsByClassName('clustering-color-options')).forEach((el) => {\n el.style.display = clustering_mode == 'color' ? '' : 'none';\n });\n\n document.getElementById('none').classList.remove('selected');\n document.getElementById('polygon').classList.remove('selected');\n document.getElementById('spline').classList.remove('selected');\n document.getElementById(mode).classList.add('selected');\n Array.from(document.getElementsByClassName('spline-options')).forEach((el) => {\n el.style.display = mode == 'spline' ? '' : 'none';\n });\n\n if (!img.src) {\n return;\n }\n while (svg.firstChild) {\n svg.removeChild(svg.firstChild);\n }\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.drawImage(img, 0, 0);\n let converter_params = JSON.stringify({\n 'canvas_id': canvas.id,\n 'svg_id': svg.id,\n 'mode': mode,\n 'clustering_mode': clustering_mode,\n 'corner_threshold': deg2rad(globalcorner),\n 'length_threshold': globallength,\n 'max_iterations': 10,\n 'splice_threshold': deg2rad(globalsplice),\n 'filter_speckle': globalfilterspeckle*globalfilterspeckle,\n 'color_precision': 8-globalcolorprecision,\n 'layer_difference': globallayerdifference,\n });\n if (runner) {\n runner.stop();\n }\n runner = new ConverterRunner(converter_params);\n progress.value = 0;\n progressregion.style.display = 'block';\n runner.run();\n}\n\nfunction deg2rad(deg) {\n return deg/180*3.141592654;\n}\n\nclass ConverterRunner {\n constructor (converter_params) {\n this.converter =\n clustering_mode == 'color' ?\n vtracer__WEBPACK_IMPORTED_MODULE_0__[\"ColorImageConverter\"].new_with_string(converter_params):\n vtracer__WEBPACK_IMPORTED_MODULE_0__[\"BinaryImageConverter\"].new_with_string(converter_params);\n this.converter.init();\n this.stopped = false;\n if (clustering_mode == 'binary') {\n svg.style.background = '#000';\n canvas.style.display = 'none';\n } else {\n svg.style.background = '';\n canvas.style.display = '';\n }\n canvas.style.opacity = '';\n }\n\n run () {\n const This = this;\n setTimeout(function tick () {\n if (!This.stopped) {\n let done = false;\n const startTick = performance.now();\n while (!(done = This.converter.tick()) &&\n performance.now() - startTick < 25) {\n }\n progress.value = This.converter.progress();\n if (progress.value >= 50) {\n canvas.style.display = 'none';\n } else {\n canvas.style.opacity = (50 - progress.value) / 25;\n }\n if (progress.value >= progress.max) {\n progressregion.style.display = 'none';\n progress.value = 0;\n }\n if (!done) {\n setTimeout(tick, 1);\n }\n }\n }, 1);\n }\n\n stop () {\n this.stopped = true;\n this.converter.free();\n }\n}\n\n//# sourceURL=webpack:///./index.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vtracer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vtracer */ \"../pkg/vtracer_webapp.js\");\n\n\nlet runner;\nconst canvas = document.getElementById('frame');\nconst ctx = canvas.getContext('2d');\nconst svg = document.getElementById('svg');\nconst img = new Image();\nconst progress = document.getElementById('progressbar');\nconst progressregion = document.getElementById('progressregion');\nlet mode = 'spline', clustering_mode = 'color';\n\n// Hide canas and svg on load\ncanvas.style.display = 'none';\nsvg.style.display = 'none';\n\n// Paste from clipboard\ndocument.addEventListener('paste', function (e) {\n\tif (e.clipboardData) {\n\t\tvar items = e.clipboardData.items;\n\t\tif (!items) return;\n\n\t\t//access data directly\n\t\tfor (var i = 0; i < items.length; i++) {\n\t\t\tif (items[i].type.indexOf(\"image\") !== -1) {\n\t\t\t\t//image\n\t\t\t\tvar blob = items[i].getAsFile();\n\t\t\t\tvar URLObj = window.URL || window.webkitURL;\n\t\t\t\tvar source = URLObj.createObjectURL(blob);\n\t\t\t\tsetSourceAndRestart(source);\n\t\t\t}\n\t\t}\n\t\te.preventDefault();\n\t}\n});\n\n// Download as SVG\ndocument.getElementById('export').addEventListener('click', function (e) {\n const blob = new Blob([new XMLSerializer().serializeToString(svg)], {type: 'octet/stream'}),\n url = window.URL.createObjectURL(blob);\n\n this.href = url;\n this.target = '_blank';\n\n this.download = 'export-' + new Date().toISOString().slice(0, 19).replace(/:/g, '').replace('T', ' ') + '.svg';\n});\n\n// Store template config\nvar presetConfigs = [\n {\n src: 'assets/samples/K1_drawing.jpg',\n clustering_mode: 'binary',\n filter_speckle: 4,\n color_precision: 6,\n layer_difference: 16,\n mode: 'spline',\n corner_threshold: 60,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://commons.wikimedia.org/wiki/File:K1_drawing.jpg',\n credit: 'Wikimedia',\n },\n {\n src: 'assets/samples/Cityscape Sunset_DFM3-01.jpg',\n clustering_mode: 'color',\n filter_speckle: 4,\n color_precision: 8,\n layer_difference: 25,\n mode: 'spline',\n corner_threshold: 60,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://www.vecteezy.com/vector-art/227400-beautiful-cityscape-at-sunset',\n credit: 'Building Vectors by Vecteezy',\n },\n {\n src: 'assets/samples/Gum Tree Vector.jpg',\n clustering_mode: 'color',\n filter_speckle: 4,\n color_precision: 8,\n layer_difference: 28,\n mode: 'spline',\n corner_threshold: 60,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://www.vecteezy.com/vector-art/172177-gum-tree-vector',\n credit: 'Nature Vectors by Vecteezy',\n },\n {\n src: 'assets/samples/vectorstock_31191940.png',\n clustering_mode: 'color',\n filter_speckle: 8,\n color_precision: 7,\n layer_difference: 64,\n mode: 'spline',\n corner_threshold: 60,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://www.vectorstock.com/royalty-free-vector/dessert-poster-design-with-chocolate-cake-mousses-vector-31191940',\n credit: 'Vector image by VectorStock / vectorstock',\n },\n {\n src: 'assets/samples/angel-luciano-LATYeZyw88c-unsplash-s.jpg',\n clustering_mode: 'color',\n filter_speckle: 10,\n color_precision: 8,\n layer_difference: 48,\n mode: 'spline',\n corner_threshold: 180,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://unsplash.com/photos/LATYeZyw88c',\n credit: 'Photo by Angel Luciano on Unsplash',\n },\n {\n src: 'assets/samples/tank-unit-preview.png',\n clustering_mode: 'color',\n filter_speckle: 0,\n color_precision: 8,\n layer_difference: 0,\n mode: 'none',\n corner_threshold: 180,\n length_threshold: 4,\n splice_threshold: 45,\n source: 'https://opengameart.org/content/sideview-sci-fi-patreon-collection',\n credit: 'Artwork by Luis Zuno on opengameart.org',\n },\n];\n\n// Insert gallery items dynamically\nfor (let i = 0; i < presetConfigs.length; i++) {\n\tdocument.getElementById('galleryslider').innerHTML += \n\t`
  • \n\t
    \n\t\t\n\t\t\t\n\t\t\n\t
    \n\t
  • `;\n document.getElementById('credits-modal-content').innerHTML += \n `

    ${presetConfigs[i].credit}

    `;\n}\n\n// Function to load a given config WITHOUT restarting\nfunction loadConfig(config) {\n\tmode = config.mode;\n\tclustering_mode = config.clustering_mode;\n\n\tglobalcorner = config.corner_threshold;\n\tdocument.getElementById('cornervalue').innerHTML = globalcorner;\n\tdocument.getElementById('corner').value = globalcorner;\n\t\n\tgloballength = config.length_threshold;\n\tdocument.getElementById('lengthvalue').innerHTML = globallength;\n\tdocument.getElementById('length').value = globallength;\n\t\n\tglobalsplice = config.splice_threshold;\n\tdocument.getElementById('splicevalue').innerHTML = globalsplice;\n\tdocument.getElementById('splice').value = globalsplice;\n\n\tglobalfilterspeckle = config.filter_speckle;\n\tdocument.getElementById('filterspecklevalue').innerHTML = globalfilterspeckle;\n\tdocument.getElementById('filterspeckle').value = globalfilterspeckle;\n\n\tglobalcolorprecision = config.color_precision;\n\tdocument.getElementById('colorprecisionvalue').innerHTML = globalcolorprecision;\n\tdocument.getElementById('colorprecision').value = globalcolorprecision;\n\n\tgloballayerdifference = config.layer_difference;\n\tdocument.getElementById('layerdifferencevalue').innerHTML = globallayerdifference;\n\tdocument.getElementById('layerdifference').value = globallayerdifference;\n\n}\n\n// Choose template from gallery\nlet chooseGalleryButtons = document.querySelectorAll('.galleryitem a');\nchooseGalleryButtons.forEach(item => {\n\titem.addEventListener('click', function (e) {\n\t\t// Load preset template config\n\t\tlet i = Array.prototype.indexOf.call(chooseGalleryButtons, item);\n\t\tif (presetConfigs.length > i) {\n\t\t\tloadConfig(presetConfigs[i]);\n\t\t}\n\n\t\t// Set source as specified\n\t\tsetSourceAndRestart(this.firstElementChild.src);\n\t});\n});\n\n// Upload button\nvar imageSelect = document.getElementById('imageSelect'),\nimageInput = document.getElementById('imageInput'); \nimageSelect.addEventListener('click', function (e) {\n imageInput.click();\n e.preventDefault();\n});\n\nimageInput.addEventListener('change', function (e) {\n setSourceAndRestart(this.files[0]);\n});\n\n// Drag-n-Drop\nvar drop = document.getElementById('drop');\nvar droptext = document.getElementById('droptext');\ndrop.addEventListener('dragenter', function (e) {\n if (e.preventDefault) e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n droptext.classList.add('hovering');\n return false;\n});\n\ndrop.addEventListener('dragleave', function (e) {\n if (e.preventDefault) e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n droptext.classList.remove('hovering');\n return false;\n});\n\ndrop.addEventListener('dragover', function (e) {\n if (e.preventDefault) e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n droptext.classList.add('hovering');\n return false;\n});\n\ndrop.addEventListener('drop', function (e) {\n if (e.preventDefault) e.preventDefault();\n droptext.classList.remove('hovering');\n setSourceAndRestart(e.dataTransfer.files[0]);\n return false;\n});\n\n// Get Input from UI controls\nvar globalcorner = parseInt(document.getElementById('corner').value),\n globallength = parseFloat(document.getElementById('length').value),\n globalsplice = parseInt(document.getElementById('splice').value),\n globalfilterspeckle = parseInt(document.getElementById('filterspeckle').value),\n globalcolorprecision = parseInt(document.getElementById('colorprecision').value),\n globallayerdifference = parseInt(document.getElementById('layerdifference').value);\n\n// Load past inputs from localStorage\n/*\nif (localStorage.VSsettings) {\n var settings = JSON.parse(localStorage.VSsettings);\n document.getElementById('cornervalue').innerHTML = document.getElementById('corner').value = globalcorner = settings.globalcorner;\n document.getElementById('lengthvalue').innerHTML = document.getElementById('length').value = globallength = settings.globallength;\n document.getElementById('splicevalue').innerHTML = document.getElementById('splice').value = globalsplice = settings.globalsplice;\n}\n*/\n\ndocument.getElementById('none').addEventListener('click', function (e) {\n mode = 'none';\n restart();\n}, false);\n\ndocument.getElementById('polygon').addEventListener('click', function (e) {\n mode = 'polygon';\n restart();\n}, false);\n\ndocument.getElementById('spline').addEventListener('click', function (e) {\n mode = 'spline';\n restart();\n}, false);\n\ndocument.getElementById('clustering-binary').addEventListener('click', function (e) {\n clustering_mode = 'binary';\n restart();\n}, false);\n\ndocument.getElementById('clustering-color').addEventListener('click', function (e) {\n clustering_mode = 'color';\n restart();\n}, false);\n\ndocument.getElementById('filterspeckle').addEventListener('change', function (e) {\n globalfilterspeckle = parseInt(this.value);\n document.getElementById('filterspecklevalue').innerHTML = this.value;\n restart();\n});\n\ndocument.getElementById('colorprecision').addEventListener('change', function (e) {\n globalcolorprecision = parseInt(this.value);\n document.getElementById('colorprecisionvalue').innerHTML = this.value;\n restart();\n});\n\ndocument.getElementById('layerdifference').addEventListener('change', function (e) {\n globallayerdifference = parseInt(this.value);\n document.getElementById('layerdifferencevalue').innerHTML = this.value;\n restart();\n});\n\ndocument.getElementById('corner').addEventListener('change', function (e) {\n globalcorner = parseInt(this.value);\n document.getElementById('cornervalue').innerHTML = this.value;\n restart();\n});\n\ndocument.getElementById('length').addEventListener('change', function (e) {\n globallength = parseFloat(this.value);\n document.getElementById('lengthvalue').innerHTML = this.value;\n restart();\n});\n\ndocument.getElementById('splice').addEventListener('change', function (e) {\n globalsplice = parseInt(this.value);\n document.getElementById('splicevalue').innerHTML = this.value;\n restart();\n});\n\n// Save inputs before unloading\n/*\nwindow.addEventListener('beforeunload', function () {\n localStorage.VSsettings = JSON.stringify({\n globalcorner: globalcorner,\n globallength: globallength,\n globalsplice: globalsplice,\n });\n});\n*/\n\nfunction setSourceAndRestart(source) {\n img.src = source instanceof File ? URL.createObjectURL(source) : source;\n img.onload = function () {\n svg.setAttribute('viewBox', `0 0 ${img.naturalWidth} ${img.naturalHeight}`);\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n restart();\n }\n // Show display\n canvas.style.display = 'block';\n svg.style.display = 'block';\n // Hide upload text\n droptext.style.display = 'none';\n}\n\nfunction restart() {\n document.getElementById('clustering-binary').classList.remove('selected');\n document.getElementById('clustering-color').classList.remove('selected');\n document.getElementById('clustering-' + clustering_mode).classList.add('selected');\n Array.from(document.getElementsByClassName('clustering-color-options')).forEach((el) => {\n el.style.display = clustering_mode == 'color' ? '' : 'none';\n });\n\n document.getElementById('none').classList.remove('selected');\n document.getElementById('polygon').classList.remove('selected');\n document.getElementById('spline').classList.remove('selected');\n document.getElementById(mode).classList.add('selected');\n Array.from(document.getElementsByClassName('spline-options')).forEach((el) => {\n el.style.display = mode == 'spline' ? '' : 'none';\n });\n\n if (!img.src) {\n return;\n }\n while (svg.firstChild) {\n svg.removeChild(svg.firstChild);\n }\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.drawImage(img, 0, 0);\n let converter_params = JSON.stringify({\n 'canvas_id': canvas.id,\n 'svg_id': svg.id,\n 'mode': mode,\n 'clustering_mode': clustering_mode,\n 'corner_threshold': deg2rad(globalcorner),\n 'length_threshold': globallength,\n 'max_iterations': 10,\n 'splice_threshold': deg2rad(globalsplice),\n 'filter_speckle': globalfilterspeckle*globalfilterspeckle,\n 'color_precision': 8-globalcolorprecision,\n 'layer_difference': globallayerdifference,\n });\n if (runner) {\n runner.stop();\n }\n runner = new ConverterRunner(converter_params);\n progress.value = 0;\n progressregion.style.display = 'block';\n runner.run();\n}\n\nfunction deg2rad(deg) {\n return deg/180*3.141592654;\n}\n\nclass ConverterRunner {\n constructor (converter_params) {\n this.converter =\n clustering_mode == 'color' ?\n vtracer__WEBPACK_IMPORTED_MODULE_0__[\"ColorImageConverter\"].new_with_string(converter_params):\n vtracer__WEBPACK_IMPORTED_MODULE_0__[\"BinaryImageConverter\"].new_with_string(converter_params);\n this.converter.init();\n this.stopped = false;\n if (clustering_mode == 'binary') {\n svg.style.background = '#000';\n canvas.style.display = 'none';\n } else {\n svg.style.background = '';\n canvas.style.display = '';\n }\n canvas.style.opacity = '';\n }\n\n run () {\n const This = this;\n setTimeout(function tick () {\n if (!This.stopped) {\n let done = false;\n const startTick = performance.now();\n while (!(done = This.converter.tick()) &&\n performance.now() - startTick < 25) {\n }\n progress.value = This.converter.progress();\n if (progress.value >= 50) {\n canvas.style.display = 'none';\n } else {\n canvas.style.opacity = (50 - progress.value) / 25;\n }\n if (progress.value >= progress.max) {\n progressregion.style.display = 'none';\n progress.value = 0;\n }\n if (!done) {\n setTimeout(tick, 1);\n }\n }\n }, 1);\n }\n\n stop () {\n this.stopped = true;\n this.converter.free();\n }\n}\n\n//# sourceURL=webpack:///./index.js?"); /***/ }), diff --git a/docs/assets/samples/attributions.txt b/docs/assets/samples/attributions.txt deleted file mode 100644 index 0a84553..0000000 --- a/docs/assets/samples/attributions.txt +++ /dev/null @@ -1,22 +0,0 @@ -K1_drawing -B/W 4 -https://commons.wikimedia.org/wiki/File:K1_drawing.jpg - -Cityscape Sunset_DFM3-01 -Color 4,8,32 -Building Vectors by Vecteezy - -Gum Tree Vector -Color 4,8,32 -Nature Vectors by Vecteezy - -vectorstock_31191940 -Color 8,7,64 -Vector image by VectorStock / vectorstock - -angel-luciano-LATYeZyw88c-unsplash -Color 10,8,48 180 -Photo by Angel Luciano on Unsplash - -spaceships.png -https://opengameart.org/content/spaceships-1 \ No newline at end of file diff --git a/docs/assets/samples/spaceships.png b/docs/assets/samples/spaceships.png deleted file mode 100644 index d98f085ea8a6d20acd03f37098763926725447fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5754 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 J#eewt{{y~s0lWYJ diff --git a/docs/assets/samples/tank-unit-preview.png b/docs/assets/samples/tank-unit-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..fc9dca7bc7401be03bc95b0fbf9b6ffc69333df1 GIT binary patch literal 9888 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 PXG~F674liyB>4XU8ykZ` literal 0 HcmV?d00001