UPD: Color picker

This commit is contained in:
Robert Kossessa
2024-02-04 18:48:52 +01:00
parent ccd417c47f
commit 330e2d5e80
4 changed files with 33 additions and 40 deletions

View File

@@ -2,6 +2,7 @@
import { computed, onBeforeMount, ref, watch } from 'vue'
import Color from 'color'
import { SliderRoot, SliderThumb, SliderTrack } from 'radix-vue'
import { MoreHorizontal } from 'lucide-vue-next'
const hueSliderValue = ref(0)
const saturationSliderValue = ref(100)
@@ -152,7 +153,7 @@ function shake() {
<template>
<div>
<div
class="w-full flex p-4 font-heading"
class="flex p-4 font-heading rounded-b-xl"
:style="{backgroundColor: `hsl(${color.hue()},${color.saturationl()}%,${color.lightness()}%)`}">
<div
ref="colorFieldText" class="w-full flex opacity-70"
@@ -229,10 +230,8 @@ function shake() {
</div>
</div>
<div
class="px-6"
:style="{background: `linear-gradient(180deg, hsla(${color.hue()}, ${color.saturationl()}%, ${color.lightness()}%, 30%) 0%, transparent 30%`}">
class="px-6">
<div class="flex pt-4">
<p class="font-heading text-muted-foreground w-24">HUE</p>
<SliderRoot
v-model="hueSliderModel" :max="359"
class="relative flex w-full touch-none select-none items-center h-10">
@@ -240,11 +239,13 @@ function shake() {
class="relative h-2.5 w-full grow overflow-hidden rounded-full border-2 border-zinc-900"
style="background: linear-gradient(90deg, rgba(255, 0, 0, 1) 0%, rgba(255, 154, 0, 1) 10%, rgba(208, 222, 33, 1) 20%, rgba(79, 220, 74, 1) 30%, rgba(63, 218, 216, 1) 40%, rgba(47, 201, 226, 1) 50%, rgba(28, 127, 238, 1) 60%, rgba(95, 21, 242, 1) 70%, rgba(186, 12, 248, 1) 80%, rgba(251, 7, 217, 1) 90%, rgba(255, 0, 0, 1) 100%)" />
<SliderThumb
class="block h-5 w-5 rounded-full border hover:bg-zinc-900 border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 cursor-pointer focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" />
class="flex h-6 w-8 rounded-[8px] hover:bg-zinc-200 outline outline-zinc-100 bg-zinc-300 focus-visible:outline-none focus-visible:ring-1 cursor-pointer focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 text-zinc-600 justify-center items-center"
style="box-shadow: -3px 0 15px 0 rgba(0,0,0,0.6)">
<MoreHorizontal class="h-full" />
</SliderThumb>
</SliderRoot>
</div>
<div class="flex pt-4">
<p class="font-heading text-muted-foreground w-24">SAT</p>
<SliderRoot
v-model="saturationSliderModel" :max="100"
class="relative flex w-full touch-none select-none items-center h-10">
@@ -252,11 +253,13 @@ function shake() {
class="relative h-2.5 w-full grow overflow-hidden rounded-full border-2 border-zinc-900"
:style="{background: `linear-gradient(90deg, hsl(0, 0%, ${saturationSliderColor.lightness()}%) 0%, hsl(${saturationSliderColor.hue()}, 100%, ${saturationSliderColor.lightness()}%) 100%)`}" />
<SliderThumb
class="block h-5 w-5 rounded-full border hover:bg-zinc-900 border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 cursor-pointer focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" />
class="flex h-6 w-8 rounded-[8px] hover:bg-zinc-200 outline outline-zinc-100 bg-zinc-300 focus-visible:outline-none focus-visible:ring-1 cursor-pointer focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 text-zinc-600 justify-center items-center"
style="box-shadow: -3px 0 15px 0 rgba(0,0,0,0.6)">
<MoreHorizontal class="h-full" />
</SliderThumb>
</SliderRoot>
</div>
<div class="flex pt-4">
<p class="font-heading text-muted-foreground w-24">VAL</p>
<SliderRoot
v-model="valueSliderModel" :max="100"
class="relative flex w-full touch-none select-none items-center h-10">
@@ -264,7 +267,10 @@ function shake() {
class="relative h-2.5 w-full grow overflow-hidden rounded-full border-2 border-zinc-900"
:style="{background: `linear-gradient(90deg, black, hsl(${valueSliderColor.hue()}, ${valueSliderColor.saturationl()}%, ${valueSliderColor.lightness()}%) 100%`}" />
<SliderThumb
class="block h-5 w-5 rounded-full border hover:bg-zinc-900 border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 cursor-pointer focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" />
class="flex h-6 w-8 rounded-[8px] hover:bg-zinc-200 outline outline-zinc-100 bg-zinc-300 focus-visible:outline-none focus-visible:ring-1 cursor-pointer focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 text-zinc-600 justify-center items-center"
style="box-shadow: -3px 0 15px 0 rgba(0,0,0,0.6)">
<MoreHorizontal class="h-full" />
</SliderThumb>
</SliderRoot>
</div>
</div>

View File

@@ -1,15 +1,20 @@
<template>
<div class="flex font-heading">
<button
v-for="(option, key) in options" :key="key"
class="flex-1 pt-2 items-center text-center"
:class="currentOption!==key ? 'hover:bg-zinc-800 text-zinc-200' : 'text-black bg-zinc-200 hover:bg-zinc-100'"
@click="currentOption = key">
{{ $t(option.titleKey) }}
<span class="flex h-4 w-full mt-2" :style="{background: option.color.hex()}" />
</button>
<div
class="p-4"
:style="{background: `linear-gradient(180deg, hsla(${options[currentOption].color.hue()}, ${options[currentOption].color.saturationl()}%, ${options[currentOption].color.lightness()}%, 30%) 0%, transparent 50%`}">
<div
class="flex font-heading rounded-t-xl overflow-hidden">
<button
v-for="(option, key) in options" :key="key"
class="flex-1 pt-2 items-center text-center"
:class="currentOption!==key ? 'hover:bg-zinc-800 text-zinc-200 bg-zinc-900' : 'text-black bg-zinc-300 hover:bg-zinc-200'"
@click="currentOption = key">
{{ $t(option.titleKey) }}
<span class="flex h-4 w-full mt-2" :style="{background: option.color.hex()}" />
</button>
</div>
<HSVInput v-model="options[currentOption].color" class="relative z-20" />
</div>
<HSVInput v-model="options[currentOption].color" class="relative z-20" />
</template>
<script setup>
import HSVInput from '@/components/common/HSVInput.vue'

View File

@@ -6,7 +6,7 @@
<button class="flex items-center" @click="showProfileList=true">
<component :is="showProfileList ? List : ArrowLeft" class="w-5 h-full mr-1" />
<span class="font-heading mr-2">
<ScrambleText :text="showProfileList ? $t('profiles.title') : store.selectedProfile.name" />
<ScrambleText :text="showProfileList ? $t('profiles.title') : store.selectedProfile?.name" />
<ScrambleText
v-if="showProfileList" class="text-sm text-zinc-600"
scramble-on-mount
@@ -64,7 +64,7 @@
<ProfileButton
v-for="(profile, index) in tagProfiles" :key="profile.id" v-model="tagProfiles[index]"
class="border-0 border-b"
:selected="store.selectedProfile.id === profile.id"
:selected="store.selectedProfile?.id === profile.id"
@select="store.selectProfile(profile.id); showProfileList=false"
@duplicate="store.duplicateProfile(profile.id)"
@delete="store.deleteProfile(profile.id)" />

View File

@@ -1,20 +1,3 @@
// import { computed, reactive } from 'vue'
//
// export const store = reactive({
// device: {
// profiles: [],
// activeProfileId: null,
// activeProfile: computed(() => {
// return store.device.profiles.find(p => p.id === store.device.activeProfileId)
// }),
// },
// currentProfileId: null,
// currentProfile: computed(() => {
// return store.device.profiles.find(p => p.id === store.currentProfileId)
// }),
// profileIds: computed(() => store.device.profiles.map(p => p.id)),
// })
import { createPinia, defineStore } from 'pinia'
import Axios from 'axios'
import schema from '@/data/profileSchema.json'
@@ -28,7 +11,6 @@ import KeyLightConfig from '@/components/config/keys/KeyLightConfig.vue'
const ajv = new Ajv()
export const useStore = defineStore('main', {
// arrow function recommended for full type inference
state: () => {
return {
profiles: [],
@@ -125,7 +107,7 @@ export const useStore = defineStore('main', {
ids.add(profile.id)
return true
}),
selectedProfileId: profiles[0]?.id || null,
//selectedProfileId: profiles[0]?.id || null,
})
}).catch((err) => {
console.error(err)