sigma-ui
Version:
CLI for SIGMA-UI components.
16 lines • 3.42 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 'top-0 left-0 overflow-hidden pointer-events-none z-(--infusion-z-index)',\n props.relative\n ? 'absolute w-full h-full'\n : 'fixed w-screen h-screen',\n]);\n\nconst mediaClass = 'w-full h-full object-cover scale-110 opacity-(--infusion-opacity) dark:opacity-(--infusion-opacity-dark)';\nconst noiseClass = 'absolute top-0 left-0 w-full h-full bg-repeat mix-blend-overlay';\n</script>\n\n<template>\n <div\n :class=\"containerClass\"\n :style=\"imageStyle\"\n >\n <img\n v-if=\"props.type === 'image'\"\n :class=\"mediaClass\"\n :src=\"props.src\"\n :style=\"{\n filter: `blur(var(--infusion-blur))`,\n }\"\n alt=\"\"\n >\n <video\n v-if=\"props.type === 'video'\"\n :class=\"mediaClass\"\n :src=\"props.src\"\n :style=\"{\n filter: `blur(var(--infusion-blur))`,\n }\"\n autoplay\n loop\n muted\n playsinline\n alt=\"\"\n />\n <div\n v-if=\"noiseIntensity > 0\"\n :class=\"noiseClass\"\n :style=\"{\n backgroundImage: `url(${noiseDataUrl})`,\n backgroundSize: 'calc(256px * var(--infusion-noise-scale))',\n opacity: 'var(--infusion-noise-opacity)',\n }\"\n />\n </div>\n</template>\n"
},
{
"name": "index.ts",
"content": "export { default as Infusion } from './Infusion.vue';\n"
}
],
"type": "components:ui"
}