From a6b4e0e00292ef047642986cf3da415fcf8f1340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=9C=D0=B0?= =?UTF-8?q?=D0=BB=D1=8E=D0=B3=D0=B8=D0=BD?= <d.malygin@iqdev.digital> Date: Wed, 15 Jan 2025 17:07:13 +0500 Subject: [PATCH] feat: 'Knob' in process --- src/stories/components/Knob/Knob.vue | 58 +++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/src/stories/components/Knob/Knob.vue b/src/stories/components/Knob/Knob.vue index 73dc2bd..7ed7a92 100644 --- a/src/stories/components/Knob/Knob.vue +++ b/src/stories/components/Knob/Knob.vue @@ -1,15 +1,69 @@ <script setup lang="ts"> import type { IKnobProps } from '@interfaces/componentsProps'; +import { computed } from 'vue'; +import { convertThemeToColor } from '@helpers/common'; -const props = withDefaults(defineProps<IKnobProps>(), {}); +const props = withDefaults(defineProps<IKnobProps>(), { + min: 0, + max: 2, + negativeTheme: 'black', + showLabel: true, +}); const value = defineModel('value'); + +const degreesTotal = computed(() => 360 - 90); +const length = computed(() => props.max - props.min); +const textColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); +const background = computed(() => { + const color = convertThemeToColor( + props.negativeTheme ?? (props.theme === 'white' ? 'black' : props.theme === 'black' ? 'white' : props.theme), + (!props.negativeTheme && props.theme === 'black') || props.negativeTheme === 'white' + ? '500' + : props.darknessNegativeTheme, + ); + return `radial-gradient(circle at center, transparent 50%, ${color} 50%)`; +}); +const conicGradient = computed(() => { + return `conic-gradient(red ${(225 + (1 / length.value) * degreesTotal.value) % 360}deg, transparent 225deg)`; +}); </script> <template> - <section class="container"></section> + {{ (225 + (1 / length) * degreesTotal) % 360 }} + {{ length }} + {{ conicGradient }} + <section class="container"> + <div class="circle" :style="`width: 100px; height: 100px`"> + <div class="circle selected" :style="`width: 100px; height: 100px`"></div> + + <span v-if="showLabel" class="count">{{ value }}</span> + </div> + </section> </template> <style scoped> .container { + position: relative; +} +.circle { + overflow: hidden; + border-radius: 50%; + background: v-bind(background); + clip-path: polygon(0 0, 0 100%, 50% 50%, 50% 50%, 100% 100%, 100% 0); +} +.selected { + position: absolute; + z-index: 100; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: v-bind(conicGradient); +} +.count { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); } </style> -- GitLab