UPD: Color picker
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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)" />
|
||||
|
||||
20
src/store.js
20
src/store.js
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user