squircle

Make all the squircles you need, in the browser. https://squircley.app/
git clone http://git.hanabi.in/repos/squircle.git
Log | Files | Refs | LICENSE

commit ecd2e457d6a679d5c352725fed62745a58a89430
parent 0f37fbac90768944027ce1d5962e6ab34ca057b6
Author: George Francis <georgedoescode@gmail.com>
Date:   Wed,  8 Jul 2020 15:28:18 +0100

hook up download and copy to clipboard buttons

Diffstat:
Mpackage-lock.json | 18++++++++++++++++++
Mpackage.json | 2++
Dsrc/components/BaseThreeBtnToggle.vue | 74--------------------------------------------------------------------------
Asrc/components/BaseTwoBtnToggle.vue | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/GeneratorControls.vue | 18++++++------------
Msrc/components/GeneratorExportOptions.vue | 24++++++++++++++++++++++--
Msrc/components/GeneratorPreview.vue | 8+++++++-
Asrc/components/test.svg | 2++
8 files changed, 130 insertions(+), 89 deletions(-)

diff --git a/package-lock.json b/package-lock.json @@ -2568,6 +2568,14 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, + "copy-to-clipboard": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", + "requires": { + "toggle-selection": "^1.0.6" + } + }, "core-js-compat": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", @@ -4235,6 +4243,11 @@ } } }, + "file-saver": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz", + "integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw==" + }, "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -10393,6 +10406,11 @@ "is-number": "^7.0.0" } }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", diff --git a/package.json b/package.json @@ -44,6 +44,8 @@ "webpack-dev-server": "^3.11.0" }, "dependencies": { + "copy-to-clipboard": "^3.3.1", + "file-saver": "^2.0.2", "lodash": "^4.17.15", "normalize.css": "^8.0.1", "vue": "^2.6.11", diff --git a/src/components/BaseThreeBtnToggle.vue b/src/components/BaseThreeBtnToggle.vue @@ -1,74 +0,0 @@ -<script> -export default { - name: 'BaseThreeBtnToggle', - props: { - toggleState: { - type: Array, - required: true, - }, - }, -}; -</script> - -<template> - <div class="base-three-btn-toggle"> - <div - v-for="option in toggleState" - :key="option.id" - class="base-three-btn-toggle__option" - > - <input - :id="option.id" - type="checkbox" - :name="option.id" - :checked="option.checked ? 'checked' : ''" - @click="$emit('change', $event)" - /> - <label :for="option.id">{{ option.label }}</label> - </div> - </div> -</template> - -<style scoped> -.base-three-btn-toggle { - position: relative; - display: grid; - grid-template-columns: 1fr 1fr 1fr; - grid-auto-columns: 1fr; - align-items: center; - height: var(--spacing-5); - border: 1px solid var(--grey-200); - border-radius: 8px; - overflow: hidden; -} - -.base-three-btn-toggle__option { - width: 100%; - height: 100%; -} - -.base-three-btn-toggle label { - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - cursor: pointer; -} - -.base-three-btn-toggle > div:nth-of-type(2) { - border-left: 1px solid var(--grey-200); - border-right: 1px solid var(--grey-200); -} - -.base-three-btn-toggle input { - position: absolute; - width: 0; - height: 0; - opacity: 0; -} - -.base-three-btn-toggle input:checked + label { - background: var(--grey-000); -} -</style> diff --git a/src/components/BaseTwoBtnToggle.vue b/src/components/BaseTwoBtnToggle.vue @@ -0,0 +1,73 @@ +<script> +export default { + name: 'BaseThreeBtnToggle', + props: { + toggleState: { + type: Array, + required: true, + }, + }, +}; +</script> + +<template> + <div class="base-three-btn-toggle"> + <div + v-for="option in toggleState" + :key="option.id" + class="base-three-btn-toggle__option" + > + <input + :id="option.id" + type="radio" + :name="option.id" + :checked="option.checked ? 'checked' : ''" + @click="$emit('change', $event)" + /> + <label :for="option.id">{{ option.label }}</label> + </div> + </div> +</template> + +<style scoped> +.base-three-btn-toggle { + position: relative; + display: grid; + grid-template-columns: 1fr 1fr; + grid-auto-columns: 1fr; + align-items: center; + height: var(--spacing-5); + border: 1px solid var(--grey-200); + border-radius: 8px; + overflow: hidden; +} + +.base-three-btn-toggle__option { + width: 100%; + height: 100%; +} + +.base-three-btn-toggle label { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + cursor: pointer; +} + +.base-three-btn-toggle > div:nth-of-type(1) { + border-right: 1px solid var(--grey-200); +} + +.base-three-btn-toggle input { + position: absolute; + width: 0; + height: 0; + opacity: 0; +} + +.base-three-btn-toggle input:checked + label { + background: var(--grey-000); +} +</style> diff --git a/src/components/GeneratorControls.vue b/src/components/GeneratorControls.vue @@ -18,16 +18,10 @@ export default { fill: this.initialFill, detailToggleState: [ { - id: 'low', - label: 'Low', - checked: false, - value: 0.1, - }, - { - id: 'med', - label: 'Med', + id: 'normal', + label: 'Normal', checked: true, - value: 0.05, + value: 0.1, }, { id: 'high', @@ -123,10 +117,10 @@ export default { /> </div> <label for="quality" class="generator-controls__label"> - Detail + Smoothing </label> - <BaseThreeBtnToggle + <BaseTwoBtnToggle :toggle-state="detailToggleState" class="generator-controls__detail" @change="handleDetailChange" @@ -158,7 +152,7 @@ export default { .generator-controls__label { grid-column: 1; align-self: center; - margin-right: var(--spacing-4); + margin-right: var(--spacing-6); font-size: var(--font-size-4); font-weight: 700; } diff --git a/src/components/GeneratorExportOptions.vue b/src/components/GeneratorExportOptions.vue @@ -2,21 +2,41 @@ import DownloadIcon from '@/assets/img/download-cloud.svg'; import ClipBoardIcon from '@/assets/img/clipboard.svg'; +import { saveAs } from 'file-saver'; +import copy from 'copy-to-clipboard'; + export default { name: 'GeneratorExportOptions', components: { DownloadIcon, ClipBoardIcon, }, + methods: { + downloadSVG() { + const content = document.querySelector('#squircleSVG').outerHTML; + const blob = new Blob([content], { + type: 'text/plain;charset=utf-8', + }); + + saveAs(blob, 'squircle.svg'); + }, + copySVGToClipBoard() { + const content = document.querySelector('#squircleSVG').outerHTML; + copy(content); + }, + }, }; </script> <template> <div class="generator-export-controls"> - <button class="generator-export-controls__btn"> + <button class="generator-export-controls__btn" @click="downloadSVG"> <DownloadIcon /> </button> - <button class="generator-export-controls__btn"> + <button + class="generator-export-controls__btn" + @click="copySVGToClipBoard" + > <ClipBoardIcon /> </button> </div> diff --git a/src/components/GeneratorPreview.vue b/src/components/GeneratorPreview.vue @@ -16,7 +16,13 @@ export default { <template> <div class="generator-preview"> - <svg viewBox="0 0 200 200" preserveAspectRatio :fill="fill"> + <svg + id="squircleSVG" + viewBox="0 0 200 200" + xmlns="http://www.w3.org/2000/svg" + version="1.1" + :fill="fill" + > <polygon :points="points" transform="translate(100 100)" /> </svg> </div> diff --git a/src/components/test.svg b/src/components/test.svg @@ -0,0 +1 @@ +<svg data-v-48b4e325="" id="squircleSVG" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" version="1.1" fill="#1f2933"><polygon data-v-48b4e325="" points="50,0,49.9374347315226,28.105349349619956,49.74894772701058,33.38125893496222,49.43210398961228,36.865217437128976,48.98263025427052,39.4979090335682,48.39405353450391,41.60545688696009,47.65710433322145,43.34244334724622,46.75875757676016,44.7948581252825,45.680673939258156,46.01545300735627,44.396578006028626,47.038749297466545,42.867603943558464,47.88834085605044,41.033384280035264,48.580803716233255,38.7930918099949,49.127937928793024,35.95840962927993,49.538116551701805,32.1041553210079,49.817120724280485,25.785880944891794,49.96865787500007,-20.668737088928854,49.99466918555193,-29.956182700719914,49.89548287220808,-34.5201828207678,49.669839580916744,-37.70230710668928,49.31479412613785,-40.158885692393156,48.825477005081844,-42.146329362745725,48.194673272115715,-43.79321479286572,47.41213665228212,-45.17348020151125,46.4634869251508,-46.333473818393585,45.32840364011719,-47.30397084853738,43.977545800733104,-48.10620692483128,42.36697540663552,-48.75518134341905,40.42718692898893,-49.26158187631472,38.03884883716981,-49.63295515000776,34.968957604030756,-49.87443399426523,30.645531115791925,-49.989185870559965,22.578384016733814,-49.97867105359658,-24.57678863888069,-49.84275691617425,-31.5107966242708,-49.579707672748405,-35.54963902205564,-49.18604787459506,-38.47952561467618,-48.656276375778404,-40.78057444195726,-47.982378713545955,-42.658482197045586,-47.1530395522619,-44.22141608216573,-46.15237291527318,-45.5334130635048,-44.95782175307521,-46.63539323882238,-43.53652056893556,-47.55488164537939,-41.83856702173175,-48.31102943026928,-39.78338276776928,-48.91741955492407,-37.228218758527575,-49.383725427718076,-33.87938299377073,-49.71672826385652,-28.934918946547423,-49.92095027716803,-16.68115501567175,-49.99904069194345,27.193853664432815,-49.951988501586584,32.858437980837316,-49.7791993713926,36.48970610425173,-49.478449588120235,39.20455792860998,-49.04570937003211,41.366737135103584,-48.474804951473345,43.14403738679277,-47.75685630794576,44.62835820546156,-46.87937287335108,45.875518076488795,-45.82478801792596,46.921801484828244,-44.56800700970109,47.79189715486234,-43.072087757046816,48.50310468773851,-41.280059539312454,49.06772910855131,-39.09777961912339,49.49451465320193,-36.352361387879625,49.789530280840445,-32.66515710981263,49.956720050590576,-26.84456764936676" transform="translate(100 100)"></polygon></svg> +\ No newline at end of file