You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

108 lines
3.2 KiB

<script lang="ts" context="module">
export const selectedColorPicker = writable<any>(null);</script>
<script lang="ts">
import type { Color } from "$lib/models/color";
import { rgb2hsv } from "$lib/utils/color";
import { tick } from "svelte";
import { writable } from "svelte/store";
export let color: Color;
export let id: any = null;
let xy: boolean;
let x: number;
let y: number;
$: {
if (color.xy) {
xy = true;
x = color.xy.x;
y = color.xy.y;
} else if (color.hs) {
xy = false;
x = Math.sin((360-color.hs.hue) * (Math.PI / 180)) * (color.hs.sat * 0.85);
y = Math.cos((360-color.hs.hue) * (Math.PI / 180)) * (color.hs.sat * 0.85);
} else if (color.k) {
const angle = 2.5 + ((color.k - 1000) / 11000) * 355;
x = Math.sin((180-angle) * (Math.PI / 180)) * 0.95;
y = Math.cos((180-angle) * (Math.PI / 180)) * 0.95;
} else if (color.rgb) {
const hs = rgb2hsv(color.rgb);
xy = false;
x = Math.sin((360-hs.hue) * (Math.PI / 180)) * (hs.sat * 0.85);
y = Math.cos((360-hs.hue) * (Math.PI / 180)) * (hs.sat * 0.85);
}
}
function onClickColor(event: MouseEvent & { currentTarget: EventTarget & HTMLDivElement; }) {
if (xy) {
const x = Math.floor((event.offsetX / event.currentTarget.offsetWidth) * 1000) / 1000;
const y = Math.floor((event.offsetY / event.currentTarget.offsetHeight) * 1000) / 1000;
color = { xy: { x, y } };
} else {
const x = 2 * ((event.offsetX / event.currentTarget.offsetWidth) - 0.505);
const y = 2 * ((event.offsetY / event.currentTarget.offsetHeight) - 0.505);
const dist = Math.sqrt((x*x)+(y*y));
const angle = ((Math.atan2(y/dist, x/dist)*(180/Math.PI))+360) % 360.0
if (dist > 0.9) {
color = { k: Math.max(Math.min(Math.floor((((((angle + 90) % 360)-2.5)/355) * 11000) + 1000), 12000), 1000) }
} else {
color = { hs: { hue: Math.floor((270+angle)%360), sat: Math.floor(Math.min(dist / 0.85, 1) * 100) / 100 } };
}
}
tick().then(() => {
tick().then(() => { $selectedColorPicker = id; });
});
}
</script>
{#if $selectedColorPicker == id}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="color-picker" on:click={onClickColor}>
{#if xy}
<img draggable="false" alt="color wheel" src="/color-xy.png" />
<div class="dot" style="left: calc({x} * 10ch); top: calc({y-1} * 10ch)">
<div class="ring"></div>
</div>
{:else}
<img draggable="false" alt="color wheel" src="/color-hsk.png" />
<div class="dot" style="left: calc({((x/2)+0.5)} * 10ch + 0.5px); top: calc({((y/2)+0.5)-1} * 10ch + 0.5px)">
<div class="ring"></div>
</div>
{/if}
</div>
{/if}
<style lang="sass">
@import "$lib/css/colors.sass"
div.color-picker
position: relative
width: 10ch
height: 10ch
> img
width: 10ch
height: 10ch
div.dot
position: relative
z-index: 10
pointer-events: none
div.ring
position: relative
left: -0.525ch
top: -0.95ch
width: 1ch
height: 1ch
border: 2px solid $color-main4
box-sizing: border-box
border-radius: 1ch
</style>