Vue.Js transition not functional - vue.js

I'm trying to use the Vue transitions located on the vue docs (specifically the "Slide Fade") in order to animate the changing of text on a component. I have this particular tag set to render when a watched computed property returns from a vuex store. In order to transition the text through the various options, i have a recursive timeout function that sets the "showAnnouncement" property to false, sets the new text, then makes it true again. This works perfectly with or without the transition.
Here is a snippet from my template, showing it in action.
<div class="announcements">
<h2> Announcements </h2>
<transition name="slide-fade">
<h3 v-if="showAnnouncement">
<a :href="announcementCurrent.link" class="announcementLink">
{{announcementCurrent.title}}
</a>
- {{announcementCurrent.author}}
</h3>
</transition>
<!-- -->
</div>
One of the troubleshooting steps I took was to completely forgo the vue transition component, and set CSS transitions directly on the class. Which failed, so I've decided to go back to square one with vue transitions.
Here is the CSS for the transition, pulled directly from the documentation I've linked above:
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active below version 2.1.8 */ {
transform: translateX(10px);
opacity: 0;
}
Sorry in advance if the spacing is a little off, it didn't seem to want to paste indented properly.
I'm a bit at a loss right now, and thank you in advance for your help.
P.S. I should also mention, that this project uses Vuetify, I don't think it would affect anything, but it might be good to know.

Related

Vue-Leaflet map doesn't render completely [duplicate]

Update: I have put my answer. Please see it.
Original Question:
Can you tell me why leaflet map doesn't show on the full map area?
.html
<ion-content padding>
<div style="height: 100%;width:100%" leaflet [leafletOptions]="options" *ngIf="options" [leafletCenter]="center">
</div>
</ion-content>
.ts
init(): void {
this.options = {
layers: [
tileLayer("http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { maxZoom: 18, attribution: "..." })
],
zoom: 10,
center: this.center = latLng(Number(this.activatedRoute.snapshot.paramMap.get("latitude")), Number(this.activatedRoute.snapshot.paramMap.get("longitude"))),
attributionControl: false,
};
}
UI
Please see the image. It seems a problem with transform. Default it was 0,0,0. I have changed it manually on the browser like so. So how can I set it to the map?
I had the same issue in an ionic 4 project. Like suggested in comment with link I needed to use map.invalidateSize() when I rendered the map, as well as when adding/removing markers or any other action for that matter. This didn't help completely. I also had to manually trigger change detection after that. Here's a sample from our code:
this.map.setView([this.myLocation.latitude, this.myLocation.longitude], 13);
this.map.invalidateSize();
this.ref.detectChanges();
where ref refers to ChangeDetectorRef.
Also make sure that you have the the leaflet css imported in your angular.json file:
"styles": [
// ....
"./node_modules/leaflet/dist/leaflet.css"
]
In my opinion the leaflet is filled 100% in its parents space, can you use the browsers inspect tool to see what is the parents width and height. You can also try using
position: absolute; left: 0;
to ignore parents width
Try removing the padding and changing height to 100vh
Try this:
<ion-content>
<div style="height: 100vh; width:100%" leaflet [leafletOptions]="options" *ngIf="options" [leafletCenter]="center">
</div>
</ion-content>
If you want to set the transform do it like so:
<ion-content padding>
<div style="height: 100%; width:100%; transform: translate3D(250px, 200px, 100px)" leaflet [leafletOptions]="options" *ngIf="options" [leafletCenter]="center">
</div>
</ion-content>
Here I'm using this with Ionic 4 app. I have tried many solutions given by different devs. But none of them worked for me. The problem here is the life cycle event which I have used earlier. So now I use ionViewDidEnter() and no issues.
ionViewDidEnter() {
this.center = latLng(Number(this.activatedRoute.snapshot.paramMap.get("latitude")), Number(this.activatedRoute.snapshot.paramMap.get("longitude")));
this.options = {
layers: [
tileLayer("http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { maxZoom: 18, attribution: "..." })
],
zoom: 17,
center: this.center,
attributionControl: false,
};
this.layers.push(this.mapService.getMarker(this.center, "assets/icon/map/placeholder.png"));
}
I had the same problem, even with the import of leaflet.css and the "invalidateSize()" trick.
It was because I wrote in "myComponent.page.html":
<ion-content>
<div id="map" style="height:400px; width: 100%;"></div>
</ion-content>
It seems Ionic4 css conflicts with leaflet.
You need to get the <div> outside of <ion-content>.
Correct is just :
<div id="map" style="height:400px; width: 100%;"></div>
Hope this help someone
map.invalidateSize() runs after window resize event.
So after height change, just write the code :
window.dispatchEvent(new Event('resize'));
this.map.invalidateSize();
It works like a charm in my case.
Dont' forget to replace map with your map variable.
My it helps someone

Vue transition on router - but transition effects specific html Element

I have a page transition for VUE js that I have implemented. I did this manually because I could not find how to do this using VUES transition.
(I am using gridsome framework for vue js - I have added a custom App.vue page - which should allow transitions of gridsome to act like normal Vue js transitions)
I feel like what I have done is bloated for its use case so wanted to see if anyone knew how to implement this using vue transtions.
#1
Users click component (which has a #click - triggering a this.$router.push() to the route)
#2
A div pops over the screen in the color of that component, creating a nice fade to hide the transition
#3
On the new page, another div identical to the transition one, now exits the screen.
I have this working here for reference, just click on clients (please try not to judge me to much, its still in development) -
https://wtwd.ninjashotgunbear.com/
MY METHOD:
Index.html
Each component is a SectionTitle when the user clicks on one of them they $emit the specific obj with the data for that page (such as the color && the name of the page to be routed to) - this is the #routeChange="reRoute($event) seen below:
<template>
<Layout>
<div class="navs" v-for="section in sections" :key="section.sectionTitle">
<!-- On click delay for screen to come ove top -->
<!-- router to be put here -->
<SectionTitle :data="section" #routeChange="reRoute($event)"/> <<<< COMPONENT that $emits on click
</div>
<!-- fullpage div to slide in and cover up no leave transition -->
<div class="leaveScreen"></div> <<<<< DIV that covers the screen
</Layout>
</template>
This triggers my method that moves the div over the UI view and creates the transition effect:
methods:{
reRoute(value){
console.log(value)
// 1) animate the loading screen
let screen = document.querySelector('.leaveScreen');
screen.style.cssText=`background: ${value.backgroundColor}; left: 0%`;
// 2) re-route the page
setTimeout(()=>{
this.$router.push(value.sectionLink)
}, 700)
}
}
CSS FOR DIV :
.leaveScreen {
position: absolute;
top: 0;
bottom: 0;
left: -100%;
width: 100%;
z-index: 11;
// background color added by the fn reRoute()
transition: all 0.7s;
}
The on the page, I use the mounted hook to remove the div from the users view (in the same, but other way around, way that I added it above.
mounted(){
let screen = document.querySelector('.fadeOutScreen');
// set timeout works to delay
setTimeout(()=>{
screen.style.cssText='left: 100%;'
},700)
}
If you know how to do this in a cleaner code / or by using VUES transition property then your help is very welcomed. I figured that VUE would have a specific way of doing this, but have not found it yet.
Thanks in advance -
W
If you wrap .leave-screen in a transition element you can do something like this:
new Vue({
el: "#app",
data: {
leaveScreen: false
}
})
body {
margin: 0;
}
.click-me {
cursor: pointer;
font-size: 30px;
}
.leave-screen {
position: absolute;
height: 100vh;
width: 100vw;
top: 0;
background-color: rgb(0, 0, 0);
}
.leave-screen-enter-active,
.leave-screen-leave-active {
background-color: rgba(0, 0, 0, 1);
transform: translateX(0);
transition: all 1s ease-in-out;
}
.leave-screen-leave-to,
.leave-screen-enter {
background-color: rgba(0, 0, 0, 0);
transform: translateX(-100%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div #click="leaveScreen = true" class="click-me">
Click Me
</div>
<transition name="leave-screen">
<div v-if="leaveScreen" class="leave-screen" #click="leaveScreen = false"></div>
</transition>
</div>
.leave-screen-enter-active and .leave-screen-leave-active define the state of the element during transition.
.leave-screen-leave-to is the state the element leaves to (surprisingly) and .leave-screen-enter is the state of the element before it enters.
The styles you set on the element itself are where the transition starts/ends (depending on whether it's entering/leaving).
Vue's definitions:
v-enter: Starting state for enter. Added before element is inserted, removed one frame after element is inserted.
v-enter-active: Active state for enter. Applied during the entire entering phase. Added before element is inserted, removed when transition/animation finishes. This class can be used to define the duration, delay and easing curve for the entering transition.
v-leave-active: Active state for leave. Applied during the entire leaving phase. Added immediately when leave transition is triggered, removed when the transition/animation finishes. This class can be used to define the duration, delay and easing curve for the leaving transition.
v-leave-to: Only available in versions 2.1.8+. Ending state for leave. Added one frame after a leaving transition is triggered (at the same time v-leave is removed), removed when the transition/animation finishes.

Slide transition on tab (one pushing the other)

I'm trying to achieve a slide transition between two tabs. One tab is supposed to come from the left pushing the other one to the right and the opposite for the other one.
The leave transition goes well but the tab just pop in straight away without starting where it is supposed to...
I have made a CodePen to reproduce what I've tried : Slide transition test on CodePen
Here is the HTML, it is just a div containting 2 buttons that change the visibility of two div that represents my tabs content.
<div id="transition-test" class="demo">
<div class="tabs">
<button v-for="tab in tabs" class="tab" :key="tab.id" #click="selectedTab = tab.id"> {{tab.text}}</button>
<transition name="slide-right">
<div v-show="1 === selectedTab" class="tab1" key="tab1"></div>
</transition>
<transition name="slide-left">
<div v-show="2 === selectedTab" class="tab2" key="tab2"></div>
</transition>
</div>
</div>
In order to do the transition I do have the following css :
.slide-left,
.slide-right{
position: absolute;
}
.slide-right-enter-to,
.slide-right-leave {
opacity: 1;
transform: translateX(0);
}
.slide-right-enter,
.slide-right-leave-to {
opacity: 0;
transform: translateX(100%);
}
.slide-left-enter-active,
.slide-left-leave-active,
.slide-right-enter-active,
.slide-right-leave-active {
transition: all 500ms ease-in-out;
}
.slide-left-enter-to,
.slide-left-leave {
opacity: 1;
transform: translateX(0);
}
.slide-left-enter,
.slide-left-leave-to {
opacity: 0;
transform: translateX(-100%);
}
Does anyone have an idea about what I'm missing here ?
I found the issue. I don't know why in the Vue transition documentation the css class added at enter is v-enter but the class applied in reality is v-enter-from...
this css class :
.slide-left-enter
becomes :
.slide-left-enter-from
Instead of coding it by yourself, you can use npm version of the transition. It will also help you with its API, Guides and Examples, so that you don't have to worry about those.

Vue.js router transition fade gap

I'm using the amazing transition to slide router pages in vue.js
<template>
<div>
<header-comp></header-comp>
<transition
name="custom-classes-transition"
mode="out-in"
enter-active-class="animated slideInLeft"
leave-active-class="animated slideOutRight"
>
<router-view></router-view>
</transition>
<footer-comp></footer-comp>
</div>
</template>
<style>
#import 'https://cdn.jsdelivr.net/npm/animate.css#3.5.1';
</style>
It works very nice and smooth, but... the new coming page enter when the first one is totally gone. This made a gap between transition.
In Vue manual: Transition-Modes there are a few examples. I need to replicate the third button example but I'm missing the mode I have to use.
Any suggestion?
The main problem with your transitioning elements is that you want them to occupy the same space in DOM at the same time (even if, visually, one enters and one exists - that's only done through transforms but the two elements need to occupy the same space in DOM).
Therefore you need to give one of them position:absolute and use CSS to size and position it correctly, to match the exact position and size it would have when not having position:absolute (which is what it will have when not trasitioning).
Here's a working example. Note yours might need different styles applied to a different element.
Since you haven't provided a minimal, reproducible example with your own markup, there's no way to know.
In the example above, I gave the subsequent <div> (the entering one)
position: absolute;
width: 100%;
top: 60px;
left: 0;
If you choose to wrap all your <router-view>s into a common wrapper element with position:relative, top would need to be 0 (in the example 60px is accounting for <nav>'s height).
Note: and yes, as others already pointed, you don't need mode="in-out". But that still leaves you with the positioning issue.
Edit: I've played with two more examples.
one using a flexbox container of height:100vh where top and bottom elements don't grow and middle one does. When middle element is too big, it becomes scrollable.
another one where I played with the transition effects and Bootstrap Vue.
Actually since you don't need any special behaviour and actually want both transitions to happen at the same time, you shouldn't be using the mode at all. Just remove it and it should work as you described. From the docs link you pasted:
Simultaneous entering and leaving transitions aren’t always desirable though, so Vue offers some alternative transition modes
in-out: New element transitions in first, then when complete, the current element transitions out.
out-in: Current element transitions out first, then when complete, the new element transitions in.
mode="in-out": New element transitions in first, then when complete, the current element transitions out.
new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
showOn: true
},
methods: {
handleClick() {
console.log(this.message);
}
}
})
.slide-fade-enter-active {
transition: all .3s ease;
position: absolute;
left: 0;
top: 0;
}
.slide-fade-leave-active {
position: absolute;
left: 0;
top: 0;
}
.slide-fade-enter, .slide-fade-leave-to {
transform: translateX(10px);
opacity: 0;
}
#app {
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<body>
<div id="app">
<transition name="slide-fade" mode="in-out">
<button v-if="showOn"
key="on"
type="button"
#click="showOn=false">On</button>
<button v-else type="button"
key="off"
#click="showOn=true">Off</button>
</transition>
</div>
</body>

Font awesome spinner not spinning

I have completed an installation of fontawesome in Nuxt with this fantastic link;
https://github.com/FortAwesome/vue-fontawesome
I have a spinner rendered as
<font-awesome-icon :icon="['fas','spinner']" />
The spinner does not spin, it is static.
I added fa-spin as
<font-awesome-icon :icon="['fas','spinner', 'spin']" />
This caused the error in the console Could not find one or more icon(s) undefined
Can anyone point me in the right direction, show me how to get my spinner spinning.
The relevant portion on the nuxt.config.js
modules: [
'nuxt-fontawesome'
],
//font-awesome
fontawesome: {
imports: [
{
set: '#fortawesome/free-solid-svg-icons',
icons: ['fas']
},
],
},
build: {
config.resolve.alias['#fortawesome/fontawesome-free-brands$'] = '#fortawesome/fontawesome-free-brands/shakable.es.js'
config.resolve.alias['#fortawesome/fontawesome-free-solid$'] = '#fortawesome/fontawesome-free-solid/shakable.es.js'
}
In the component("../pages/index.vue") it is;
<template>
<div>
<font-awesome-icon :icon="['fas','spinner','spin' ]" />
</div>
</template>
As suggested by #Steve, i have created a Glitch workspace
https://glitch.com/edit/#!/join/d57a5054-b448-4a53-ad37-d9465b0cef8b
You can add the spin directive.
<font-awesome-icon icon="spinner" spin />
Docs: https://github.com/FortAwesome/vue-fontawesome#basic
This works for me:
<template>
<div>
<font-awesome-icon icon="spinner" class="fa-spin" />
</div>
</template>
Font Awesome v.5, Vue.js v.2 (with #vue/cli 3)
Unless times have changed, Font Awesome does not provide out-of-the-box tools to animate their font and graphic libraries. They simply provide the service of offering single-colored, vector-graphic libraries formatted for various needs: true-type fonts (TTF), scalable vector graphics (SVG), etc.
You'll need to do the animation work yourself. Fortunately, it's very short work with CSS plus you'll get to control the speed of your spinner spinning.
/* Define an animation behavior */
#keyframes spinner {
to { transform: rotate(360deg); }
}
/* This is the class name given by the Font Awesome component when icon contains 'spinner' */
.fa-spinner {
/* Apply 'spinner' keyframes looping once every second (1s) */
animation: spinner 1s linear infinite;
}
I've updated the Glitch workspace you created (very helpful) with the additional CSS lines above to animate. Adjust accordingly and good luck!