Created
January 13, 2023 15:03
-
-
Save trezy/8680345e5e1698eb478ab0a98d826304 to your computer and use it in GitHub Desktop.
Sass mixin that generates a `clip-path` polygon to simulate creates the pixelated, snipped corners.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.componentWithCutCorners { | |
background-color: red; | |
clip-path: generateCornerCutPath(( | |
'borderSize': $panelBorderSize, | |
'clipSize': $panelCornerClipSize, | |
'isBorder': false, | |
'uiScale': var(--ui-scale), | |
)); | |
display: block; | |
height: 100px; | |
width: 100px; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@use 'sass:list'; | |
@use 'sass:map'; | |
$optionsDefaults: ( | |
'borderSize': 0, | |
'clipSize': 0, | |
'isBorder': false, | |
'uiScale': 1, | |
); | |
@function generateCornerCutPath($options) { | |
$options: map.merge( | |
$optionsDefaults, | |
$options, | |
); | |
// How thick should the border be; only used if `isBorder` is `true`. | |
$borderSize: map.get($options, 'borderSize'); | |
// How deep the corner should be clipped. | |
$clipSize: map.get($options, 'clipSize'); | |
// Whether to cut out the inside of the polygon. | |
$isBorder: map.get($options, 'isBorder'); | |
// The size of a pixel. | |
$uiScale: map.get($options, 'uiScale'); | |
$points: (); | |
// Top left outer corner | |
@for $index from 0 through $clipSize { | |
$points: list.append( | |
$points, | |
calc(#{$index} * #{$uiScale} * 1px) calc((#{$clipSize} - #{$index}) * #{$uiScale} * 1px), | |
$separator: comma, | |
); | |
$points: list.append( | |
$points, | |
calc(#{$index + 1} * #{$uiScale} * 1px) calc((#{$clipSize} - #{$index}) * #{$uiScale} * 1px), | |
$separator: comma, | |
); | |
} | |
$points: list.append( | |
$points, | |
calc(#{$clipSize} * #{$uiScale} * 1px) 0, | |
$separator: comma, | |
); | |
// Top right outer corner | |
$points: list.append( | |
$points, | |
100% 0, | |
$separator: comma, | |
); | |
// Bottom right outer corner | |
@for $index from 0 through $clipSize { | |
$points: list.append( | |
$points, | |
calc(100% - (#{$index} * #{$uiScale} * 1px)) calc(100% - ((#{$clipSize} - #{$index}) * #{$uiScale} * 1px)), | |
$separator: comma, | |
); | |
$points: list.append( | |
$points, | |
calc(100% - (#{$index + 1} * #{$uiScale} * 1px)) calc(100% - ((#{$clipSize} - #{$index}) * #{$uiScale} * 1px)), | |
$separator: comma, | |
); | |
} | |
$points: list.append( | |
$points, | |
calc(100% - (#{$clipSize} * #{$uiScale} * 1px)) 100%, | |
$separator: comma, | |
); | |
// Bottom left outer corner | |
$points: list.append( | |
$points, | |
0 100%, | |
$separator: comma, | |
); | |
// U-turn | |
@if $isBorder { | |
$points: list.append( | |
$points, | |
0 calc(#{$clipSize} * #{$uiScale} * 1px), | |
$separator: comma, | |
); | |
$points: list.append( | |
$points, | |
calc(#{$borderSize}px * #{$uiScale}) calc(#{$clipSize} * #{$uiScale} * 1px), | |
$separator: comma, | |
); | |
$points: list.append( | |
$points, | |
calc(#{$borderSize}px * #{$uiScale}) calc(100% - #{$borderSize}px * #{$uiScale}), | |
$separator: comma, | |
); | |
// Bottom right inner corner | |
@for $index from 0 through ($clipSize - $borderSize + 1) { | |
$points: list.append( | |
$points, | |
calc(100% - ((#{$borderSize}px + #{$clipSize - $index}px) * #{$uiScale})) calc(100% - (#{$borderSize}px + #{$index}px) * #{$uiScale}), | |
$separator: comma, | |
); | |
$points: list.append( | |
$points, | |
calc(100% - ((#{$borderSize}px + #{$clipSize - $index - 1}px) * #{$uiScale})) calc(100% - (#{$borderSize}px + #{$index}px) * #{$uiScale}), | |
$separator: comma, | |
); | |
} | |
// Top right inner corner | |
$points: list.append( | |
$points, | |
calc(100% - (#{$borderSize}px * #{$uiScale})) calc(#{$borderSize}px * #{$uiScale}), | |
$separator: comma, | |
); | |
// Top left inner corner | |
@for $index from 0 through ($clipSize - $borderSize + 1) { | |
$points: list.append( | |
$points, | |
calc((#{$borderSize}px + #{$clipSize - $index}px) * #{$uiScale}) calc((#{$borderSize}px + #{$index}px) * #{$uiScale}), | |
$separator: comma, | |
); | |
$points: list.append( | |
$points, | |
calc((#{$borderSize}px + #{$clipSize - $index - 1}px) * #{$uiScale}) calc((#{$borderSize}px + #{$index}px) * #{$uiScale}), | |
$separator: comma, | |
); | |
} | |
} | |
@return polygon($points); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment