Skip to content

Instantly share code, notes, and snippets.

@AnoRebel
Created January 6, 2024 10:23
Show Gist options
  • Save AnoRebel/c5e6d4224b622717828e464973da351b to your computer and use it in GitHub Desktop.
Save AnoRebel/c5e6d4224b622717828e464973da351b to your computer and use it in GitHub Desktop.
Vue 3 spiral component copied from an instagram reel
<script setup>
import { ref, onMounted } from 'vue'
const ANIMATION_DURATION = 4000; // ms
const spiral = ref(null);
const spiral_1 = ref(null);
const words = ref("anorebel");
onMounted(() => {
const characters = words.value.split("").forEach((char, index) => {
const createElement = offset => {
const div = document.createElement("div");
div.innerText = char;
div.classList.add("character");
div.style.animationDelay = `-${index * (ANIMATION_DURATION / 16) - offset}ms`;
return div;
}
spiral.value.append(createElement(0));
spiral_1.value.append(createElement(-1 * (ANIMATION_DURATION / 2)));
});
});
</script>
<template>
<div ref="spiral" class="spiral" ></div>
<div ref="spiral_1" class="spiral" ></div>
</template>
<style>
html, body {
height: 100%;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
background-color: black;
overflow: hidden;
}
.spiral {
display: flex;
align-items: center;
gap: 10px;
position: absolute;
}
@property --angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
@keyframes spiral {
0% {
--angle: 0deg;
}
100% {
--angle: 360deg;
}
}
.character {
color: white;
font-size: 4em;
transform: translateY(calc(sin(var(--angle)) * 100px)) scale(calc(cos(var(--angle)) * 0.5 + 0.5));
animation: spiral 4s linear infinite;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment