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 df786c18a9fc9812a23e9d4ec71d846be6e515e0
parent 0458f65e88a7d42f30ea5a7c933df5d6e3aeb85b
Author: George Francis <georgedoescode@gmail.com>
Date:   Sun,  5 Jul 2020 09:17:32 +0100

add the actual squirle (finally)

Diffstat:
Msrc/App.vue | 14++++++++++++++
Msrc/components/GeneratorExportOptions.vue | 4+++-
Msrc/components/GeneratorPreview.vue | 11+++++++++--
Msrc/components/TheGenerator.vue | 60++++++++++++++++++++++++++++++++++++++++++++++--------------
4 files changed, 72 insertions(+), 17 deletions(-)

diff --git a/src/App.vue b/src/App.vue @@ -39,4 +39,18 @@ export default { grid-column: -1 / 1; grid-row: 2; } + +.app__content { + display: grid; + grid-template-columns: + minmax(0, 1fr) + minmax(0, var(--spacing-15)) + minmax(0, 1fr); + grid-auto-rows: max-content; +} + +.generator { + grid-row: 1; + grid-column: 2; +} </style> diff --git a/src/components/GeneratorExportOptions.vue b/src/components/GeneratorExportOptions.vue @@ -38,11 +38,13 @@ export default { height: var(--spacing-6); margin-left: var(--spacing-4); padding: 0; + border: 0; border-radius: 50%; outline: none; cursor: pointer; background: #fff; - border: 1px solid var(--grey-100); + + /* box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.075); */ transition: stroke 125ms ease-in-out, transform 125ms ease-in-out; } diff --git a/src/components/GeneratorPreview.vue b/src/components/GeneratorPreview.vue @@ -1,13 +1,19 @@ <script> export default { name: 'GeneratorPreview', + props: { + points: { + type: Array, + required: true, + }, + }, }; </script> <template> <div class="generator-preview"> - <svg viewBox="0 0 320 320" preserveAspectRatio> - <rect x="80" y="80" width="160" height="160" fill="#f5f7fa"></rect> + <svg viewBox="0 0 200 200" preserveAspectRatio> + <polygon :points="points" transform="translate(100 100)" /> </svg> </div> </template> @@ -41,5 +47,6 @@ export default { left: 0; width: 100%; height: 100%; + fill: var(--grey-900); } </style> diff --git a/src/components/TheGenerator.vue b/src/components/TheGenerator.vue @@ -10,35 +10,67 @@ export default { GeneratorControls, GeneratorExportOptions, }, + data() { + return { + squircleOpts: { + n: 4, + a: 50, + b: 50, + }, + points: [], + }; + }, + mounted() { + this.setPoints(); + }, + methods: { + setPoints() { + this.points = []; + for (let angle = 0; angle < Math.PI * 2; angle += 0.05) { + const na = 2 / this.squircleOpts.n; + const x = + Math.pow(Math.abs(Math.cos(angle)), na) * + this.squircleOpts.a * + this.sgn(Math.cos(angle)); + const y = + Math.pow(Math.abs(Math.sin(angle)), na) * + this.squircleOpts.b * + this.sgn(Math.sin(angle)); + + this.points.push([x, y]); + } + }, + sgn(value) { + if (value > 0) { + return 1; + } else if (value < 0) { + return -1; + } else { + return 0; + } + }, + }, }; </script> <template> - <div class="generator-wrapper"> - <div class="generator"> - <GeneratorPreview /> - <GeneratorControls /> - <GeneratorExportOptions class="generator__export-opts" /> - </div> + <div class="generator"> + <GeneratorPreview :points="points" /> + <GeneratorControls /> + <GeneratorExportOptions class="generator__export-opts" /> </div> </template> <style scoped> -.generator-wrapper { - width: var(--spacing-15); - margin: 0 auto; -} - .generator { position: relative; display: grid; grid-template-columns: 320px 1fr; grid-gap: var(--spacing-4); - margin: 0 auto; padding: var(--spacing-4); background: #fff; - border: 1px solid var(--grey-100); - border-radius: 24px; + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.075); + border-radius: 32px; } .generator__export-opts {