sigma-ui
Version:
CLI for SIGMA-UI components.
16 lines • 3.99 kB
JSON
{
"name": "infusion",
"dependencies": [],
"registryDependencies": [],
"files": [
{
"name": "Infusion.vue",
"content": "<script setup lang=\"ts\">\nimport { computed, type CSSProperties } from 'vue';\n\ninterface Props {\n src: string;\n opacity?: number;\n opacityDark?: number;\n zIndex?: number;\n blur?: number;\n noiseIntensity?: number;\n noiseScale?: number;\n noiseOpacity?: number;\n blendMode?: CSSProperties['mixBlendMode'];\n relative?: boolean;\n type?: 'image' | 'video';\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n src: '',\n opacity: 0.2,\n opacityDark: 0.3,\n zIndex: 100,\n blur: 64,\n noiseIntensity: 0.5,\n noiseScale: 1,\n noiseOpacity: 0.05,\n blendMode: 'normal',\n relative: false,\n type: 'image',\n});\n\nconst imageStyle = computed(() => ({\n '--infusion-opacity': props.opacity,\n '--infusion-opacity-dark': props.opacityDark,\n '--infusion-z-index': props.zIndex,\n '--infusion-blur': `${props.blur}px`,\n '--infusion-noise-intensity': props.noiseIntensity,\n '--infusion-noise-scale': props.noiseScale,\n '--infusion-noise-opacity': props.noiseOpacity,\n 'mixBlendMode': props.blendMode,\n}));\n\nconst noiseDataUrl = computed(() => {\n if (props.noiseIntensity === 0) {\n return '';\n }\n\n if (typeof document === 'undefined') {\n return '';\n }\n\n const canvas = document.createElement('canvas');\n canvas.width = 256;\n canvas.height = 256;\n const context = canvas.getContext('2d');\n\n if (!context) {\n return '';\n }\n\n const imageData = context.createImageData(canvas.width, canvas.height);\n const data = imageData.data;\n\n for (let index = 0; index < data.length; index += 4) {\n const value = Math.random() * 255;\n data[index] = value;\n data[index + 1] = value;\n data[index + 2] = value;\n data[index + 3] = props.noiseIntensity * 255;\n }\n\n context.putImageData(imageData, 0, 0);\n return canvas.toDataURL();\n});\n\nconst containerClass = computed(() => [\n 'infusion-container',\n {\n 'infusion-container--relative': props.relative,\n },\n]);\n</script>\n\n<template>\n <div\n :class=\"containerClass\"\n :style=\"imageStyle\"\n >\n <img\n v-if=\"props.type === 'image'\"\n class=\"infusion-image\"\n :src=\"props.src\"\n alt=\"\"\n >\n <video\n v-if=\"props.type === 'video'\"\n class=\"infusion-video\"\n :src=\"props.src\"\n autoplay\n loop\n muted\n playsinline\n alt=\"\"\n />\n <div\n v-if=\"noiseIntensity > 0\"\n class=\"infusion-noise\"\n :style=\"{ backgroundImage: `url(${noiseDataUrl})` }\"\n />\n </div>\n</template>\n\n<style scoped>\n.infusion-container {\n position: fixed;\n z-index: var(--infusion-z-index);\n top: 0;\n left: 0;\n overflow: hidden;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n}\n\n.infusion-container--relative {\n position: absolute;\n z-index: var(--infusion-z-index);\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\n.infusion-image {\n width: 100%;\n height: 100%;\n filter: blur(var(--infusion-blur));\n object-fit: cover;\n opacity: var(--infusion-opacity);\n transform: scale(1.1)\n}\n\n.dark .infusion-image {\n opacity: var(--infusion-opacity-dark);\n}\n\n.infusion-video {\n width: 100%;\n height: 100%;\n filter: blur(var(--infusion-blur));\n object-fit: cover;\n opacity: var(--infusion-opacity);\n transform: scale(1.1)\n}\n\n.dark .infusion-video {\n opacity: var(--infusion-opacity-dark);\n}\n\n.infusion-noise {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-repeat: repeat;\n background-size: calc(256px * var(--infusion-noise-scale));\n mix-blend-mode: overlay;\n opacity: var(--infusion-noise-opacity);\n}\n</style>\n"
},
{
"name": "index.ts",
"content": "export { default as Infusion } from './Infusion.vue';\n"
}
],
"type": "components:ui"
}