|
| 1 | +<script lang="ts"> |
| 2 | + export let colors = 8; |
| 3 | + export let saturation = 100; |
| 4 | + export let lightness = 50; |
| 5 | +
|
| 6 | + function x(n: number) { |
| 7 | + return Math.sin((2 * Math.PI) / colors) * n; |
| 8 | + } |
| 9 | +
|
| 10 | + function y(n: number) { |
| 11 | + return n - Math.cos((2 * Math.PI) / colors) * n; |
| 12 | + } |
| 13 | + // Sharp angle (doesnt work for 2) |
| 14 | + // `M50 0 l${x(50)} ${y(50)}L${50+x(25)} ${25+y(25)}L50 25z` |
| 15 | + $: path = |
| 16 | + colors > 1 |
| 17 | + ? `M50 0 a50 50 0 01 ${x(50)} ${y(50)}L${50 + x(25)} ${25 + y(25)}A25 25 0 00 50 25` |
| 18 | + : "M50 0a50 50 0 01 0 100a50 50 0 01 0-100m0 25a25 25 0 01 0 50a25 25 0 01 0-50"; |
| 19 | +
|
| 20 | + let current_color = ""; |
| 21 | + async function copyColor( |
| 22 | + event: MouseEvent & { currentTarget: SVGPathElement } |
| 23 | + ) { |
| 24 | + const rgb = getComputedStyle(event.currentTarget).fill; |
| 25 | + const hex = |
| 26 | + "#" + |
| 27 | + rgb |
| 28 | + .slice(4, -1) |
| 29 | + .split(", ") |
| 30 | + .map((d) => parseInt(d).toString(16).padStart(2, "0")) |
| 31 | + .join("") |
| 32 | + .toUpperCase(); |
| 33 | + await navigator.clipboard.writeText(hex); |
| 34 | + current_color = hex; |
| 35 | + setTimeout(() => (current_color = ""), 1000); |
| 36 | + } |
| 37 | +</script> |
| 38 | + |
| 39 | +<div class="container"> |
| 40 | + <svg viewBox="0 0 100 100"> |
| 41 | + {#key colors} |
| 42 | + {#each Array(colors) as _, i} |
| 43 | + {@const rotation = (360 / colors) * i} |
| 44 | + <!-- svelte-ignore a11y-click-events-have-key-events --> |
| 45 | + <!-- svelte-ignore a11y-no-static-element-interactions --> |
| 46 | + <path |
| 47 | + d={path} |
| 48 | + style:rotate="{rotation}deg" |
| 49 | + style:fill="hsl({rotation} |
| 50 | + {saturation} |
| 51 | + {lightness})" |
| 52 | + on:click={copyColor} |
| 53 | + /> |
| 54 | + {/each} |
| 55 | + {/key} |
| 56 | + </svg> |
| 57 | + {#if current_color !== ""} |
| 58 | + <div class="copied" style:--color={current_color}> |
| 59 | + {current_color} copied |
| 60 | + </div> |
| 61 | + {/if} |
| 62 | +</div> |
| 63 | + |
| 64 | +<style lang="scss"> |
| 65 | + .container { |
| 66 | + position: relative; |
| 67 | + } |
| 68 | + .copied { |
| 69 | + position: absolute; |
| 70 | + inset: 0; |
| 71 | + margin: auto; |
| 72 | + width: fit-content; |
| 73 | + height: fit-content; |
| 74 | + background-color: var(--color); |
| 75 | + color: black; |
| 76 | + padding: 1rem 2rem; |
| 77 | + border-radius: 100rem; |
| 78 | + } |
| 79 | + path { |
| 80 | + transform-origin: center; |
| 81 | + fill-rule: evenodd; |
| 82 | + transition: scale ease 0.15s; |
| 83 | + &:hover { |
| 84 | + scale: 0.95; |
| 85 | + cursor: pointer; |
| 86 | + } |
| 87 | + } |
| 88 | +</style> |
0 commit comments