Yazılım Panteri
Yazılım Panteri
NNuxt
Created by Yazılım Panteri on 11/28/2024 in #❓・help
Nuxt 3 GSAP custom page transitions
@kapa.ai CustomLoader.vue <template> <div class="indicator fixed top-0 left-0" :style="{ pointerEvents: 'none', width: '100%', height: ${props.height}px, opacity: isLoading ? 1 : 0, background: error ? props.errorColor : props.color || undefined, backgroundSize: '100% auto', // Always full size transform: scaleX(${Math.max(progress, 10)}%), // Ensure minimum width transformOrigin: 'left', transition: 'transform 0.1s, height 0.4s, opacity 0.4s', zIndex: 999999 }"></div> <div id="transitionLayer" class="fixed left-0 w-full bg-black z-[10000] flex flex-col items-center justify-start h-0 bottom-0 overflow-hidden" ref="transitionLayer"></div> </template> <script setup> import { ref, watch, onMounted } from 'vue'; import { useRouter } from 'vue-router'; import gsap from 'gsap'; // Props const props = defineProps({ throttle: { type: Number, default: 200 }, duration: { type: Number, default: 2000 }, height: { type: Number, default: 3 // Adjust height for thicker loader }, color: { type: String, default: 'repeating-linear-gradient(to right,#00dc82 0%,#34cdfe 50%,#0047e1 100%)' }, errorColor: { type: String, default: 'repeating-linear-gradient(to right,#f87171 0%,#ef4444 100%)' }, estimatedProgress: { type: Function, default: (duration, elapsed) => (2 / Math.PI) * 100 * Math.atan(((elapsed / duration) * 100) / 50) } }); // Refs const transitionLayer = ref(null); const animationComplete = ref(false); // Tracks animation state // Loading Indicator const { progress, isLoading, error, start, finish, clear } = useLoadingIndicator({ duration: props.duration, throttle: props.throttle, estimatedProgress: props.estimatedProgress }); // Router instance const router = useRouter(); // Watch for loading state watch(progress, newVal => { if (newVal === 100) { startAnimation(); } }); // Start Animation function startAnimation() { gsap.set(transitionLayer.value, { height: 0, top: 'auto', bottom: 0 }); gsap.to(transitionLayer.value, { height: '100%', duration: 1, ease: 'power2.out', onComplete: () => { finishAnimation(); } }); } // Finish Animation function finishAnimation() { const appContainer = document.getElementById('app'); const navbar = document.getElementById('navbar'); const tl = gsap.timeline({ onComplete: () => { // Remove GSAP-applied styles gsap.set(appContainer, { clearProps: 'all' }); } }); animationComplete.value = false; gsap.set(transitionLayer.value, { height: '100%', top: 0, bottom: 'auto' }); tl.to(transitionLayer.value, { height: 0, top: '-100%', duration: 1, ease: 'power2.out' }); tl.fromTo( appContainer, { yPercent: 100 }, { yPercent: 0, duration: 0.8, ease: 'power2.out' }, '<+=0.1' ); tl.play(); } // Mount hook to ensure transition layer is set up onMounted(() => { animationComplete.value = false; }); </script> <style scoped> #transitionLayer { will-change: height; } .counter-enter-active, .counter-leave-active { transition: all 0.15s ease-out; } .counter-leave-active { position: absolute; } .counter-enter-from { transform: translateY(-300%); } .counter-enter-to { transform: translateY(0%); } .counter-leave-from { transform: translateY(0%); } .counter-leave-to { transform: translateY(300%); } </style> app.vue <template> <CustomLoader></CustomLoader> <NuxtLayout> <NuxtPage></NuxtPage> </NuxtLayout> </template> <script setup></script> i want to make a custom page loader. new page should mount after finishAnimation starts. important point is new page should continue to it's loading progress. just not affect visually until animation complete
15 replies
NNuxt
Created by Yazılım Panteri on 11/28/2024 in #❓・help
Nuxt 3 GSAP custom page transitions
@kapa.ai /middleware/loading.global.js
// middleware/transition.js

import gsap from 'gsap';

export default defineNuxtRouteMiddleware(async (to, from, next) => {
const app = useNuxtApp();
if (!document) {
return;
}

// Access the transition layer
const transitionLayer = document.getElementById('transitionLayer');

// Start the page loading and trigger transition animation
app.hook('page:loading:start', () => {
console.log('Loading started');
// Trigger GSAP animation to show the transition layer
gsap.set(transitionLayer, { height: 0, top: 'auto', bottom: 0 });
gsap.to(transitionLayer, {
height: '100%',
duration: 1,
ease: 'power2.out'
});
});

// End the page loading and trigger transition animation for the exit
app.hook('page:finish', () => {
console.log('Loading ended');
// Trigger GSAP animation to hide the transition layer after loading
gsap.to(transitionLayer, {
height: 0,
duration: 0.5,
ease: 'power2.inOut',
onComplete: () => {
// Ensure the transition layer is reset after the animation
gsap.set(transitionLayer, { top: 'auto', bottom: 0 });
}
});
});
});
// middleware/transition.js

import gsap from 'gsap';

export default defineNuxtRouteMiddleware(async (to, from, next) => {
const app = useNuxtApp();
if (!document) {
return;
}

// Access the transition layer
const transitionLayer = document.getElementById('transitionLayer');

// Start the page loading and trigger transition animation
app.hook('page:loading:start', () => {
console.log('Loading started');
// Trigger GSAP animation to show the transition layer
gsap.set(transitionLayer, { height: 0, top: 'auto', bottom: 0 });
gsap.to(transitionLayer, {
height: '100%',
duration: 1,
ease: 'power2.out'
});
});

// End the page loading and trigger transition animation for the exit
app.hook('page:finish', () => {
console.log('Loading ended');
// Trigger GSAP animation to hide the transition layer after loading
gsap.to(transitionLayer, {
height: 0,
duration: 0.5,
ease: 'power2.inOut',
onComplete: () => {
// Ensure the transition layer is reset after the animation
gsap.set(transitionLayer, { top: 'auto', bottom: 0 });
}
});
});
});
i'm using nested pages sometimes and page:finish hook called multiple times when that happen. for exapmle i have pages/profile.vue and also have pages/profile/[name]/index.vue. is there any prevent or fix to call page:finish hook multiple times for same request?
15 replies
NNuxt
Created by Yazılım Panteri on 10/8/2024 in #❓・help
Need help for component library with vue 3
thanks. i will send when it done. now i need some really experienced dev to determine core principles about this project. i'm still working on it
4 replies
NNuxt
Created by Yazılım Panteri on 10/8/2024 in #❓・help
Need help for component library with vue 3
Hello guys! I need some advices and help about my Project. I'm currently working on a aceternity ui and shadcn ui like component library for vue and nuxt 3. I have prepared some examples and skeleton about it but i feel something is missing but i don't know how to fix it. I'm not a 10 year experienced guy worked on a Google or apple so i need some guidance. Here is a demo version of the Project https://nuxt3-component-library.pages.dev/docs/components/3d-card And of course github repo https://github.com/safakdinc/nuxt3-component-library If you are interested, feel free to contact via dm. Important reminder! Since this is an independent project, I cannot give you earnings references or promises of success. we'll wait and see what happens
4 replies
NNuxt
Created by Yazılım Panteri on 6/18/2024 in #❓・help
index.html cannot load js files when i generate page with nuxi generate
it works. Thaks
8 replies
NNuxt
Created by Yazılım Panteri on 6/18/2024 in #❓・help
index.html cannot load js files when i generate page with nuxi generate
i'm new to deployment work. how can I make the changes you mentioned?
8 replies
NNuxt
Created by Yazılım Panteri on 6/2/2023 in #❓・help
Nuxt 3 CORS error
is there any option for bypass this cors error?
6 replies
NNuxt
Created by Yazılım Panteri on 6/2/2023 in #❓・help
Nuxt 3 CORS error
i send a get request to the server. payload is a youtube link. it can be any youtube video. ytdl-core recieve this link and find it's id. after that it's return a link like the first picture. you can use it in <audio src> element and play it freely. but when this code runs, source.value = ctx.createMediaElementSource(audio.value); i get error message. i don't know cors and nuxt 3 server very well and i need help
6 replies
NNuxt
Created by Yazılım Panteri on 6/2/2023 in #❓・help
Nuxt 3 CORS error
/server/api/audio_link.js import ytdl from 'ytdl-core'; export default defineEventHandler(async event => { const query = getQuery(event); const videoUrl = query.url; const videoId = ytdl.getURLVideoID(videoUrl); const audioInfo = await ytdl.getInfo(videoId); const audioFormat = ytdl.chooseFormat(audioInfo.formats, { quality: 'highestaudio' }); return { data: audioFormat.url }; });
6 replies
NNuxt
Created by Yazılım Panteri on 6/2/2023 in #❓・help
Nuxt 3 CORS error
AudioVisualizer.vue <template> <div class="w-full h-[50vh] flex justify-center items-center box"> <div class="w-full h-full relative transition-all duration-500 flex gap-1 items-end" ref="visualizer"></div> </div> </template> <script setup> import { ref, onMounted } from 'vue'; import '@/assets/visualizer.css'; const visualizer = ref(null); const audio = ref(null); const ctx = new window.AudioContext(); const analyser = ctx.createAnalyser(); const source = ref(null); analyser.fftSize = 64; const bufferLength = analyser.frequencyBinCount; let dataArray = new Uint8Array(bufferLength); const elements = ref([]); onMounted(async () => { audio.value = document.querySelector('audio'); audio.value.crossOrigin = 'anonymous'; source.value = ctx.createMediaElementSource(audio.value); source.value.connect(analyser); source.value.connect(ctx.destination); }); onMounted(async () => { for (let i = 0; i < bufferLength; i++) { let element = document.createElement('div'); element.classList.add('element'); elements.value.push(element); visualizer.value.appendChild(element); } update(); }); const clamp = (num, min, max) => { if (num >= max) { return max; } else if (num <= min) { return min; } else { return num; } }; const update = () => { requestAnimationFrame(update); analyser.getByteFrequencyData(dataArray); for (let i = 0; i < bufferLength; i++) { let item = dataArray[i]; item = item > 150 ? item : item * 1.5; elements.value[i].style.height = ${item}px; } }; </script>
6 replies