Skip to content

Commit

Permalink
Update ElgatoNeo preset UI.
Browse files Browse the repository at this point in the history
  • Loading branch information
sebinside committed Aug 4, 2024
1 parent 9deefbe commit 95ef102
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 30 deletions.
162 changes: 136 additions & 26 deletions StreamAwesome/src/components/settings/presets/ElgatoNeo.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { reactive, ref } from 'vue'
import type { CustomIcon, FontAwesomePreset } from '@/model/customIcon'
import { ColorSpaceKeys } from '@/model/customIcon'
const props = defineProps<{
icon: CustomIcon<FontAwesomePreset>
Expand All @@ -10,23 +11,42 @@ const currentIcon = reactive(props.icon ?? ({} as CustomIcon<FontAwesomePreset>)
currentIcon.presetSettings = {
preset: 'Elgato Neo',
colorSpace: 'lch',
hueStart: 0,
hueStop: 180,
lightness: 50,
hueStart: 220,
hueShift: 60,
lightness: 0.6,
invertDirection: false,
saturation: 100,
saturation: 0.8,
symbolOnly: false,
translation: 0
}
currentIcon.fontAwesomeIcon.style = 'solid'
currentIcon.fontAwesomeIcon.family = 'classic'
// FIXME: Fix this hack
const currentHue = ref(currentIcon.presetSettings.hueStart)
const settingsExpanded = ref(false)
const toggleSettings = () => {
settingsExpanded.value = !settingsExpanded.value
}
</script>

<template>
<label class="inline-flex cursor-pointer items-center">
<label for="hueSelector" class="block flex-grow text-sm font-medium text-gray-900 dark:text-white"
>Hue Start:</label
>
<input
type="range"
id="hueSelector"
min="0"
max="360"
class="selector focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
v-model="(currentIcon as CustomIcon<'Elgato Neo'>).presetSettings.hueStart"
@input="currentHue = (currentIcon as CustomIcon<'Elgato Neo'>).presetSettings.hueStart"
/>

<label class="mt-3 inline-flex cursor-pointer items-center">
<input
type="checkbox"
class="peer sr-only"
Expand All @@ -38,28 +58,102 @@ const currentHue = ref(currentIcon.presetSettings.hueStart)
<span class="ms-3 text-sm font-medium text-gray-900 dark:text-white">Invert Direction</span>
</label>

<label for="hueSelector" class="block flex-grow text-sm font-medium text-gray-900 dark:text-white"
>Hue start:</label
>
<input
type="range"
id="hueSelector"
max="360"
min="0"
class="selector focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
v-model="(currentIcon as CustomIcon<'Elgato Neo'>).presetSettings.hueStart"
/>
<label for="hueSelector" class="block flex-grow text-sm font-medium text-gray-900 dark:text-white"
>Hue stop:</label
<br />

<label class="mt-3 inline-flex cursor-pointer items-center">
<input
type="checkbox"
class="peer sr-only"
v-model="(currentIcon as CustomIcon<'Elgato Neo'>).presetSettings.symbolOnly"
/>
<div
class="peer relative h-6 w-11 rounded-full bg-gray-200 after:absolute after:start-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:bg-blue-600 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rtl:peer-checked:after:-translate-x-full dark:border-gray-600 dark:bg-gray-700 dark:peer-focus:ring-blue-800"
></div>
<span class="ms-3 text-sm font-medium text-gray-900 dark:text-white">Symbol Only</span>
</label>

<br />

<button
class="mt-3 cursor-pointer rounded bg-slate-900 p-1 leading-3 text-gray-200 hover:text-blue-500"
:title="settingsExpanded ? 'Fewer options' : 'More options'"
@click="toggleSettings"
>
<input
type="range"
id="hueSelector"
max="360"
min="0"
class="selector focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
v-model="(currentIcon as CustomIcon<'Elgato Neo'>).presetSettings.hueStop"
/>
<i class="fa-solid fa-gear text-center text-xs"></i
><span class="ml-2 text-xs">Toggle More Options</span>
</button>

<div v-if="settingsExpanded" class="mt-2 border-l-4 border-l-gray-700 pl-2">
<label for="hueShift" class="block text-sm font-medium text-gray-900 dark:text-white"
>Hue Shift:</label
>
<input
type="range"
id="hueShift"
min="0"
max="180"
class="h-2 w-full cursor-pointer appearance-none rounded-lg bg-gray-200 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:bg-gray-700"
v-model="(currentIcon as CustomIcon<'Elgato Neo'>).presetSettings.hueShift"
/>

<label for="hueShift" class="block text-sm font-medium text-gray-900 dark:text-white"
>Translation:</label
>
<input
type="range"
id="hueShift"
min="-0.5"
max="0.5"
step="0.01"
class="h-2 w-full cursor-pointer appearance-none rounded-lg bg-gray-200 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:bg-gray-700"
v-model="(currentIcon as CustomIcon<'Elgato Neo'>).presetSettings.translation"
/>

<label
for="saturationSelector"
class="mt-2 block text-sm font-medium text-gray-900 dark:text-white"
>Saturation:</label
>
<input
type="range"
id="saturationSelector"
max="1"
min="0.05"
step="0.01"
class="selector focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
v-model="(currentIcon as CustomIcon<'Elgato Neo'>).presetSettings.saturation"
/>

<label
for="lightnessSelector"
class="mt-2 block text-sm font-medium text-gray-900 dark:text-white"
>Lightness:</label
>
<input
type="range"
id="lightnessSelector"
max="0.95"
min="0.05"
step="0.01"
class="selector focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
v-model="(currentIcon as CustomIcon<'Elgato Neo'>).presetSettings.lightness"
/>

<label
for="colorSpaceSelector"
class="mb-2 mt-3 block text-sm font-medium text-gray-900 dark:text-white"
>Select Color Space:</label
>
<select
id="presetselector"
v-model="(currentIcon as CustomIcon<'Elgato Neo'>).presetSettings.colorSpace"
class="mb-6 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
>
<option v-for="colorSpace in ColorSpaceKeys" :value="colorSpace" :key="colorSpace">
{{ colorSpace.toUpperCase() }}
</option>
</select>
</div>
</template>

<style scoped>
Expand All @@ -86,6 +180,22 @@ const currentHue = ref(currentIcon.presetSettings.hueStart)
);
}
#saturationSelector {
background: linear-gradient(
90deg,
hsl(v-bind('currentHue'), 5%, 56%) 0%,
hsl(v-bind('currentHue'), 100%, 56%) 100%
);
}
#lightnessSelector {
background: linear-gradient(
90deg,
hsl(v-bind('currentHue'), 72%, 5%) 0%,
hsl(v-bind('currentHue'), 72%, 95%) 100%
);
}
input[type='range']::-webkit-slider-thumb,
input[type='range']::-moz-range-thumb {
height: 2rem;
Expand Down
14 changes: 12 additions & 2 deletions StreamAwesome/src/logic/generator/elgatoNeoIconGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,25 @@ export default class ElgatoNeoIconGenerator extends IconGenerator<'Elgato Neo'>
}

private generateTopLeftGradient(startColor: Color, stopColor: Color): CanvasGradient {
const gradient = this.renderingContext.createLinearGradient(0, 0, this.canvas.width, this.canvas.height)
const gradient = this.renderingContext.createLinearGradient(
0,
0,
this.canvas.width,
this.canvas.height
)
gradient.addColorStop(0, startColor.hex())
gradient.addColorStop(1, stopColor.hex())

return gradient
}

private generateBottomLeftGradient(startColor: Color, stopColor: Color): CanvasGradient {
const gradient = this.renderingContext.createLinearGradient(0, this.canvas.width, this.canvas.width, 0)
const gradient = this.renderingContext.createLinearGradient(
0,
this.canvas.width,
this.canvas.width,
0
)
gradient.addColorStop(0, startColor.hex())
gradient.addColorStop(1, stopColor.hex())

Expand Down
6 changes: 4 additions & 2 deletions StreamAwesome/src/model/customIcon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export const FontAwesomePresetKeys = [
'Custom'
] as const
export type FontAwesomePreset = (typeof FontAwesomePresetKeys)[number]
export type ColorSpace = 'rgb' | 'hsl' | 'lab' | 'lch' | 'lrgb'

export const ColorSpaceKeys = ['rgb', 'hsl', 'lab', 'lch', 'lrgb'] as const
export type ColorSpace = (typeof ColorSpaceKeys)[number]

export interface CustomIcon<T extends FontAwesomePreset> {
fontSize: number
Expand Down Expand Up @@ -36,7 +38,7 @@ interface ElgatoNeoPreset extends Preset {
invertDirection: boolean
symbolOnly: boolean
hueStart: number
hueStop: number
hueShift: number
saturation: number
translation: number
lightness: number
Expand Down

0 comments on commit 95ef102

Please sign in to comment.