knxdisplay/web-interface/src/components/widgets/elements/LedElement.vue
2026-02-04 18:18:07 +01:00

64 lines
2.3 KiB
Vue

<template>
<div
class="z-[1] select-none touch-none"
:class="selected ? 'outline outline-2 outline-accent outline-offset-2' : ''"
:style="computedStyle"
@mousedown.stop="$emit('drag-start', { id: widget.id, event: $event })"
@touchstart.stop="$emit('drag-start', { id: widget.id, event: $event })"
@click.stop="$emit('select')"
>
<!-- Resize Handle -->
<div
v-if="selected"
class="absolute -right-1.5 -bottom-1.5 w-3.5 h-3.5 rounded-[4px] bg-accent border-[2px] border-[#1b1308] shadow-[0_4px_12px_rgba(0,0,0,0.35)] cursor-se-resize z-10"
data-resize-handle
@mousedown.stop="$emit('resize-start', { id: widget.id, event: $event })"
@touchstart.stop="$emit('resize-start', { id: widget.id, event: $event })"
>
<span class="absolute right-[2px] bottom-[2px] w-[6px] h-[6px] border-r-2 border-b-2 border-[#1b1308a6] rounded-[2px]"></span>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue';
import { getBaseStyle, clamp, hexToRgba } from '../shared/utils';
const props = defineProps({
widget: { type: Object, required: true },
scale: { type: Number, default: 1 },
selected: { type: Boolean, default: false }
});
defineEmits(['select', 'drag-start', 'resize-start']);
const computedStyle = computed(() => {
const w = props.widget;
const s = props.scale;
const style = getBaseStyle(w, s);
style.borderRadius = '999px';
const brightness = clamp((w.bgOpacity ?? 255) / 255, 0, 1);
const glowColor = (w.shadow && w.shadow.color) ? w.shadow.color : w.bgColor;
const highlight = clamp(brightness + 0.25, 0, 1);
const core = clamp(brightness, 0, 1);
const edge = clamp(brightness * 0.5, 0, 1);
style.background = `radial-gradient(circle at 30% 30%, ${hexToRgba(w.bgColor, highlight)} 0%, ${hexToRgba(w.bgColor, core)} 45%, ${hexToRgba(w.bgColor, edge)} 70%, rgba(0,0,0,0.4) 100%)`;
if (w.shadow && w.shadow.enabled) {
const sx = (w.shadow.x || 0) * s;
const sy = (w.shadow.y || 0) * s;
const blur = (w.shadow.blur || 0) * s;
const spread = (w.shadow.spread || 0) * s;
const glowAlpha = clamp(0.4 + brightness * 0.6, 0, 1);
style.boxShadow = `${sx}px ${sy}px ${blur}px ${spread}px ${hexToRgba(glowColor, glowAlpha)}`;
} else {
style.boxShadow = 'inset 0 0 0 1px rgba(255,255,255,0.12)';
}
return style;
});
</script>