ADD: Sexy slider animations
Dear god this was a huge pain in the ass to get right. Worth it ✨
This commit is contained in:
@@ -131,6 +131,7 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<SliderThumb
|
<SliderThumb
|
||||||
|
:class="{ 'transition-all': animateSliders }"
|
||||||
class="flex h-6 w-8 cursor-pointer items-center justify-center rounded-[8px] border border-zinc-100 bg-zinc-300 text-zinc-600 hover:bg-zinc-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
|
class="flex h-6 w-8 cursor-pointer items-center justify-center rounded-[8px] border border-zinc-100 bg-zinc-300 text-zinc-600 hover:bg-zinc-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
|
||||||
style="box-shadow: -3px 0 15px 0 rgba(0, 0, 0, 0.6)"
|
style="box-shadow: -3px 0 15px 0 rgba(0, 0, 0, 0.6)"
|
||||||
>
|
>
|
||||||
@@ -152,6 +153,7 @@
|
|||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<SliderThumb
|
<SliderThumb
|
||||||
|
:class="{ 'transition-all': animateSliders }"
|
||||||
class="flex h-6 w-8 cursor-pointer items-center justify-center rounded-[8px] border border-zinc-100 bg-zinc-300 text-zinc-600 hover:bg-zinc-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
|
class="flex h-6 w-8 cursor-pointer items-center justify-center rounded-[8px] border border-zinc-100 bg-zinc-300 text-zinc-600 hover:bg-zinc-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
|
||||||
style="box-shadow: -3px 0 15px 0 rgba(0, 0, 0, 0.6)"
|
style="box-shadow: -3px 0 15px 0 rgba(0, 0, 0, 0.6)"
|
||||||
>
|
>
|
||||||
@@ -171,6 +173,7 @@
|
|||||||
:style="{ background: `linear-gradient(90deg, black, ${valueSliderColor.hex()} 100%` }"
|
:style="{ background: `linear-gradient(90deg, black, ${valueSliderColor.hex()} 100%` }"
|
||||||
/>
|
/>
|
||||||
<SliderThumb
|
<SliderThumb
|
||||||
|
:class="{ 'transition-all': animateSliders }"
|
||||||
class="flex h-6 w-8 cursor-pointer items-center justify-center rounded-[8px] border border-zinc-100 bg-zinc-300 text-zinc-600 hover:bg-zinc-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
|
class="flex h-6 w-8 cursor-pointer items-center justify-center rounded-[8px] border border-zinc-100 bg-zinc-300 text-zinc-600 hover:bg-zinc-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
|
||||||
style="box-shadow: -3px 0 15px 0 rgba(0, 0, 0, 0.6)"
|
style="box-shadow: -3px 0 15px 0 rgba(0, 0, 0, 0.6)"
|
||||||
>
|
>
|
||||||
@@ -266,6 +269,17 @@ const valueSliderColor = computed(() => {
|
|||||||
return Color.hsv(hueSliderModel.value[0], saturationSliderModel.value[0], 100)
|
return Color.hsv(hueSliderModel.value[0], saturationSliderModel.value[0], 100)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const animateSliders = ref(false)
|
||||||
|
const disableAnimateSliders = useDebounceFn(() => {
|
||||||
|
animateSliders.value = false
|
||||||
|
}, 150)
|
||||||
|
const enableAnimateSliders = () => {
|
||||||
|
console.log('ANIMATE!!!')
|
||||||
|
animateSliders.value = true
|
||||||
|
disableAnimateSliders()
|
||||||
|
}
|
||||||
|
defineExpose({ enableAnimateSliders })
|
||||||
|
|
||||||
const hexInput = ref('FF0000')
|
const hexInput = ref('FF0000')
|
||||||
const hueInput = ref('000')
|
const hueInput = ref('000')
|
||||||
const saturationInput = ref('100')
|
const saturationInput = ref('100')
|
||||||
@@ -280,6 +294,7 @@ function onSubmitHexInput() {
|
|||||||
input = '#' + input
|
input = '#' + input
|
||||||
}
|
}
|
||||||
if (input.match(/^#[0-9A-F]{6}$/i)) {
|
if (input.match(/^#[0-9A-F]{6}$/i)) {
|
||||||
|
enableAnimateSliders()
|
||||||
color.value = Color(input)
|
color.value = Color(input)
|
||||||
} else shake()
|
} else shake()
|
||||||
}
|
}
|
||||||
@@ -290,6 +305,7 @@ function onSubmitHueInput() {
|
|||||||
shake()
|
shake()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enableAnimateSliders()
|
||||||
const newHue = Math.max(0, Math.min(input, 360))
|
const newHue = Math.max(0, Math.min(input, 360))
|
||||||
if (newHue === color.value.hue()) {
|
if (newHue === color.value.hue()) {
|
||||||
updateInputs()
|
updateInputs()
|
||||||
@@ -303,6 +319,7 @@ function onSubmitSaturationInput() {
|
|||||||
shake()
|
shake()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enableAnimateSliders()
|
||||||
const newSaturation = Math.max(0, Math.min(input, 100))
|
const newSaturation = Math.max(0, Math.min(input, 100))
|
||||||
if (newSaturation === color.value.saturationv()) {
|
if (newSaturation === color.value.saturationv()) {
|
||||||
updateInputs()
|
updateInputs()
|
||||||
@@ -316,6 +333,7 @@ function onSubmitValueInput() {
|
|||||||
shake()
|
shake()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enableAnimateSliders()
|
||||||
const newValue = Math.max(0, Math.min(input, 100))
|
const newValue = Math.max(0, Math.min(input, 100))
|
||||||
if (newValue === color.value.value()) {
|
if (newValue === color.value.value()) {
|
||||||
updateInputs()
|
updateInputs()
|
||||||
@@ -331,6 +349,7 @@ function onSubmitRGBInput() {
|
|||||||
shake()
|
shake()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
enableAnimateSliders()
|
||||||
const newColor = Color.rgb(r, g, b)
|
const newColor = Color.rgb(r, g, b)
|
||||||
if (newColor.hex() === color.value.hex()) {
|
if (newColor.hex() === color.value.hex()) {
|
||||||
updateInputs()
|
updateInputs()
|
||||||
|
|||||||
@@ -17,7 +17,12 @@
|
|||||||
? 'hover:bg-zinc-800 text-muted-foreground mx-[1px]'
|
? 'hover:bg-zinc-800 text-muted-foreground mx-[1px]'
|
||||||
: 'text-black bg-zinc-300 hover:bg-zinc-200 border-x border-t border-zinc-100'
|
: 'text-black bg-zinc-300 hover:bg-zinc-200 border-x border-t border-zinc-100'
|
||||||
"
|
"
|
||||||
@click="currentOption = key"
|
@click="
|
||||||
|
() => {
|
||||||
|
enableAnimateSliders()
|
||||||
|
currentOption = key
|
||||||
|
}
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ $t(option.titleKey) }}
|
{{ $t(option.titleKey) }}
|
||||||
</button>
|
</button>
|
||||||
@@ -29,10 +34,16 @@
|
|||||||
class="h-6 flex-1 transition-colors"
|
class="h-6 flex-1 transition-colors"
|
||||||
:class="{ 'color-tab': currentOption === key }"
|
:class="{ 'color-tab': currentOption === key }"
|
||||||
:style="{ background: Color(option.colorNumber).hex() }"
|
:style="{ background: Color(option.colorNumber).hex() }"
|
||||||
@click="currentOption = key"
|
@click="
|
||||||
|
() => {
|
||||||
|
enableAnimateSliders()
|
||||||
|
currentOption = key
|
||||||
|
}
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<HSVInput
|
<HSVInput
|
||||||
|
ref="hsvInput"
|
||||||
:color-number="options[currentOption].colorNumber"
|
:color-number="options[currentOption].colorNumber"
|
||||||
@input="(colorNumber) => $emit('input', currentOption, colorNumber)"
|
@input="(colorNumber) => $emit('input', currentOption, colorNumber)"
|
||||||
/>
|
/>
|
||||||
@@ -47,6 +58,8 @@ defineEmits(['input'])
|
|||||||
|
|
||||||
const currentOption = ref(null)
|
const currentOption = ref(null)
|
||||||
|
|
||||||
|
const hsvInput = ref(null)
|
||||||
|
|
||||||
const currentColorHex = computed(() => Color(props.options[currentOption.value].colorNumber).hex())
|
const currentColorHex = computed(() => Color(props.options[currentOption.value].colorNumber).hex())
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -69,6 +82,11 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function enableAnimateSliders() {
|
||||||
|
hsvInput.value.enableAnimateSliders()
|
||||||
|
}
|
||||||
|
defineExpose({ enableAnimateSliders })
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
if (currentOption.value === null) currentOption.value = Object.keys(props.options)[0]
|
if (currentOption.value === null) currentOption.value = Object.keys(props.options)[0]
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<ConfigSection title="Key Colors" :icon-component="Palette">
|
<ConfigSection title="Key Colors" :icon-component="Palette">
|
||||||
<PaletteInput
|
<PaletteInput
|
||||||
|
ref="paletteInput"
|
||||||
:options="keyColors"
|
:options="keyColors"
|
||||||
@input="
|
@input="
|
||||||
(optionKey, colorNumber) => {
|
(optionKey, colorNumber) => {
|
||||||
@@ -23,12 +24,14 @@ import PaletteInput from '@renderer/components/common/PaletteInput.vue'
|
|||||||
import { useDeviceStore } from '@renderer/deviceStore'
|
import { useDeviceStore } from '@renderer/deviceStore'
|
||||||
import { useAppStore } from '@renderer/appStore'
|
import { useAppStore } from '@renderer/appStore'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { computed } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const deviceStore = useDeviceStore()
|
const deviceStore = useDeviceStore()
|
||||||
const { keyColor } = storeToRefs(deviceStore)
|
const { keyColor } = storeToRefs(deviceStore)
|
||||||
|
|
||||||
|
const paletteInput = ref(null)
|
||||||
|
|
||||||
const keyColors = computed({
|
const keyColors = computed({
|
||||||
get() {
|
get() {
|
||||||
return {
|
return {
|
||||||
@@ -51,4 +54,9 @@ const keyColors = computed({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => appStore.selectedKey,
|
||||||
|
() => paletteInput.value.enableAnimateSliders()
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user