Files
2024-04-23 22:19:44 +08:00

133 lines
2.8 KiB
Vue

<!-- https://codepen.io/TWilson/pen/jOdWqbZ -->
<template>
<div
class="absolute flex flex-col z-[40] w-full !max-w-full items-center justify-center bg-transparent transition-bg overflow-hidden"
:class="className"
>
<div
class="jumbo absolute opacity-60"
:class="{
// '-safari': isSafari,
'-animate': animated,
'-static': isStatic
}"
/>
</div>
</template>
<style scoped>
@keyframes jumbo {
from {
background-position: 50% 50%, 50% 50%;
}
to {
background-position: 350% 50%, 350% 50%;
}
}
.jumbo {
--stripes: repeating-linear-gradient(
100deg,
#fff 0%,
#fff 7%,
transparent 10%,
transparent 12%,
#fff 16%
);
--stripesDark: repeating-linear-gradient(
100deg,
#000 0%,
#000 7%,
transparent 10%,
transparent 12%,
#000 16%
);
--rainbow: repeating-linear-gradient(
100deg,
#60a5fa 10%,
#e879f9 16%,
#5eead4 22%,
#60a5fa 30%
);
contain: strict;
contain-intrinsic-size: 100vw 40vh;
background-image: var(--stripes), var(--rainbow);
background-size: 300%, 200%;
background-position: 50% 50%, 50% 50%;
height: inherit;
/* Webkit GPU acceleration hack for some reason */
/* https://stackoverflow.com/a/21364496 */
-webkit-transform: translateZ(0);
-webkit-perspective: 1000;
-webkit-backface-visibility: hidden;
filter: invert(100%);
mask-image: radial-gradient(ellipse at 100% 0%, black 40%, transparent 70%);
pointer-events: none;
}
.jumbo::after {
content: '';
position: absolute;
inset: 0;
background-image: var(--stripes), var(--rainbow);
background-size: 200%, 100%;
background-attachment: fixed;
mix-blend-mode: difference;
}
.-animate.jumbo::after {
animation: jumbo 90s linear infinite;
}
.-static.jumbo::after {
animation: unset !important;
}
/* .-safari::after {
animation: unset !important;
} */
.dark .jumbo {
background-image: var(--stripesDark), var(--rainbow);
filter: opacity(50%) saturate(200%);
}
.dark .jumbo::after {
background-image: var(--stripesDark), var(--rainbow);
}
</style>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
const props = defineProps<{
class?: string
static?: boolean
}>()
const animated = ref(false)
const isStatic = ref(props.static)
const className = ref(props.class || 'h-screen')
// const isSafari = ref(
// typeof window !== 'undefined'
// ? navigator.userAgent.indexOf('Safari') !== -1 &&
// navigator.userAgent.indexOf('Chrome') === -1
// : false
// )
onMounted(() => {
if (navigator?.hardwareConcurrency > 4) animated.value = true
// isSafari.value =
// navigator.userAgent.indexOf('Safari') !== -1 &&
// navigator.userAgent.indexOf('Chrome') === -1
})
</script>