How can my splash screen be implemented into Vue? - vue.js

Side note:
The splash screen code below from my Vue app is a view file not a component. Also I'm suing Vue router.
So below is my code, this is a splash screen using Gsap that has a callback function that I can later put in a route that goes to '/' which is the Home view.
How can I have this view showed first when launching the Vue app? And then once the animation is completed the callback will direct the user to the home page. Also one more thing, I'm not sure how this would work, but I want to make sure that once a user goes to the home page and some reason they refresh they don't have to see the splash screen again. How can that also be achieved?
Note: I did try to mess with the index.js under router but nothing worked and redirect never allowed the user to get to the home page.
HTML:
<template>
<div class="module_wrapper">
<h1 ref="title">Welcome</h1>
<div ref="module" class="module">
<div class="top_wrapper">
<div ref="box1" class="box box_1"></div>
</div>
<div class="bottom_wrapper">
<div ref="box2" class="box box_2"></div>
<div ref="box3" class="box box_4"></div>
<div ref="box4" class="box box_5"></div>
<div ref="box5" class="box box_3"></div>
</div>
</div>
</div>
</template>
JavaScript:
import { TimelineLite, Back } from 'gsap';
export default {
methods: {
onCompleteAll () {
console.log('done');
}
},
mounted () {
const {module} = this.$refs;
const {title} = this.$refs;
const {box1} = this.$refs;
const {box2} = this.$refs;
const {box3} = this.$refs;
const {box4} = this.$refs;
const {box5} = this.$refs;
const {top} = this.$refs;
const {bottom} = this.$refs;
const timeline = new TimelineLite({onComplete: this.onCompleteAll});
timeline.to(module, 1.3, {scale: 1, ease: 'elastic.out(1, 0.5)',})
.to(box1, 0.5, {opacity: 1, translateY: 0, ease: Back.easeInOut}, '-=0.4')
.to(box2, 0.5, {opacity: 1, translateY: 0, ease: Back.easeInOut}, '-=0.4')
.to(box3, 0.5, {opacity: 1, translateY: 0, ease: Back.easeInOut}, '-=0.4')
.to(box4, 0.5, {opacity: 1, translateY: 0, ease: Back.easeInOut}, '-=0.4')
.to(box5, 0.5, {opacity: 1, translateY: 0, ease: Back.easeInOut}, '-=0.4')
.to(top, 0.4, {marginLeft: 10 + '%', ease: Back.easeInOut}, '-=0.2')
.to(bottom, 0.4, {marginLeft: 10 + '%', ease: Back.easeInOut}, '-=0.2')
.to(title, 0.4, {
translateY: 0,
opacity: 1,
ease: Back.easeInOut
}, '-=0.8');
}
};
CSS:
#app {
font-family: Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
html {
font-size: 100%;
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
outline: none;
}
html {
width: 100%;
height: 100%;
overflow: hidden;
}
html, body {
transform: perspective(1px) scale(1) translateZ(0);
backface-visibility: hidden;
-webkit-font-smoothing: subpixel-antialiased;
}
body {
background: radial-gradient(#656565, #000000);
width: 100%;
height: 100%;
}
.module_wrapper {
color: white;
text-align: center;
height: 13.4375rem;
width: 18.75rem;
margin: 0;
padding: 0;
border-radius: 0.75rem;
}
h1 {
font-size: 1.4375rem;
font-weight: 500;
color: #D9D9D9;
letter-spacing: 0.5rem;
cursor: default;
opacity: 0;
transform: translateY(10px);
}
.module {
background-color: #fff;
border-radius: 0.75rem;
width: 18.75rem;
height: 11.375rem;
margin: 0;
padding: 0;
transform: scale(0);
}
.top_wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 50%;
padding: 0 1.25rem;
}
.bottom_wrapper {
display: flex;
align-items: center;
padding: 0 1.25rem;
justify-content: space-evenly;
height: 50%;
}
.box {
background-color: #D9D9D9;
border-radius: 0.4375rem;
margin: 0;
padding: 0;
transform: translateY(-40px);
opacity: 0;
}
.box_1 {
width: 14.375rem;
height: 3.6rem;
}
.box_2, .box_3, .box_4, .box_5 {
width: 2.875rem;
height: 3.25rem;
}

You will need to add a Navigation Guard to your / route.
The general idea is:
-Check if the user has already authenticated
-if they have, call next()
-if they haven't, redirect them to the login/splash page: next('login')

There are a few options, but I think the best one will be to control the component's visibility in App.vue rather than inside the component. When the animation is over emit something to the parent, listen to that thing in the parent, and change the component visibility.
In order to display animation only one time, use session storage or local storage, and as the first job on page load, check if storage has anything about that. If it doesn't play your animation.

Related

How to increase clickable area surrounding a Vuetify v-slider's nob?

How do you increase the clickable area surrounding the nobs of Vuetify's v-slider component?
I would like to do this in order to make it easier for users to 'grab the nob' and control the slider, particularly for the sake of mobile UX.
Here is a method to increase the clickable area of the draggable v-slider and v-range-slider nobs using CSS. It should be noted that, as of February 2021, v-slider and v-range-slider do not yet have built-in props to control this functionality.
My answer is based on this github comment (note: it is worth reading this entire github issue thread, as it concerns the OP's question).
<style scoped lang="scss">
.my-slider-class >>> .v-slider__thumb:after {
transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
content: '';
color: inherit;
width: 400%;
height: 400%;
border-radius: 50%;
background: transparent;
position: absolute;
left: -150%;
top: -150%;
}
.my-slider-class >>> .v-slider__thumb:before {
transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
content: '';
color: inherit;
width: 200%;
height: 200%;
border-radius: 50%;
background: currentColor;
opacity: 0.3;
position: absolute;
left: -50%;
top: -50%;
transform: scale(0.1);
pointer-events: none;
}
</style>

Disable or alter size change of TextInput in react-native-web

I'm looking for away to disable or alter the automatic zoom behavior I get when I select a TextInput in a react-native-web project. This is not an issue I'm having in react-native projects, only in projects using react-native-web. It throws off my layout because it zooms in when I select a TextInput, but never zooms back out, even when I navigate to another screen in the same project. I end up with a screen that is wider than the phone screen and has a scroll bar on bottom.
Here are the solutions I've tried so far that haven't worked for me:
Set height and maxHeight of the TextInput to the same value, and set width and maxWidth of the TextInput to the same value. This seems to be completely ignored and make no difference.
Contain the TextInputs within a View of set height/width and/or contain the whole component or screen within a View of set height/width. This doesn't work because TextInputs won't stay inside the boundaries of the View if it expands.
Put margin and padding around the main View of the screen. This will just compensate for the behavior instead of stopping it. It's not really sufficient.
I've looked at documentation for aspect ratio but I don't think this will help since as far as I can tell aspect ratio is not changing.
Here is an example of code that I'm having this issue with:
<TextInput style={styles.inputsTwo}
accessible={this.state.access}
placeholder="Email"
clearButtonMode="always"
onChangeText={text => this.setState({email: text})}
value={this.state.email}
/>
And here's my styling:
inputsTwo: {
textDecorationLine: 'underline',
marginBottom: 10,
textAlign: 'left',
marginLeft: 30,
borderBottomColor: 'rgb(85, 99, 255)',
borderBottomWidth: 2,
fontFamily: 'HelveticaNeue',
height: 48,
maxHeight: 48,
width: 300,
maxWidth: 300
},
When I open up developer tools in a browser I see that this is what react-native-web has translated this into:
<div dir="auto" data-focusable="true" tabindex="0" class="rn-borderTopWidth-13yce4e rn-
borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-
deolkf rn-display-1471scf rn-fontStyle-o11vmf rn-fontVariant-ebii48 rn-fontWeight-gul640
rn-lineHeight-t9a87b rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-
marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-
paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
style="align-items: center; color: rgb(255, 0, 0); font-family: Helvetica-Bold; font-size:
15px; justify-content: center; text-align: center; -webkit-box-align: center; -webkit-box-
pack: center;"></div>
<input placeholder="Email" autocapitalize="sentences" autocomplete="on" autocorrect="on"
dir="auto" spellcheck="true" type="text" data-focusable="true" class="rn-MozAppearance-
97bpaa rn-WebkitAppearance-n1uzsy rn-backgroundColor-1niwhzg rn-borderTopColor-nqhrom rn-
borderRightColor-1878er4 rn-borderLeftColor-fpul1g rn-borderTopLeftRadius-ou6ah9 rn-
borderTopRightRadius-t12b5v rn-borderBottomRightRadius-zmljjp rn-borderBottomLeftRadius-
pm2fo rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-
borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-
borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-fontSize-1b43r93 rn-paddingTop-wk8lta rn-
paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-resize-1dz5y72"
value="" style="border-bottom-color: rgb(85, 99, 255); border-bottom-width: 2px; font-
family: HelveticaNeue; height: 48px; margin-bottom: 10px; margin-left: 30px; max-height:
48px; max-width: 300px; text-align: left; text-decoration: underline; width: 300px;">
Any suggestions are appreciated. Thanks,
This answer has worked for me:
https://stackoverflow.com/a/16255670/9147743
I have modified it for my case like so:
inputsTwo: {
textDecorationLine: 'underline',
marginBottom: 10,
textAlign: 'left',
marginLeft: 30,
marginRight: 30,
borderBottomColor: 'rgb(85, 99, 255)',
borderBottomWidth: 2,
fontFamily: 'HelveticaNeue',
height: 48,
fontSize: 16
},

Change the color of a TextInput placeholder with Styled Components in React Native

How do you set the color of TextInput its placeholder with Styled Components in React Native?
I tried the following without any luck:
1.
const Input = styled.TextInput`
border: 1px solid green;
display: block;
margin: 0 0 1em;
::placeholder {
color: green;
}
`
2.
const Input = styled.TextInput`
border: 1px solid green;
display: block;
margin: 0 0 1em;
&::placeholder {
color: green;
}
`
The best way to make this:
export const Input = styled.TextInput.attrs({
placeholderTextColor: "red"
})`
background-color: "#000";
`;
you can try:
export const NewTodo = styled.input`
padding: 16px 16px 16px 60px;
font-weight: 300;
font-size: 15px;
::placeholder,
::-webkit-input-placeholder {
color: red;
}
:-ms-input-placeholder {
color: red;
}
`;
How do I style an input placeholder with Styled Components?
Adding on to #Fernando Pascoal Gomes's answer, if you wish to access the theme object, consider passing a function to .attrs() that returns an object that the component inherits for its props.
For your case, TextInput accepts a placeholderTextColor prop, so it might look like this:
const Input = styled.TextInput.attrs((props) => ({
placeholderTextColor: props.theme.palette.placeholderColor,
}))`
background-color: #fff;
color: #000;
...
`
You cannot style the placeholder color with styled-components directly, but you can pass the placeholderTextColor property to your styled Textinput.
Example:
const Input = styled.TextInput`
border: 1px solid green;
display: block;
margin: 0 0 1em;
`
and then inside your render function:
<Input placeholder="hello" placeholderTextColor="green" />
Output:
Working example:
https://snack.expo.io/rybp-nKaE
To change the textinputs placeholder's text color user prperty
"placeholderTextColor"
eg
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({text})}
placeholder = 'Enter text'
placeholderTextColor = 'red'
value={this.state.text}
/>

How can I style a wrapper View without targeting the children?

Sorry I know this probably is a stupid question but I'm new to React Native and I can't seem to find a solution to this looking it up. Thank you in advance for your help.
I'm trying to give the HeadingWrapper a box-shadow but it seems to give the shadow to the inner contents. Here is my code that produces this result:
import React, { Component } from 'react';
import styled from 'styled-components';
import H1 from "../common/headings";
import LeftArrow from "../assets/LeftArrow.png";
const MainWrapper = styled.View`
box-shadow: 5px 5px 5px #000000;
`;
const HeadingWrapper = styled.View`
padding: 60px 10px 0 10px;
height: 60px;
flex: 1;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
`;
const ScrollArea = styled.ScrollView`
`;
const Img = styled.Image`
`;
class LandingPage extends Component {
render() {
return (
<MainWrapper style={styles.mainWrapper}>
<HeadingWrapper>
<Img style={styles.leftArrow} source={LeftArrow}/>
<H1>Chats</H1>
</HeadingWrapper>
<ScrollArea>
</ScrollArea>
</MainWrapper>
);
}
}
headings.js:
import styled from 'styled-components';
import React from "react";
const InnerH1 = styled.Text`
font-size: 34px;
font-weight: bold;
`;
const H1Container = styled.View`
flex: 1;
`;
const H1 = (props) => {
return (
<H1Container>
<InnerH1>{props.children}</InnerH1>
</H1Container>
)
};
export default H1;
Currently, the background color of HeadingWrapper is transparent as no background color is currently specified.
To create the 'box-shadow', all you need to do is give HeadingWrapper a background color of which is the same as your background.
Per the screenshot provided, the background color is white. Thus, you can use white as the background color for HeadingWrapper.
For inline style, you can use the below code:
<HeadingWrapper style={{ backgroundColor: 'white' }}>
<Img style={styles.leftArrow} source={LeftArrow}/>
<H1>Chats</H1>
</HeadingWrapper>

Set Leaflet map to height: 100% of container

Please how can we set the map div to be height: 100% of its container?
I have tried this within a bootstrap template content section, but all I get is height of 0px. Even Google-Dev tools shows #map height as 0px.
body {
padding: 0;
margin: 0;
}
html, body, #map {
height: 100%;
}
Set
#map{
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
and give its container position: relative.
The above answer didn't work for me, but this did:
body {
padding: 0;
margin: 0;
}
html, body, #map {
height: 100%;
width: 100%;
}
..from A full screen leaflet.js map
Leaflet needs an absolute height, and height: 100% only refers to the height of the parent element - if this isn't set, it will default to 0.
If your map is the only element in the body, use height: 100vh to match the height of the viewport (Example).
If your map is inside a container, set height: 100vh on the container (or other desired height) and height: 100% on the map element (Example).