Skip to content

Commit

Permalink
feat: support asymmetric superellipses
Browse files Browse the repository at this point in the history
  • Loading branch information
wopian committed Jul 28, 2020
1 parent 9fa9df3 commit cba6e01
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 22 deletions.
21 changes: 18 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@

![Static demo of Smooth Corners][CTA]

## Demo

[Live demo](https://wopian.github.io/smooth-corners/) featuring several different `--smooth-corners` values

- `5`, iOS App Icon
- `4`, Squircle (default)
- `2.6`, KakaoTalk profile icon
- `0.6`, [Astroid]

## Usage

### CSS
Expand All @@ -26,8 +35,6 @@ Add `mask-image: paint(smooth-corners)` to the elements you want to mask

#### Default (Squircle)

Without a `--smooth-corners` variable set it will default to a value of `4`

```css
.squircle {
mask-image: paint(smooth-corners);
Expand All @@ -38,10 +45,17 @@ Without a `--smooth-corners` variable set it will default to a value of `4`

#### Customise Shape / Roundness

You can customise the mask shape by using a CSS custom property. This can be scoped locally to the selector or defined globally in `:root {}`

`--smooth-corners: nA[, nB]`

- **nA** - Float,


```css
.mask {
/* Integer 0 to 100. Scoped locally or globally in :root {}
< 1 are concave rhombuses / asteroids
< 1 are concave rhombuses
= 1 is a perfect rhombus
> 1 and <2 are convex rhombuses>
= 2 is a perfect circle
Expand Down Expand Up @@ -99,3 +113,4 @@ Like Web Workers, the [Paint Worklet] API requests the module path in the browse
[Paint Worklet]:https://developer.mozilla.org/en-US/docs/Web/API/PaintWorklet
[CTA]:https://raw.githubusercontent.com/wopian/smooth-corners/master/.github/images/cta.png
[Example]:https://raw.githubusercontent.com/wopian/smooth-corners/master/.github/images/example.png
[Astroid]:https://en.wikipedia.org/wiki/Astroid
24 changes: 17 additions & 7 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,16 @@
--smooth-corners: 1.2;
}

.asteroid {
--smooth-corners: 0.5;
.astroid {
--smooth-corners: 0.6;
}

.special-3-1d8 {
--smooth-corners: 3, 1.8;
}

.special-0d6-2 {
--smooth-corners: 0.6, 2;
}

.custom-6 {
Expand Down Expand Up @@ -133,10 +141,12 @@
<div class='box mask'>4</div>
<div class='box circleish mask'>2.6</div>
<div class='box circle mask'>2</div>
<div class='box special-3-1d8 mask'>3, 1.8</div>
<div class='box special-0d6-2 mask'>0.6, 2</div>
<div class='box rhombus-convex mask'>1.2</div>
<div class='box rhombus mask'>1</div>
<div class='box rhombus-concave mask'>0.8</div>
<div class='box asteroid mask'>0.5</div>
<div class='box astroid mask'>0.6</div>
</section>

<!-- Black -->
Expand All @@ -149,7 +159,7 @@
<div class='box rhombus-convex'>1.2</div>
<div class='box rhombus'>1</div>
<div class='box rhombus-concave'>0.8</div>
<div class='box asteroid'>0.5</div>
<div class='box astroid'>0.6</div>
</section>

<!-- Avatar -->
Expand Down Expand Up @@ -185,7 +195,7 @@
/>
<img
src='https://media.kitsu.io/users/avatars/42603/large.png?1590004137'
class='avatar mask asteroid'
class='avatar mask astroid'
/>
</section>

Expand Down Expand Up @@ -222,7 +232,7 @@
/>
<img
src='https://media.kitsu.io/anime/poster_images/42722/large.jpg?1580402011'
class='avatar mask asteroid'
class='avatar mask astroid'
/>
</section>

Expand Down Expand Up @@ -259,7 +269,7 @@
/>
<img
src='https://media.kitsu.io/anime/poster_images/42722/large.jpg?1580402011'
class='poster mask asteroid'
class='poster mask astroid'
/>
</section>

Expand Down
38 changes: 26 additions & 12 deletions paint.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,48 @@
class SmoothCornersPainter {
static get inputProperties() {
return ['--smooth-corners'];
return ["--smooth-corners"];
}

superellipse(a, b, n) {
const n2 = 2 / n;
superellipse(a, b, nX = 4, nY) {
if (Number.isNaN(nX)) nX = 4;
if (typeof nY === "undefined" || Number.isNaN(nY)) nY = nX;
if (nX > 100) nX = 100;
if (nY > 100) nY = 100;
if (nX < 0.00000000001) nX = 0.00000000001;
if (nY < 0.00000000001) nY = 0.00000000001;

const nX2 = 2 / nX;
const nY2 = nY ? 2 / nY : nX2;
const steps = 360;
const step = (2 * Math.PI) / steps;
const points = t => {
const cosT = Math.cos(t);
const sinT = Math.sin(t);
return {
x: Math.abs(cosT) ** n2 * a * Math.sign(cosT),
y: Math.abs(sinT) ** n2 * b * Math.sign(sinT)
x: Math.abs(cosT) ** nX2 * a * Math.sign(cosT),
y: Math.abs(sinT) ** nY2 * b * Math.sign(sinT)
};
};
return Array.from({ length: steps }, (_, i) => points(i * step));
}

paint(ctx, geom, properties) {
const m = properties.get('--smooth-corners').toString() || 4;
let n = m;
if (m > 100) n = 100;
if (m < 0.00000000001) n = 0.00000000001;
const [nX, nY] = properties
.get("--smooth-corners")
.toString()
.replace(/ /g, "")
.split(",");

const width = geom.width / 2;
const height = geom.height / 2;
const smooth = this.superellipse(width, height, n);
const smooth = this.superellipse(
width,
height,
parseFloat(nX, 10),
parseFloat(nY, 10)
);

ctx.fillStyle = '#000';
ctx.fillStyle = "#000";
ctx.setTransform(1, 0, 0, 1, width, height);
ctx.beginPath();

Expand All @@ -44,4 +58,4 @@ class SmoothCornersPainter {
}

// eslint-disable-next-line no-undef
registerPaint('smooth-corners', SmoothCornersPainter);
registerPaint("smooth-corners", SmoothCornersPainter);

0 comments on commit cba6e01

Please sign in to comment.