BarbaJS-like Page Transitions In Vue/NuxtJS - vue.js

After doing quite a bit of research on the topic, I am attempting to figure out how to achieve BarbaJS-like page transitions with Vue/Nuxt.
My goal is to have the URL change upon the dynamic transition of, for example, a portfolio project. So, sort of like an expanding grid layout that also changes the URL when clicked. Examples of what I am trying to achieve are at the following two websites:
https://strakzat.com/
https://infinum.co
The first website actually uses BarbaJS, but the second just uses pushState to achieve the desired effect. When you click on the examples of their work, the project element does an expanding effect into a new page, along with the URL change.
I do know that this is much simpler to achieve using Vue/Nuxt but I cannot seem to figure out how I would go about it within the test project I am working on. In Nuxt, my assumption would be to use a combination of page transitions along with middleware, which would "catch" the data while undergoing the transition and then
the router would take care of the URL change. But then again, maybe it is even much simpler than this.
Any ideas or help would be appreciated.

If you are implementing your VueJS project as a Single Page Application or SPA.
You would probably use vue-router.
Vue-router has explained in their documentation how to add a transition when you navigate from one page to another. It is as simple as wrapping the <router-view> component with <transition> just like the example below:
<transition>
<router-view></router-view>
</transition>

For Future Googler. Just add these in default .vue in layout.
<style>
.page-enter-active {
transition: all 0.25s ease-out;
}
.page-leave-active {
transition: all 0.5s ease-in;
}
.page-enter,
.page-leave-active {
opacity: 0;
}
</style>
That's all. Keep experimenting with it to get the desired effect.

There is a great article here by Sarah Drasner that explains how you can do it either with simple CSS transitions or with more complex transitions using libraries like GSAP.

Related

Vuetify styles being added after initial DOM load

I'm on "nuxt": "2.15.4", "#nuxtjs/vuetify": "1.12.1" and "sass": "1.32.13" and have a navbar component added to my default layout that uses v-navigation-drawer and at first moment of page load there is a flicker and every thing (drawer) splashed on screen and after that css is loaded.
I have read nuxt-css-issue this and kinda understand that it's because of nuxt and vuetify behaviour . so is there any way to solve this?? It's really ugly when you load the app !!
oh btw I use nuxt universal ssr and for vuetify treeShake is true
So, you either wait for the CSS to come with the JS (better performance-wise, but may have some small flickering) or load all the CSS globally at the beginning, then the JS (less good in terms of speed, but no flicker). Do I understand the issue well?
Not sure if there is a real solution to this issue besides maybe display-hiding the component until he is loaded with a #hook:mounted hook and a v-show who is showing the component when done. More info here: https://stackoverflow.com/a/67535239/8816585
Did you found out something on Vuetify's github issues?
Not sure if there is something available yet, feel free to maybe post a new issue.
PS: there is maybe some shenanigan move here, to preload some CSS once we have reached a specific page or some hook. Not sure how would this be doable but knowing the JS ecosystem, this kind of hack may be feasable.

Can I Dynamically Inject a Router View

I am trying to accomplish something that I am not sure is possible or semantically good. I am building out a personal portfolio website and I liked the idea of a full page navigation where each link transitions into a 90% view and the router view loads in that space(See codepen below for transition example). I've stripped out the main router-view from my codesandbox. I am wondering maybe I need named router views?
Another thing I'd like to know is if I could keep the html semantic at all if I basically inject a main tag directing after a nav link? There has to be a better way than how I am doing this. I just need to step back and look at it differently.
CodeSandBox Portfolio:
CodePen Tester for Navigation Transition (I will probably do this a different way using Vue transition components)
See the Pen Portfolio Nav Tester by CJ Haviland (#cjhaviland) on CodePen.

Best way to dynamically change theme of my Vue.js SPA?

So I think the title is enough explaination: I would like to dynamically theme my whole application. Maybe this means to change color of all divs when I press a specific button, or change the whole webapp's colors when a specific user logs in.
Just to give some insights on what I am currently working on I will say that I have built a Vue.js app that uses many libraries, including one called Element-ui which already has a theming option built onto it. The problem is that it's written in scss and I would like to change all the variable colors during the navigation. My project looks something like this:
<template>
... some HTML and components...
</template>
<script>
... some javascript ...
</script>
<style scoped>
... some style that is scoped to the current component only ...
</style>
I have many files like this one so making a "global function" for all of them doesn't seem practical to me. Also I import the main scss file just once in my main.js.
Is there anything I can do to create a dinamic theming for my webapp? Is using saas a good idea? Javascript maybe?
EDIT
I feel like I didn't explain it good enough so I want to add a simple example. If you visit the Element page you can see in the top right corner there is a color selector that, when a color changes, it changes also the whole website's accent colors like the buttons colors, the links colors etc.
Hope this can help understanding a bit better
EDIT
Right now I have settled on a very poor and, I think, badly optimized solution. The idea is that when the user changes theme, I just create a new css file and append it to the current document.
let sheet = document.createElement('style')
sheet.innerHTML = `*[class*="--primary"]{
background-color: ${colors[0]};
}
...`;
document.body.appendChild(sheet);
I truly think this is a very bad solution but right now I can't come up with nothing else that could work dinamically when the user changes a parameter. I would really want the process to be flawless: the user picks a color and the whole application just changes to that specific color, no prebuilt theme.css.
FINAL EDIT
I've finally found a solution, refer to the answer!
Finally, after a few long days I came up with a solution that I think is both easy to implement and very very lightweight.
CSS VARIABLES
Before searching up a lot, I didn't even know the existance of these kind of variables and they don't seem so used. Anyway, I hope this can help someone out there seeking my same answer:
<template
<app-main></app-main>
<app-sidebar></app-sidebar>
...
</template>
<style>
:root{
--primary-color: #C5C5C5!important;
--secondary-color: #6C7478!important;
--tertiary-color: #FFFFFF!important;
--success-color: #80b855!important;
--warning-color: #eaca44!important;
--error-color: #ef4d4d!important;
}
/* Theming */
header{
background-color: var(--primary-color);
}
div{
color: var(--tetriary-colory);
}
...
/* END */
</style>
<script>
import axios from 'axios' /* all your imports etc. */
export default{
data(){
},
methods: {
axios.post(`http://localhost:8080/foo`).then(function (response){
let bodyStyles = document.body.style;
bodyStyles.setProperty('--primary-color', response.colors[0]);
bodyStyles.setProperty('--tertiary-color', response.colors[1]);
...
}
}
}
</script>
As you can see, I just initialize a few useful CSS variables and when I need them (for example in that api post call) I just modify them using a simple bodyStyles.setProperty('propertyName') function.
I really enjoy this type of setup since I use it in my login page so when a user successfully logs-in I load from the database his own colors and set them up just like that.
Hoping this can help someone! Cheers!

Can I include scoped css without Vue Loader?

For a project where Vue is dropped in, is using style or similar available to components?
Vue.component('vue-sup', {
template: '<div>Sup</div>',
style: '* { color: blue; }'
})
I tried adding the styles inside the template like:
<div>
<style>
.here{}
</style>
<div>Sup</div>
</div>
which didn't work because the template parser detected a tag with side effects
Vue's implementation of scoped css is entirely a feature of vue-loader, and thus only works with compilation. Scoped css momentarily made a debut into Html 5 but saw almost no adoption and was dropped entirely as far as I know. There is the anticipation that "Shadow DOM" may be supported broadly and could be use to add scoped css, but adoption is not there yet either.
So at this point you can add unique classes or ids obviously to a parent container and scope your css that way, but is understandably not what you are asking for nor is it always practical.
The best alternative is a pollyfill. There are several that are available. Here is one by Sam Thorogood and another by Thomas Park but if you do a quick search you will likely discover more.
I came across the same problem and I'm able to insert styling inside Vue template
by creating a component that will dynamically insert a <style> tag on the DOM. This might be impractical like #skribe said but it allows me to have separate CSS from JS without using .vue extension.
You can take a look at this

access waveform.png inside .css sheet to use webkit-mask?

based on the custom-player-examples im building my own player.
i used the minimal-player template.
after i set up the player like i want it to be, i started to customize the design (color.css, structure.css, standard,css)
but now i am stuck badly..
i found out that i cant change the background-color of the waveforms unless i use a webkit or the waveform.js.
the webkit should do just fine for me...
my only problem is,
i dont know how to acess the track.waveform_url in neither my index.html or *.css files.
i know its inside waveform-container div but i need the url
.wavekit{
-webkit-mask-box-image: url(**IN HERE!!!**);
background: #81D8D0;
height: 280px;
width: 100%;
bottom: 0px;
position: fixed;
}
inside my stylesheet..
sadly i cant provide a link because its only on my hard drive yet
can somebody please help me out here?
thank you verymuch
Well, this is very hacky, but after a couple of attempts I haven't found a better way to get waveform URL.
Idea is that for first play there is an event of 'ajaxSuccess' that is firing and for the next ones there is 'scPlayer:onAudioReady' event. The point being that image’s DOM is being generated by the plugin only at some point, so we need a certain “hook” like an event to know for sure the image will be already present in DOM.
$(document).bind('ajaxSuccess scPlayer:onAudioReady', function () {
// get image from DOM of player
// it will be re-set every next play
console.log($('.sc-waveform-container > img').attr('src'));
$('.wavekit').style({
'-webkit-mask-box-image': $('.sc-waveform-container > img').attr('src')
});
});
Here's working example http://jsbin.com/uhofom/2/edit (only tested in Chrome)
Custom player project is outdated and will probably not get much attention. Its current state is not very extendable from the JavaScript point of view.
My suggestion would be to use something like Audio5JS or SoundManager2 to play music and to have custom HTML and CSS UI. To get actual sounds or sets data you could query our HTTP API or use SoundCloud JavaScript SDK. Then you'd have proper object with all data including waveform API and would control the process much better.