Skip to content

Instantly share code, notes, and snippets.

@trezy
Created January 13, 2023 15:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trezy/8680345e5e1698eb478ab0a98d826304 to your computer and use it in GitHub Desktop.
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.
.componentWithCutCorners {
background-color: red;
clip-path: generateCornerCutPath((
'borderSize': $panelBorderSize,
'clipSize': $panelCornerClipSize,
'isBorder': false,
'uiScale': var(--ui-scale),
));
display: block;
height: 100px;
width: 100px;
}
@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