Compare commits
19 Commits
develop
...
base-templ
| Author | SHA1 | Date | |
|---|---|---|---|
| a824795cc3 | |||
| 957ffd750d | |||
| 957a504397 | |||
| 70aeed88c1 | |||
| 6c8484420b | |||
| 08b383fdd4 | |||
| ceff5de958 | |||
| 22c8bb8ed1 | |||
| a082bfb4c0 | |||
| fa7308339b | |||
| 7052ade2ab | |||
| 5ad6a640e7 | |||
| 0d52bbd092 | |||
| be959db125 | |||
| 52a1d9fe4a | |||
| 9da6579cba | |||
| 2fb62006b7 | |||
| dfd489480e | |||
| bd1bbc284d |
934
firebase.md
934
firebase.md
@@ -10,18 +10,20 @@ List of errors: <https://firebase.google.com/docs/reference/js/firebase.auth.Aut
|
||||
You can catch the error and use if/else to capture the specific error.
|
||||
|
||||
```javascript
|
||||
firebase.auth().createUserWithEmailAndPassword(email, password)
|
||||
firebase
|
||||
.auth()
|
||||
.createUserWithEmailAndPassword(email, password)
|
||||
.catch(function(error) {
|
||||
// Handle Errors here.
|
||||
var errorCode = error.code;
|
||||
var errorMessage = error.message;
|
||||
if (errorCode == 'auth/weak-password') {
|
||||
alert('The password is too weak.');
|
||||
if (errorCode == "auth/weak-password") {
|
||||
alert("The password is too weak.");
|
||||
} else {
|
||||
alert(errorMessage);
|
||||
}
|
||||
console.log(error);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
Firebase User object:
|
||||
@@ -48,7 +50,6 @@ mention using `reauthenticateWithCredential`. This is only needed if using a 3rd
|
||||
|
||||
`yarn add @mdi/font -D`
|
||||
|
||||
|
||||
## Controlling layouts
|
||||
|
||||
### Spacing
|
||||
@@ -137,7 +138,6 @@ For example, to break on the medium viewport and have the second layout apply to
|
||||
|
||||
Here the second layout does not include the medium layout, hence the medium layout will apply to it.
|
||||
|
||||
|
||||
## App bar
|
||||
|
||||
### Gradient as a background colour
|
||||
@@ -157,8 +157,8 @@ If you want to apply a fade gradient colour on top of the image, you should use
|
||||
<v-img
|
||||
v-bind="props"
|
||||
gradient="to top right, rgba(100,115,201,.7), rgba(25,32,72,.7)"
|
||||
></v-img>
|
||||
</template>
|
||||
></v-img> </template
|
||||
></v-app-bar>
|
||||
```
|
||||
|
||||
If you want to just use a gradient (no img), then apply a solid colour image and then use a scoped slot with the gradient you want.
|
||||
@@ -201,8 +201,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
video: require("../assets/videos/optical.mp4")
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
@@ -220,8 +220,8 @@ You can find full props to customise the video:
|
||||
You can set a gradient to the image to improve visibility:
|
||||
|
||||
```javascript
|
||||
style=" height: 100vh;"
|
||||
overlay="linear-gradient(45deg,#2a4ae430,#fb949e6b)"
|
||||
style = " height: 100vh;";
|
||||
overlay = "linear-gradient(45deg,#2a4ae430,#fb949e6b)";
|
||||
```
|
||||
|
||||
## Dynamically hide app bar
|
||||
@@ -242,7 +242,7 @@ Use the Vuex store to determine when you want to hide the app bar:
|
||||
state.fullScreen = fullScreen;
|
||||
}
|
||||
},
|
||||
```
|
||||
```
|
||||
|
||||
and create the lifecycle actions in the component that houses the appbar:
|
||||
|
||||
@@ -258,11 +258,917 @@ and create the lifecycle actions in the component that houses the appbar:
|
||||
Then you can wrap the appbar in a `v-if`:
|
||||
|
||||
```html
|
||||
<v-app-bar
|
||||
<v-app-bar
|
||||
flat
|
||||
app
|
||||
class="hidden-sm-and-down"
|
||||
color="#EEEEEE"
|
||||
v-if="!this.$store.getters.fullScreen"
|
||||
>
|
||||
></v-app-bar>
|
||||
```
|
||||
|
||||
## Change default font colour
|
||||
|
||||
In `_variables.scss` create a variable with the colour you want:
|
||||
|
||||
```scss
|
||||
$mainColor: #323947;
|
||||
```
|
||||
|
||||
Then create a new class `fontColor` to apply to the router, and edit the default `theme--light` class for Vuetify to apply this colour:
|
||||
|
||||
```scss
|
||||
.theme--light.v-application,
|
||||
.fontColor,
|
||||
.theme--light.v-sheet {
|
||||
color: $mainColor !important;
|
||||
// color: red !important;
|
||||
}
|
||||
```
|
||||
|
||||
Then in `App.vue` apply the `fontColor` class to the `<v-app>`:
|
||||
|
||||
```html
|
||||
<v-app
|
||||
:style="{ background: $vuetify.theme.themes.light.background }"
|
||||
class="fontColor"
|
||||
></v-app>
|
||||
```
|
||||
|
||||
## Grids
|
||||
|
||||
<https://vuetifyjs.com/en/components/grids/#row-and-column-breakpoints>
|
||||
|
||||
In addition to using the flex classes you can use the grid system. The grid system allows you to create rows and columns and use props to control how the content should be displayed.
|
||||
|
||||
This playground demonstrates what `align` and `justify` can do:
|
||||
<https://vuetifyjs.com/en/components/grids/#playground>
|
||||
|
||||
The grid system applies to `<v-row>` and you can use the following props:
|
||||
|
||||
- `align` controls the y-axis. You have `start`, `center`, `end`, `baseline` and `stretch`.
|
||||
- `justify` controls the x-axis. You have `start`, `center`, `end`, `space-around` and `space-between`.
|
||||
|
||||
For `<v-col>` only `align-self` is available. To align content on a column, or any other element like a card, you should use the same classes as in the flex system. For example:
|
||||
|
||||
```html
|
||||
<v-col cols="5" align-self="start" class="d-flex justify-end pr-0"></v-col>
|
||||
```
|
||||
|
||||
## Container filling whole page
|
||||
|
||||
A container should be used whenever you want to use `<v-col>` and `<v-row>`. To make this container fill the whole page (and be able to use `align` props and flex classes) you should specify the following two props:
|
||||
|
||||
- `fill-height`
|
||||
- `fluid`.
|
||||
|
||||
To make content fill the width of the element it is in, you can use the following css:
|
||||
|
||||
```css
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
```
|
||||
|
||||
`width` sets the element to the percentage of its parent. So to have a textbox fill the width of the v-card element it is in you should set the `<v-card>`, `<v-form>` and `<v-text-field>` to `width: 100%;`. As long as the parent elements have 100%, you can set the text input to be a percentage of this, say 50%.
|
||||
|
||||
## Multi column layouts
|
||||
|
||||
An example can be found here:
|
||||
<https://git.panaetius.co.uk/web-development/savvy-firebase/src/branch/base-template/src/views/forms/LoginForm.vue>
|
||||
|
||||
You can make use of the above to create dynamic layouts.
|
||||
|
||||
One idea (for a login page) might be to use the following nested layout:
|
||||
|
||||
### Container
|
||||
|
||||
A `<v-container>` with `fill-height` and `fluid` props.
|
||||
|
||||
### Row
|
||||
|
||||
A `<v-row>`
|
||||
|
||||
### Columns
|
||||
|
||||
A `<v-col>` with `align-self="stretch"` and `class="d-flex flex-column justify-space-between"`.
|
||||
|
||||
`align-self=stretch` allows each child of the column to _stretch_ (<https://developer.mozilla.org/en-US/docs/Web/CSS/align-items)>.
|
||||
|
||||
`class="d-flex flex-column justify-space-between"` allows each child of the column to flex - with justify-space-between putting them equally apart top to bottom. It's used to equally space out the _rows_ inside this column. Even though we are not using `<v-row>`.
|
||||
|
||||
### Cards
|
||||
|
||||
A `<v-card>` with `class="d-flex align-end flex-column"`.
|
||||
|
||||
`class="d-flex align-end flex-column"` allows content inside the card to flex. The `align-end` means they will be on the right hand side and flex-column means they are flexing across columns.
|
||||
|
||||
To make text align right, you should use the `text-right` class:
|
||||
|
||||
`<p class="whiteText font-regular text-right mb-0">`
|
||||
|
||||
This is because although the `<p>` element will align to the right becasue of the class from the `<v-card>`, the text inside will align to the left.
|
||||
|
||||
We can add `color="rgb(0, 0, 0, 0)"` and `flat` props to the card - allowing it to seamlessly blend in with the background.
|
||||
|
||||
We can add mulitple cards to this layout in this column - and control how they are spaced with the props on the column.
|
||||
|
||||
We can add `<v-spacer>` and then add additional colums with the same props to add content in a column like manner.
|
||||
|
||||
Important!
|
||||
|
||||
If you want content to be aligned in a column with each item on a new line, then use:
|
||||
|
||||
```html
|
||||
<v-col cols="6" align-self="center" class="">
|
||||
<v-card color="rgb(0, 0, 0, 0)" flat class="d-flex align-center flex-column">
|
||||
<v-icon color="white" size="3em">mdi-account-circle</v-icon>
|
||||
<p class="mb-0 display-2">Login</p></v-card
|
||||
></v-col
|
||||
>
|
||||
```
|
||||
|
||||
## Helper classes
|
||||
|
||||
### Spacing
|
||||
|
||||
<https://vuetifyjs.com/en/styles/spacing/>
|
||||
|
||||
You can use classes like `ma-2` and `pd-3` to control margin/padding in directions for any component.
|
||||
|
||||
See the playground for a quick demonstration on what each one does:
|
||||
|
||||
<https://vuetifyjs.com/en/styles/spacing/#playground>
|
||||
|
||||
## Typography
|
||||
|
||||
There are quite a few helper classes available to control font sizes and styles.
|
||||
|
||||
<https://vuetifyjs.com/en/styles/typography/>
|
||||
|
||||
There are two types of styles: Typography Display Classes and Style and Weight Classes.
|
||||
|
||||
Examples include `.display-2` and `.font-weight-black`.
|
||||
|
||||
### Replace Vuetify default font with custom
|
||||
|
||||
Fonts needed to replace the Roboto default:
|
||||
|
||||
- Thin
|
||||
- Regular
|
||||
- Medium
|
||||
- Light
|
||||
- Condensed Light (Light)
|
||||
- Bold
|
||||
- Black
|
||||
- italic
|
||||
- Light italic
|
||||
- Medium italic
|
||||
- Bold italic
|
||||
|
||||
If font styles dont exist then substitute them with the closest type.
|
||||
|
||||
An example of a stylesheet replacing all of these with the Gilroy font is here:
|
||||
<https://git.panaetius.co.uk/web-development/savvy-firebase/src/branch/base-template/src/scss/_variables.scss>
|
||||
|
||||
## Custom colour theme
|
||||
|
||||
Creating a custom colour theme for Vuetify is straightforward.
|
||||
|
||||
<https://mycolor.space> is a good resource to generate palettes from a colour.
|
||||
|
||||
See <https://vuetifyjs.com/en/customization/theme/#customizing> for details on customising a theme.
|
||||
|
||||
### Editable colours
|
||||
|
||||
You change the `Vuetify` object in `vuetify.js`:
|
||||
|
||||
```javascript
|
||||
export default new Vuetify({
|
||||
icons: {
|
||||
iconfont: "mdi"
|
||||
},
|
||||
theme: {
|
||||
themes: {
|
||||
light: {
|
||||
primary: "#051937",
|
||||
secondary: "#374366",
|
||||
accent: "#d4a418",
|
||||
background: "#e8e8e8"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
These are the editable colours you can choose for Vuetify
|
||||
|
||||
```json
|
||||
{
|
||||
"primary": "#1976D2",
|
||||
"secondary": "#424242",
|
||||
"accent": "#82B1FF",
|
||||
"error": "#FF5252",
|
||||
"info": "#2196F3",
|
||||
"success": "#4CAF50",
|
||||
"warning": "#FFC107"
|
||||
}
|
||||
```
|
||||
|
||||
These follow the Material style of colours:
|
||||
<https://material.io/design/color/the-color-system.html#color-theme-creation>
|
||||
|
||||
The accent colour in Vuetify isn't really specified in the Material colour design - typically the secondary colour would be used as an accent colour - with shades of the primary used throughout the UI. However in some themes you may wish to use primary and secondary together, and have a seperate accent colour.
|
||||
|
||||
<https://material.io/design/color/the-color-system.html#color-theme-creation>
|
||||
|
||||
### Colour variants
|
||||
|
||||
Vuetify will automatically generate darken and lighten colour variants of the primary and secondary colours in the theme. If you want to control these manually you can do so following the instructions:
|
||||
<https://vuetifyjs.com/en/customization/theme/#custom-theme-variants>
|
||||
|
||||
The variants you can use are:
|
||||
|
||||
```json
|
||||
{
|
||||
"base": "string",
|
||||
"lighten5": "string",
|
||||
"lighten4": "string",
|
||||
"lighten3": "string",
|
||||
"lighten2": "string",
|
||||
"lighten1": "string",
|
||||
"darken1": "string",
|
||||
"darken2": "string",
|
||||
"darken3": "string",
|
||||
"darken4": "string"
|
||||
}
|
||||
```
|
||||
|
||||
You can apply these as a class to the object you want to darken/lighten.
|
||||
For example:
|
||||
`<v-btn color="primary" class="darken-2">Hello</v-btn>`
|
||||
|
||||
## Forms
|
||||
|
||||
### Changing the colour of form inputs
|
||||
|
||||
You can change the background colour, and the highlight colour (when clicked) with the following props:
|
||||
|
||||
```html
|
||||
<v-text-field
|
||||
v-model="username"
|
||||
background-color="rgb(100%, 100%, 100%, 10%)"
|
||||
color="rgb(100%, 100%, 100%, 10%)"
|
||||
class="white-placeholder"
|
||||
></v-text-field>
|
||||
```
|
||||
|
||||
To change the placeholder (text) colour you should use a custom class that overwrites this colour:
|
||||
|
||||
```css
|
||||
.white-placeholder ::v-deep input::placeholder {
|
||||
color: white !important;
|
||||
opacity: 1;
|
||||
}
|
||||
```
|
||||
|
||||
To change the label (text) colour:
|
||||
|
||||
```css
|
||||
.white-placeholder ::v-deep .v-label {
|
||||
color: white !important;
|
||||
opacity: 1;
|
||||
}
|
||||
```
|
||||
|
||||
To change the input colour (the text that is typed in by the user) we should use another custom class:
|
||||
|
||||
```css
|
||||
.white-placeholder ::v-deep input {
|
||||
color: white !important;
|
||||
opacity: 1;
|
||||
}
|
||||
```
|
||||
|
||||
We have to use `::v-deep` because we are in a scoped component. Any nested css classes/variables in a scoped component will have a random id attached to them (vue does this dynamically). The `::v-deep` will make sure that the nested css gets the formatting applied. See <https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors> for details.
|
||||
|
||||
## Overwriting sass/scss variables
|
||||
|
||||
<https://vuetifyjs.com/en/customization/sass-variables/>
|
||||
|
||||
Create a `_variables.scss` in `./src/scss`.
|
||||
|
||||
If Vuetify is installed through the Vuetify CLI then this `scss` file will be automatically bootstrapped into the App. If you want to write additional sheets then you should edit the `vue.config.js` file and add the following to `module.exports`:
|
||||
|
||||
```scss
|
||||
module.exports = {
|
||||
css: {
|
||||
loaderOptions: {
|
||||
scss: {
|
||||
prependData: `
|
||||
@import "@/scss/_variables.scss";
|
||||
`
|
||||
}
|
||||
}
|
||||
},
|
||||
transpileDependencies: ["vuetify"]
|
||||
};
|
||||
```
|
||||
|
||||
Overwriting `sass` variables is easy. You need to simply define them in this `_variables.scss` file and they will be used in the main app.
|
||||
|
||||
You can find a list of default variables <https://vuetifyjs.com/en/customization/sass-variables/>.
|
||||
|
||||
Or you can use the variables defined in the `sass` section of the components api documentation.
|
||||
|
||||
## Slots
|
||||
|
||||
When using slots in Vuetify find the slot name from the api documentation.
|
||||
|
||||
To use a slot, you should create a `<template>` inside the component and pass a `v-slot:$NAME` directive.
|
||||
|
||||
For example:
|
||||
`<template v-slot:prepend-inner>`
|
||||
|
||||
You can also use `#` as a keybinding for `v-slot`:
|
||||
`<template #prepend-inner>`
|
||||
|
||||
An example of passing a prepend icon to a `<v-text-field>`:
|
||||
|
||||
```html
|
||||
<template #prepend-inner>
|
||||
<v-icon>
|
||||
mdi-account-circle
|
||||
</v-icon>
|
||||
</template>
|
||||
```
|
||||
|
||||
Expects the v-img component. Scoped props should be applied with
|
||||
v-bind="props".
|
||||
|
||||
## Forms
|
||||
|
||||
Forms should be done dynamically - creating a `v-for` on a text field input. You should create all the props values in an object in `data`.
|
||||
|
||||
The `<v-form>` should specify a `v-model` prop, which should reference a boolean on whether the form is valid or not. You should set a `ref` prop, which is the name you will refer to the form.
|
||||
|
||||
```html
|
||||
<v-form
|
||||
v-model="valid"
|
||||
ref="form"
|
||||
class="pt-4 d-flex flex-column align-center full-width"
|
||||
></v-form>
|
||||
```
|
||||
|
||||
You would refer to this form with `this.$refs.form`.
|
||||
|
||||
```html
|
||||
<v-text-field
|
||||
v-for="field in formFields"
|
||||
:key="field.name"
|
||||
outlined
|
||||
rounded
|
||||
required
|
||||
:type="field.password ? 'password' : 'text'"
|
||||
background-color="rgb(100%, 100%, 100%, 10%)"
|
||||
color="rgb(100%, 100%, 100%, 20%)"
|
||||
class="white-placeholder full-width"
|
||||
v-model="field.value"
|
||||
:rules="field.rules"
|
||||
:placeholder="field.placeholder"
|
||||
:success="!!field.value"
|
||||
@click:append="field.showIconData = !field.showIconData"
|
||||
>
|
||||
<template #prepend-inner>
|
||||
<v-icon color="white" class="pr-3">
|
||||
{{ field.prependIcon }}
|
||||
</v-icon>
|
||||
</template>
|
||||
<template #append>
|
||||
<div class="innerIcon">
|
||||
<v-btn
|
||||
v-if="field.appendIconShow"
|
||||
flat
|
||||
icon
|
||||
text
|
||||
x-small
|
||||
@click="
|
||||
() => {
|
||||
field.showIconData = !field.showIconData;
|
||||
field.password = !field.password;
|
||||
}
|
||||
"
|
||||
>
|
||||
<v-icon color="white">
|
||||
{{ field.showIconData ? field.appendIconShow : field.appendIconHide }}
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
</v-text-field>
|
||||
```
|
||||
|
||||
Here we have created the text fields we want to render and we are looping over `formFields` to fill in the props and slots.
|
||||
|
||||
```javascript
|
||||
{
|
||||
valid: false,
|
||||
load: false,
|
||||
formFields: [
|
||||
{
|
||||
name: "Email",
|
||||
rules: [
|
||||
v => !!v || "You must enter an email address.",
|
||||
v => /.+@.+/.test(v) || "Email is not valid."
|
||||
],
|
||||
placeholder: "Email",
|
||||
successmessage: "Email is valid.",
|
||||
prependIcon: "mdi-at",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
name: "Password",
|
||||
rules: [
|
||||
v => !!v || "You must enter a password.",
|
||||
v => (v && v.length >= 8) || "Minimum 8 characters."
|
||||
],
|
||||
placeholder: "Password",
|
||||
successmessage: "Password is valid.",
|
||||
prependIcon: "mdi-lock",
|
||||
appendIconShow: "mdi-eye",
|
||||
appendIconHide: "mdi-eye-off",
|
||||
showIconData: false,
|
||||
value: "",
|
||||
password: true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This is the data object in the `<script>`. Here we define everything we need for the form, and specify all props needed for the form to work.
|
||||
|
||||
### Validation
|
||||
|
||||
Validating a form is done on the inputs that make up the form with the `rules` prop.
|
||||
This prop takes an array where each one of them must resolve to `true` in order for the form to be valid. We use arrow functions as the value of the input field is passed into the rules in order to check whether or not it is valud.
|
||||
|
||||
### Submitting and check
|
||||
|
||||
You should create a `<v-btn>` component and a method that will be called with `@click`.
|
||||
|
||||
```html
|
||||
<v-btn
|
||||
depressed
|
||||
large
|
||||
color="primary"
|
||||
class="lighten-3"
|
||||
:loading="load"
|
||||
@click="submit"
|
||||
>Submit</v-btn
|
||||
>
|
||||
```
|
||||
|
||||
```javascript
|
||||
async submit() {
|
||||
this.load = !this.load;
|
||||
console.log("loading");
|
||||
if (this.$refs.form.validate()) {
|
||||
console.log("Success");
|
||||
} else {
|
||||
console.log("Not valid");
|
||||
this.load = !this.load;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here we are checking the validity of the form, and enabling/disabling the loading prop based on whether or not the form is correct.
|
||||
|
||||
### Hints
|
||||
|
||||
The following is a codepen showing how you can dynamically populate a hint to show if the form is submitted with empty values. This can be useful if don't want to show an error message, but you still want the form to provide feedback on what to fill in.
|
||||
|
||||
<https://codepen.io/anon/pen/GeVQLG>
|
||||
|
||||
## Triangle backgrounds
|
||||
|
||||
### Designs
|
||||
|
||||
Dual image: <https://codepen.io/eddyerburgh/pen/EPYVVX>
|
||||
background-image: linear-gradient( 109.6deg, rgba(113,14,51,0.83) 15.2%, rgba(217,43,23,0.95) 96.8% );
|
||||
|
||||
## Animations
|
||||
|
||||
Vue Animations: <https://css-tricks.com/intro-to-vue-5-animations/>
|
||||
|
||||
### transitions
|
||||
|
||||
You can use Animista css animations with Vue's transition element:
|
||||
<https://serversideup.net/animista-css-with-vuejs-transitions/>
|
||||
|
||||
### Router Animations
|
||||
|
||||
<https://github.com/Orlandster/vue-page-transition>
|
||||
|
||||
`yarn add vue-page-transition`
|
||||
|
||||
```javascript
|
||||
import VuePageTransition from "vue-page-transition";
|
||||
Vue.use(VuePageTransition);
|
||||
```
|
||||
|
||||
You should wrap the `<router-view>`:
|
||||
|
||||
```html
|
||||
<vue-page-transition name="fade-in-right">
|
||||
<router-view />
|
||||
</vue-page-transition>
|
||||
```
|
||||
|
||||
A list of all transitions is here: <https://orlandster.github.io/vue-page-transition/#/>
|
||||
|
||||
### Animate on scroll
|
||||
|
||||
You can use vue transitions or you can use a helper library.
|
||||
|
||||
<https://michalsnik.github.io/aos/> can be used to quickly apply animations on scroll.
|
||||
|
||||
To use install with yarn:
|
||||
`yarn add aos@next`
|
||||
|
||||
Then, in `main.js` add:
|
||||
|
||||
```javascript
|
||||
import AOS from "aos";
|
||||
import "aos/dist/aos.css";
|
||||
```
|
||||
|
||||
And then add to the Vue instance the `AOS.init`:
|
||||
|
||||
```javascript
|
||||
new Vue({
|
||||
created() {
|
||||
AOS.init();
|
||||
},
|
||||
router,
|
||||
store,
|
||||
vuetify,
|
||||
render: h => h(App)
|
||||
}).$mount("#app");
|
||||
```
|
||||
|
||||
You can then in any component add any of the animations from the documentation:
|
||||
`data-aos="zoom-in"`
|
||||
|
||||
To use with nuxt install as a plugin:
|
||||
<https://www.yasminzy.com/nuxt/aos.html#steps>
|
||||
|
||||
#### Custom animations with AOS library
|
||||
|
||||
Custom Cubic-bezier easings: <https://cubic-bezier.com>
|
||||
Custom easings: <https://easings.net/en>
|
||||
|
||||
You can use custom animations with the AOS library. For example, we can use Animista.
|
||||
|
||||
The base template is:
|
||||
|
||||
```scss
|
||||
[data-aos="test-roll"] {
|
||||
// initial here
|
||||
transition-property: transform, opacity, filter;
|
||||
&.aos-animate {
|
||||
// final here
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In Animista you should copy the keyframes. Take the 0% content and put it as the intitial content in the above template.
|
||||
|
||||
The the 100% content and place it in the final content in the above template.
|
||||
|
||||
You need to update the `transition-property` with the elements you are animating from one state to another.
|
||||
|
||||
Using custom easings is straightforward.
|
||||
|
||||
Create the scss:
|
||||
|
||||
```scss
|
||||
[data-aos] {
|
||||
body[data-aos-easing="new-easing"] &,
|
||||
&[data-aos][data-aos-easing="new-easing"] {
|
||||
transition-timing-function: cubic-bezier(0.25, 1, 0.57, 0.55);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then apply in the html:
|
||||
|
||||
```html
|
||||
<v-card
|
||||
flat
|
||||
color="rgb(0, 0, 0, 0)"
|
||||
class="d-flex align-center justify-center flex-column pa-6"
|
||||
data-aos="test-roll"
|
||||
data-aos-duration="3000"
|
||||
data-aos-easing="new-easing"
|
||||
></v-card>
|
||||
```
|
||||
|
||||
## Alternative to fill-height
|
||||
|
||||
Using `fill-height` prop on a `<v-container>` can result in a bug where the width of the container doesn't reach all the way to the right hand side.
|
||||
|
||||
An alternative is to use `d-flex` on the `<v-container>`:
|
||||
|
||||
```html
|
||||
<v-container
|
||||
fluid
|
||||
class="d-flex align-center"
|
||||
style="height: 100vh;"
|
||||
></v-container>
|
||||
```
|
||||
|
||||
document usign align with viewport
|
||||
set a default which applies to all, set the one you want to apply for upwards
|
||||
|
||||
document setting a default cols (check this with triangle)
|
||||
|
||||
## Dynamic Mobile Layouts
|
||||
|
||||
### Cols
|
||||
|
||||
<!-- TODO Screenshot of firebase tutorial login page -->
|
||||
|
||||
<https://git.panaetius.co.uk/web-development/savvy-firebase/src/branch/base-template/src/views/forms/LoginForm.vue>
|
||||
|
||||
You can control how items are rendered based on the viewport width. For example, you can have a page appear across 2 columns on desktop, but display a single column on mobile : <http://localhost:8080/triangle>
|
||||
|
||||
One way is to use the the viewport cols props for `<v-col>`:
|
||||
|
||||
```html
|
||||
<v-col
|
||||
sm="6"
|
||||
cols="12"
|
||||
align-self="stretch"
|
||||
class="d-flex justify-sm-end justify-center pb-10 pb-sm-0 pr-sm-10"
|
||||
></v-col>
|
||||
```
|
||||
|
||||
This will set a default of 12, and then use 6 on sm and anything above it.
|
||||
|
||||
You can find all props for the dynamic cols in <https://vuetifyjs.com/en/components/grids/#api>
|
||||
|
||||
If you set a row to use more than 12 columns, it will overfill on to the next line.
|
||||
|
||||
<!-- ? should this be merged with the previous section on mobile layouts -->
|
||||
|
||||
Using the cards to create dynamic rows filling the space in each column, you can go even further and control how this should render on different viewports.
|
||||
|
||||
For example, if we wanted to center content on a mobile, but have it align to the right on larger screens we can do the following:
|
||||
|
||||
```html
|
||||
<div
|
||||
class="d-flex flex-column align-sm-end align-center justify-center"
|
||||
:class="alignOnViewport"
|
||||
>
|
||||
```
|
||||
|
||||
Here we are using `align-center`. This will set the content to center itself by default. We can then use `align-sm-end` to align the content to the right on anything sm and above. Combinations of these can be used to create dynamic and fluid layouts for all devices.
|
||||
|
||||
You can also use dynamically created classes to apply css to the content depending on the viewport.
|
||||
|
||||
<!-- ! create the trilium note link here -->
|
||||
|
||||
## CSS Spacing
|
||||
|
||||
<https://vuetifyjs.com/en/styles/spacing/>
|
||||
|
||||
You can use the helper classes `pa-10` to control padding/margins.
|
||||
|
||||
You can also viewport widths in these too:
|
||||
`pb-xs-10 pr-sm-10`
|
||||
|
||||
When wanting to use a default value and only apply another one on a certain viewport:
|
||||
|
||||
`class="d-flex justify-sm-end justify-center pb-10 pb-sm-0 pr-sm-10"`
|
||||
|
||||
This will set a padding on the bottom of 10 for xs and then 0 for anything higher.
|
||||
|
||||
## Dynamically Apply Classes
|
||||
|
||||
<https://michaelnthiessen.com/dynamically-add-class-name/>
|
||||
|
||||
### Apply classes based on viewport
|
||||
|
||||
You can use the breakpoint variables:
|
||||
<https://vuetifyjs.com/en/customization/breakpoints/#breakpoint-service-object>
|
||||
|
||||
In javascript to determine what the breakpoint/size/dimension etc is. You should prepend:
|
||||
`$vuetify.breakpoint`
|
||||
before each breakpoint service object.
|
||||
|
||||
You can also use a neat javascript check with `switch` and `case` to create a computed variable:
|
||||
|
||||
```javascript
|
||||
computed: {
|
||||
imageHeight () {
|
||||
switch (this.$vuetify.breakpoint.name) {
|
||||
case 'xs': return '220px'
|
||||
case 'sm': return '400px'
|
||||
case 'md': return '500px'
|
||||
case 'lg': return '600px'
|
||||
case 'xl': return '800px'
|
||||
}
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, you can create a normal computed variable and reference it in your props:
|
||||
|
||||
```javascript
|
||||
computed: {
|
||||
isXSmall() {
|
||||
return this.$vuetify.breakpoint.xsOnly;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can then dynamically set classes with the `:class` prop:
|
||||
|
||||
```html
|
||||
<div
|
||||
class="d-flex flex-column align-sm-end align-center justify-center"
|
||||
:class="[isXSmall ? 'text-align-center' : 'text-align-right']"
|
||||
></div>
|
||||
```
|
||||
|
||||
You can use both `class` and the prop `:class` together. You can use different methods to do this, here we used an array, but you can also use a javascript object.
|
||||
<https://michaelnthiessen.com/dynamically-add-class-name/>
|
||||
|
||||
A cleaner way to do this is to use computed properties exclusively, either returning a single value, or an array as above:
|
||||
|
||||
```javascript
|
||||
computed: {
|
||||
alignOnViewport() {
|
||||
return this.$vuetify.breakpoint.xsOnly
|
||||
? "text-align-center"
|
||||
: "text-align-right";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Using the `:class` prop:
|
||||
|
||||
```html
|
||||
<div
|
||||
class="d-flex flex-column align-sm-end align-center justify-center"
|
||||
:class="alignOnViewport"
|
||||
></div>
|
||||
```
|
||||
|
||||
## SVG
|
||||
|
||||
### Viewbox
|
||||
|
||||
<https://css-tricks.com/scale-svg/>
|
||||
|
||||
Viewbox is an attribute on the `<svg>` element and has 4 components: x, y, height, width.
|
||||
|
||||
The x and y set the coordinate system to use for the top left corner of the viewport. Simple scaling can be done by setting these to 0,0, but you could set them to something else (like central) to make drawing circles using radius easier, or for easier transforming/rotating.
|
||||
|
||||
Take for example `viewBox="-50 -50 100 100"` - this means the top left corner has coordinates -50,-50, so the bottom right corner has coordinates 50,50. Drawing a circle centered around 0,0 with radius 50 it will fill the screen.
|
||||
|
||||
Setting a viewbox allows you to set the box that the svg element should draw in. This will allow you to then control the width and height to scale the element properly.
|
||||
|
||||
## Triangle banners
|
||||
|
||||
### Method 1 - position: absolute
|
||||
|
||||
See <https://git.panaetius.co.uk/web-development/savvy-firebase/src/branch/base-template/src/views/Triangle.vue> for an example.
|
||||
|
||||
You should create a triangle banner css class:
|
||||
|
||||
```scss
|
||||
.newtriangle {
|
||||
width: 105vw;
|
||||
height: 50vh;
|
||||
background-image: radial-gradient(
|
||||
circle farthest-corner at 7.5% 54.1%,
|
||||
rgba(0, 0, 0, 1) 0%,
|
||||
rgba(39, 0, 89, 1) 74.9%
|
||||
);
|
||||
-webkit-clip-path: polygon(0 0, 100% 35%, 100% 65%, 0% 100%);
|
||||
clip-path: polygon(0 0, 100% 35%, 100% 65%, 0% 100%);
|
||||
}
|
||||
```
|
||||
|
||||
Then you should create a `<v-row>` with this class. This row should also set `position: absolute; z-index: 1;` in the style (or add this to the triangle class).
|
||||
|
||||
```html
|
||||
<v-row class="d-flex newtriangle" style="position: absolute; z-index: 1;">
|
||||
<v-col
|
||||
class="d-flex align-center pt-0 ml-8"
|
||||
style="position: relative; z-index: 10;"
|
||||
>
|
||||
<v-card flat color="rgb(0, 0, 0, 0)">
|
||||
<h1 class="display" style="position: relative;">
|
||||
Welcome to Savvy Firebox Tutorial
|
||||
</h1>
|
||||
<v-btn
|
||||
x-large
|
||||
color="primary"
|
||||
style="position: relative; z-index: 10;"
|
||||
class="lighten-1"
|
||||
>Click Here</v-btn
|
||||
>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
```
|
||||
|
||||
Because the element has been set to position absolute, any content after this without absolute positioning will be on top of this element. You should create a blank row with `position: relative;` with a height matching the triangle banner above it. This will create blank space on top of the banner.
|
||||
|
||||
```html
|
||||
<v-row class="d-flex" style="position: relative; height: 50vh;"> </v-row>
|
||||
```
|
||||
|
||||
Any other content then be placed after this like normal.
|
||||
|
||||
### Method 2 - Without position: absolute
|
||||
|
||||
See <https://git.panaetius.co.uk/web-development/savvy-firebase/src/branch/base-template/src/views/Backgrounds.vue> for an example.
|
||||
|
||||
Add the css class for the banner:
|
||||
|
||||
```css
|
||||
.newtriangle {
|
||||
width: 105vw;
|
||||
height: 50vh;
|
||||
background-image: radial-gradient(
|
||||
circle farthest-corner at 7.5% 54.1%,
|
||||
rgba(0, 0, 0, 1) 0%,
|
||||
rgba(39, 0, 89, 1) 74.9%
|
||||
);
|
||||
-webkit-clip-path: polygon(0 0, 100% 35%, 100% 65%, 0% 100%);
|
||||
clip-path: polygon(0 0, 100% 35%, 100% 65%, 0% 100%);
|
||||
}
|
||||
```
|
||||
|
||||
Apply this class to a `<v-content>` and add any content to go inside it:
|
||||
|
||||
```html
|
||||
<v-container fluid class="newtriangle">
|
||||
<v-row class="fill-height d-flex align-center">
|
||||
<v-col class="">
|
||||
<h1 class="display-2 white--text">
|
||||
CSS polygon background with clip-path.
|
||||
</h1>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
```
|
||||
|
||||
## Fullscreen backgrounds
|
||||
|
||||
You can use svg images as a fullsize background. These images can be obtained from envano web templates - use Pixelmator Pro and its extraction tools to extract the svg elements, upscale and export for web.
|
||||
|
||||
Create a `<v-img>` with the src as the svg image.
|
||||
|
||||
```html
|
||||
<v-img
|
||||
src="../assets/images/background.svg"
|
||||
:height="this.currentHeight - 64"
|
||||
width="auto"
|
||||
contain="false"
|
||||
position="bottom 0px right 0px"
|
||||
></v-img>
|
||||
```
|
||||
|
||||
Any content to go in the page should go inside the `<v-img>` tags.
|
||||
|
||||
The width should be auto - it will be set by the height.
|
||||
|
||||
The prop `contain` should be used to ensure the image fits the full height properly and isn't cropped.
|
||||
|
||||
To align the image in the bottom right, set the position prop:
|
||||
|
||||
```html
|
||||
position="bottom 0px right 0px"
|
||||
```
|
||||
|
||||
If you are using a appbar, you should dynamically get the viewport height, and substract the height of the appbar. The default height is `64px` - use the documentation to find the heights if using dense or extended props.
|
||||
|
||||
You should add a computed property that returns the current viewport height:
|
||||
|
||||
```javascript
|
||||
computed: {
|
||||
currentHeight() {
|
||||
return window.innerHeight
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then, in the height of the `<v-img>` you should set a dynamic prop that sets the height of the image to this computed property minus the height of the appbar.
|
||||
|
||||
```html
|
||||
:height="this.currentHeight - 64"
|
||||
```
|
||||
|
||||
@@ -8,11 +8,14 @@
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"aos": "^3.0.0-beta.6",
|
||||
"core-js": "^3.6.4",
|
||||
"mime-types": "^2.1.26",
|
||||
"vue": "^2.6.11",
|
||||
"vue-page-transition": "^0.2.2",
|
||||
"vue-responsive-video-background-player": "^1.0.8",
|
||||
"vue-router": "^3.1.5",
|
||||
"vue-stripe-menu": "^1.2.8",
|
||||
"vuetify": "^2.2.11",
|
||||
"vuex": "^3.1.2"
|
||||
},
|
||||
|
||||
45
src/App.vue
45
src/App.vue
@@ -1,14 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-app
|
||||
:style="{ background: $vuetify.theme.themes.light.background }"
|
||||
class="fontColor"
|
||||
>
|
||||
<v-app :style="{ background: $vuetify.theme.themes.light.background }">
|
||||
<v-content>
|
||||
<Appbar></Appbar>
|
||||
<transition name="slide">
|
||||
<vue-page-transition name="fade">
|
||||
<router-view></router-view>
|
||||
</transition>
|
||||
</vue-page-transition>
|
||||
<v-row> </v-row>
|
||||
</v-content>
|
||||
</v-app>
|
||||
@@ -17,26 +14,44 @@
|
||||
|
||||
<script>
|
||||
import Appbar from "@/components/Appbar";
|
||||
import Welcome from "./views/stripe-appbar/Welcome";
|
||||
import WelcomeSecondary from "./views/stripe-appbar/WelcomeSecondary";
|
||||
import Random from "./views/stripe-appbar/Random"
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
|
||||
components: { Appbar },
|
||||
|
||||
data: () => ({
|
||||
video: require("./assets/videos/optical.mp4")
|
||||
})
|
||||
data() {
|
||||
return {
|
||||
menu: [
|
||||
{
|
||||
title: "Welcome",
|
||||
dropdown: "welcome",
|
||||
content: Welcome,
|
||||
secondary: WelcomeSecondary,
|
||||
element: "span"
|
||||
},
|
||||
{
|
||||
title: "Random",
|
||||
dropdown: "random",
|
||||
content: Random
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
#app {
|
||||
font-family: $gilroy, sans-serif, Arial, Helvetica;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.fontColor, .theme--light.v-application, .theme--light.v-sheet {
|
||||
// color: $mainColor !important;
|
||||
color: $mainColor !important;
|
||||
.content {
|
||||
padding: 20px;
|
||||
}
|
||||
.content--secondary {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
BIN
src/assets/fonts/Gilroy-Black.otf
Normal file
BIN
src/assets/fonts/Gilroy-Black.otf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Gilroy-BoldItalic.otf
Normal file
BIN
src/assets/fonts/Gilroy-BoldItalic.otf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Gilroy-Light.otf
Normal file
BIN
src/assets/fonts/Gilroy-Light.otf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Gilroy-LightItalic.otf
Normal file
BIN
src/assets/fonts/Gilroy-LightItalic.otf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Gilroy-Medium.otf
Normal file
BIN
src/assets/fonts/Gilroy-Medium.otf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Gilroy-MediumItalic.otf
Normal file
BIN
src/assets/fonts/Gilroy-MediumItalic.otf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Gilroy-RegularItalic.otf
Normal file
BIN
src/assets/fonts/Gilroy-RegularItalic.otf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Gilroy-Thin.otf
Normal file
BIN
src/assets/fonts/Gilroy-Thin.otf
Normal file
Binary file not shown.
BIN
src/assets/images/11-Casino chip.png
Normal file
BIN
src/assets/images/11-Casino chip.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
BIN
src/assets/images/12-Casino chip.png
Normal file
BIN
src/assets/images/12-Casino chip.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
9
src/assets/images/background.svg
Normal file
9
src/assets/images/background.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 297 KiB |
BIN
src/assets/images/newbackground.png
Normal file
BIN
src/assets/images/newbackground.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 394 KiB |
1123
src/assets/images/pipebackground.svg
Normal file
1123
src/assets/images/pipebackground.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 275 KiB |
1127
src/assets/images/pipebackground_1.svg
Normal file
1127
src/assets/images/pipebackground_1.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 262 KiB |
@@ -1,59 +1,121 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <v-app-bar flat color="indigo" app class="hidden-md-and-up">
|
||||
<v-row>
|
||||
<v-col cols="8" class="d-flex justify-start">
|
||||
<v-toolbar-title>
|
||||
Savvy Firebase
|
||||
</v-toolbar-title>
|
||||
</v-col>
|
||||
<v-col cols="4" class="d-flex justify-end">
|
||||
<v-btn color="white">
|
||||
Sign In
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-app-bar> -->
|
||||
<!-- <v-app-bar flat app class="hidden-sm-and-down" color="#EEEEEE"> -->
|
||||
<v-app-bar
|
||||
flat
|
||||
app
|
||||
class="hidden-sm-and-down"
|
||||
color="#EEEEEE"
|
||||
hide-on-scroll
|
||||
color="rgba(93.3%, 93.3%, 93.3%, 0.5)"
|
||||
v-if="!this.$store.getters.fullScreen"
|
||||
style="z-index: 15;"
|
||||
width="100%"
|
||||
>
|
||||
<v-row>
|
||||
<v-col cols="2"></v-col>
|
||||
<v-col cols="4" class="d-flex justify-start">
|
||||
<v-toolbar-title class="appTitle">
|
||||
Savvy Firebase Tutorial
|
||||
<v-row class="hidden-sm-and-down">
|
||||
<v-spacer></v-spacer>
|
||||
<v-col
|
||||
cols="4"
|
||||
class="d-flex justify-start align-center align-content-center"
|
||||
>
|
||||
<router-link :to="{ name: 'Home' }" class="routerLink">
|
||||
<v-toolbar-title class="title">
|
||||
<p class="mb-0">Savvy Firebase Tutorial</p>
|
||||
</v-toolbar-title>
|
||||
</v-col>
|
||||
<v-col cols="4" class="d-flex justify-end align-self-center">
|
||||
<router-link :to="{ name: 'Login' }" class="routerLink">
|
||||
<span class="mr-3">Sign In</span>
|
||||
</router-link>
|
||||
<span class="mr-3">Register</span>
|
||||
</v-col>
|
||||
<v-col cols="2"></v-col>
|
||||
<v-col cols="4" class="d-flex justify-end align-center">
|
||||
<vsm-menu
|
||||
ref="header"
|
||||
:menu="menu"
|
||||
:screen-offset="25"
|
||||
:base-width="380"
|
||||
:base-height="400"
|
||||
>
|
||||
<template #default="data">
|
||||
<component :is="data.item.content" class="content" />
|
||||
<component :is="data.item.secondary" class="content--secondary" />
|
||||
</template>
|
||||
<template #title="menu" class="ma-0 pa-0">
|
||||
<router-link
|
||||
:to="menu.item.routerLink"
|
||||
v-if="menu.item.routerLink"
|
||||
style="padding-bottom: -20px;"
|
||||
>
|
||||
<p class="ma-0 pa-0 underline routerLink">
|
||||
{{ menu.item.title }}
|
||||
</p>
|
||||
</router-link>
|
||||
</template>
|
||||
</vsm-menu>
|
||||
</v-col>
|
||||
<v-spacer></v-spacer>
|
||||
</v-row>
|
||||
<v-row class="hidden-md-and-up">
|
||||
<v-app-bar-nav-icon class="d-flex"></v-app-bar-nav-icon>
|
||||
<v-spacer></v-spacer>
|
||||
<v-toolbar-title class="title d-flex justify-end align-center">
|
||||
<p class="mb-0">Savvy Firebase Tutorial</p>
|
||||
</v-toolbar-title>
|
||||
</v-row>
|
||||
</v-app-bar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Welcome from "../views/stripe-appbar/Welcome";
|
||||
import WelcomeSecondary from "../views/stripe-appbar/WelcomeSecondary";
|
||||
import Random from "../views/stripe-appbar/Random";
|
||||
|
||||
export default {
|
||||
name: "Appbar"
|
||||
name: "Appbar",
|
||||
data() {
|
||||
return {
|
||||
menu: [
|
||||
{
|
||||
title: "Welcome",
|
||||
dropdown: "welcome",
|
||||
content: Welcome,
|
||||
secondary: WelcomeSecondary
|
||||
},
|
||||
{
|
||||
title: "Random",
|
||||
dropdown: "random",
|
||||
content: Random
|
||||
},
|
||||
{
|
||||
title: "Triangle",
|
||||
routerLink: { name: "Triangle" }
|
||||
},
|
||||
{
|
||||
title: "Playground",
|
||||
routerLink: { name: "Playground" }
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.appTitle {
|
||||
font-family: $gilroy-bold;
|
||||
}
|
||||
|
||||
.routerLink {
|
||||
text-decoration: none;
|
||||
color: $mainColor
|
||||
color: $mainColor;
|
||||
}
|
||||
.underline {
|
||||
position: relative;
|
||||
}
|
||||
.underline::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 0.1em;
|
||||
top: 100%;
|
||||
background: currentColor;
|
||||
z-index: -1;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleX(0);
|
||||
transition: transform 0.5s cubic-bezier(0.95, 0.05, 0.795, 0.035) 50ms;
|
||||
}
|
||||
.underline:hover::after {
|
||||
transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
|
||||
transform: scaleX(1);
|
||||
}
|
||||
</style>
|
||||
|
||||
86
src/components/AppbarOld.vue
Normal file
86
src/components/AppbarOld.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-app-bar
|
||||
flat
|
||||
app
|
||||
hide-on-scroll
|
||||
color="rgba(93.3%, 93.3%, 93.3%, 0.5)"
|
||||
v-if="!this.$store.getters.fullScreen"
|
||||
>
|
||||
<v-row>
|
||||
<v-spacer></v-spacer>
|
||||
<v-col cols="4" class="d-flex justify-start align-content-center">
|
||||
<router-link :to="{ name: 'Home' }" class="routerLink">
|
||||
<v-toolbar-title class="title">
|
||||
<p class="mb-0">Savvy Firebase Tutorial</p>
|
||||
</v-toolbar-title>
|
||||
</router-link>
|
||||
</v-col>
|
||||
<v-col cols="4" class="d-flex justify-end align-self-center">
|
||||
<router-link
|
||||
:to="{ name: 'Playground' }"
|
||||
class="routerLink ma-0 pr-2"
|
||||
>
|
||||
<p class="mb-0 underline">
|
||||
Playground
|
||||
</p>
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="{ name: 'Backgrounds' }"
|
||||
class="routerLink ma-0 pr-2"
|
||||
>
|
||||
<p class="mb-0 underline">
|
||||
Backgrounds
|
||||
</p>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'Triangle' }" class="routerLink ma-0 pr-2">
|
||||
<p class="mb-0 underline">
|
||||
Triangle
|
||||
</p>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'Login' }" class="routerLink ma-0 pr-2">
|
||||
<p class=" mb-0 underline">
|
||||
Sign In
|
||||
</p>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'Login' }" class="routerLink ma-0">
|
||||
<p class="mb-0 underline">Register</p>
|
||||
</router-link>
|
||||
</v-col>
|
||||
<v-spacer></v-spacer>
|
||||
</v-row>
|
||||
</v-app-bar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Appbar"
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.routerLink {
|
||||
text-decoration: none;
|
||||
color: $mainColor;
|
||||
}
|
||||
.underline {
|
||||
position: relative;
|
||||
}
|
||||
.underline::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 0.1em;
|
||||
top: 100%;
|
||||
background: currentColor;
|
||||
z-index: -1;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleX(0);
|
||||
transition: transform 0.5s cubic-bezier(0.95, 0.05, 0.795, 0.035) 50ms;
|
||||
}
|
||||
.underline:hover::after {
|
||||
transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
|
||||
transform: scaleX(1);
|
||||
}
|
||||
</style>
|
||||
@@ -1,151 +0,0 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-row class="text-center">
|
||||
<v-col cols="12">
|
||||
<v-img
|
||||
:src="require('../assets/logo.svg')"
|
||||
class="my-3"
|
||||
contain
|
||||
height="200"
|
||||
/>
|
||||
</v-col>
|
||||
|
||||
<v-col class="mb-4">
|
||||
<h1 class="display-2 font-weight-bold mb-3">
|
||||
Welcome to Vuetify
|
||||
</h1>
|
||||
|
||||
<p class="subheading font-weight-regular">
|
||||
For help and collaboration with other Vuetify developers,
|
||||
<br>please join our online
|
||||
<a
|
||||
href="https://community.vuetifyjs.com"
|
||||
target="_blank"
|
||||
>Discord Community</a>
|
||||
</p>
|
||||
</v-col>
|
||||
|
||||
<v-col
|
||||
class="mb-5"
|
||||
cols="12"
|
||||
>
|
||||
<h2 class="headline font-weight-bold mb-3">
|
||||
What's next?
|
||||
</h2>
|
||||
|
||||
<v-row justify="center">
|
||||
<a
|
||||
v-for="(next, i) in whatsNext"
|
||||
:key="i"
|
||||
:href="next.href"
|
||||
class="subheading mx-3"
|
||||
target="_blank"
|
||||
>
|
||||
{{ next.text }}
|
||||
</a>
|
||||
</v-row>
|
||||
</v-col>
|
||||
|
||||
<v-col
|
||||
class="mb-5"
|
||||
cols="12"
|
||||
>
|
||||
<h2 class="headline font-weight-bold mb-3">
|
||||
Important Links
|
||||
</h2>
|
||||
|
||||
<v-row justify="center">
|
||||
<a
|
||||
v-for="(link, i) in importantLinks"
|
||||
:key="i"
|
||||
:href="link.href"
|
||||
class="subheading mx-3"
|
||||
target="_blank"
|
||||
>
|
||||
{{ link.text }}
|
||||
</a>
|
||||
</v-row>
|
||||
</v-col>
|
||||
|
||||
<v-col
|
||||
class="mb-5"
|
||||
cols="12"
|
||||
>
|
||||
<h2 class="headline font-weight-bold mb-3">
|
||||
Ecosystem
|
||||
</h2>
|
||||
|
||||
<v-row justify="center">
|
||||
<a
|
||||
v-for="(eco, i) in ecosystem"
|
||||
:key="i"
|
||||
:href="eco.href"
|
||||
class="subheading mx-3"
|
||||
target="_blank"
|
||||
>
|
||||
{{ eco.text }}
|
||||
</a>
|
||||
</v-row>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
|
||||
data: () => ({
|
||||
ecosystem: [
|
||||
{
|
||||
text: 'vuetify-loader',
|
||||
href: 'https://github.com/vuetifyjs/vuetify-loader',
|
||||
},
|
||||
{
|
||||
text: 'github',
|
||||
href: 'https://github.com/vuetifyjs/vuetify',
|
||||
},
|
||||
{
|
||||
text: 'awesome-vuetify',
|
||||
href: 'https://github.com/vuetifyjs/awesome-vuetify',
|
||||
},
|
||||
],
|
||||
importantLinks: [
|
||||
{
|
||||
text: 'Documentation',
|
||||
href: 'https://vuetifyjs.com',
|
||||
},
|
||||
{
|
||||
text: 'Chat',
|
||||
href: 'https://community.vuetifyjs.com',
|
||||
},
|
||||
{
|
||||
text: 'Made with Vuetify',
|
||||
href: 'https://madewithvuejs.com/vuetify',
|
||||
},
|
||||
{
|
||||
text: 'Twitter',
|
||||
href: 'https://twitter.com/vuetifyjs',
|
||||
},
|
||||
{
|
||||
text: 'Articles',
|
||||
href: 'https://medium.com/vuetify',
|
||||
},
|
||||
],
|
||||
whatsNext: [
|
||||
{
|
||||
text: 'Explore components',
|
||||
href: 'https://vuetifyjs.com/components/api-explorer',
|
||||
},
|
||||
{
|
||||
text: 'Select a layout',
|
||||
href: 'https://vuetifyjs.com/layout/pre-defined',
|
||||
},
|
||||
{
|
||||
text: 'Frequently Asked Questions',
|
||||
href: 'https://vuetifyjs.com/getting-started/frequently-asked-questions',
|
||||
},
|
||||
],
|
||||
}),
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
<template>
|
||||
<video-background
|
||||
:src="video"
|
||||
style=" height: 100vh;"
|
||||
overlay="linear-gradient(45deg,#2a4ae430,#fb949e6b)"
|
||||
style="height: 100vh;"
|
||||
overlay="linear-gradient(to right, #05193799, #10183d90, #1e164090, #2b114290, #39094190)"
|
||||
>
|
||||
<LoginForm class=""></LoginForm>
|
||||
</video-background>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LoginForm from "../views/forms/LoginForm";
|
||||
export default {
|
||||
components: {
|
||||
LoginForm,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
video: require("../assets/videos/optical.mp4")
|
||||
|
||||
15
src/components/StripeAppbar.vue
Normal file
15
src/components/StripeAppbar.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
16
src/main.js
16
src/main.js
@@ -3,12 +3,28 @@ import App from "./App.vue";
|
||||
import router from "./router";
|
||||
import store from "./store";
|
||||
import vuetify from "./plugins/vuetify";
|
||||
// Video Background
|
||||
import VideoBackground from "vue-responsive-video-background-player";
|
||||
// Page Transitions
|
||||
import VuePageTransition from "vue-page-transition";
|
||||
// Animations
|
||||
import AOS from "aos";
|
||||
import "aos/dist/aos.css";
|
||||
// Stripe Appbar Menu
|
||||
import VueStripeMenu from "vue-stripe-menu";
|
||||
// import "vue-stripe-menu/dist/vue-stripe-menu.css";
|
||||
import "./scss/appbar.scss"
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
Vue.component("video-background", VideoBackground);
|
||||
|
||||
Vue.use(VuePageTransition);
|
||||
Vue.use(VueStripeMenu);
|
||||
|
||||
new Vue({
|
||||
created() {
|
||||
AOS.init();
|
||||
},
|
||||
router,
|
||||
store,
|
||||
vuetify,
|
||||
|
||||
@@ -11,7 +11,10 @@ export default new Vuetify({
|
||||
theme: {
|
||||
themes: {
|
||||
light: {
|
||||
background: "#fff"
|
||||
primary: "#051937",
|
||||
secondary: "#374366",
|
||||
accent: "#d4a418",
|
||||
background: "#e8e8e8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,30 @@ const routes = [
|
||||
name: "Login",
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "login" */ "../components/LoginFull.vue")
|
||||
},
|
||||
{
|
||||
path: "/hello",
|
||||
name: "Hello",
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "hello" */ "../components/HelloWorld.vue")
|
||||
},
|
||||
{
|
||||
path: "/triangle",
|
||||
name: "Triangle",
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "triangle" */ "../views/Triangle.vue")
|
||||
},
|
||||
{
|
||||
path: "/backgrounds",
|
||||
name: "Backgrounds",
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "backgrounds" */ "../views/Backgrounds.vue")
|
||||
},
|
||||
{
|
||||
path: "/playground",
|
||||
name: "Playground",
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "playground" */ "../views/Playground.vue")
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -1,27 +1,143 @@
|
||||
// Import custom fonts
|
||||
|
||||
@font-face {
|
||||
font-family: "Gilroy";
|
||||
font-family: "Gilroy-Thin";
|
||||
src: url("~@/assets/fonts/Gilroy-Thin.otf") format("opentype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Gilroy-Regular";
|
||||
src: url("~@/assets/fonts/Gilroy-Regular.otf") format("opentype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Gilroy-bold";
|
||||
font-family: "Gilroy-Medium";
|
||||
src: url("~@/assets/fonts/Gilroy-Medium.otf") format("opentype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Gilroy-Light";
|
||||
src: url("~@/assets/fonts/Gilroy-Light.otf") format("opentype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Gilroy-Condensed-Light";
|
||||
src: url("~@/assets/fonts/Gilroy-Light.otf") format("opentype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Gilroy-Bold";
|
||||
src: url("~@/assets/fonts/Gilroy-Bold.otf") format("opentype");
|
||||
}
|
||||
|
||||
$gilroy: "Gilroy", sans-serif !default;
|
||||
$gilroy-bold: "Gilroy-bold", sans-serif !default;
|
||||
@font-face {
|
||||
font-family: "Gilroy-Black";
|
||||
src: url("~@/assets/fonts/Gilroy-Black.otf") format("opentype");
|
||||
}
|
||||
|
||||
@import "../../node_modules/vuetify/src/styles/styles.sass";
|
||||
$body-font-family: $gilroy;
|
||||
$heading-font-family: $gilroy;
|
||||
@font-face {
|
||||
font-family: "Gilroy-Italic";
|
||||
src: url("~@/assets/fonts/Gilroy-RegularItalic.otf") format("opentype");
|
||||
}
|
||||
|
||||
@import "~vuetify/src/styles/settings/variables";
|
||||
$body-font-family: $gilroy;
|
||||
$heading-font-family: $gilroy;
|
||||
@font-face {
|
||||
font-family: "Gilroy-LightItalic";
|
||||
src: url("~@/assets/fonts/Gilroy-LightItalic.otf") format("opentype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Gilroy-MediumItalic";
|
||||
src: url("~@/assets/fonts/Gilroy-MediumItalic.otf") format("opentype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Gilroy-BoldItalic";
|
||||
src: url("~@/assets/fonts/Gilroy-BoldItalic.otf") format("opentype");
|
||||
}
|
||||
|
||||
// Set font variables
|
||||
|
||||
$Gilroy-Thin: "Gilroy-Thin", sans-serif !default;
|
||||
$Gilroy-Regular: "Gilroy-Regular", sans-serif !default;
|
||||
$Gilroy-Medium: "Gilroy-Medium", sans-serif !default;
|
||||
$Gilroy-Light: "Gilroy-Light", sans-serif !default;
|
||||
$Gilroy-Condensed-Light: "Gilroy-Condensed-Light", sans-serif !default;
|
||||
$Gilroy-Bold: "Gilroy-Bold", sans-serif !default;
|
||||
$Gilroy-Black: "Gilroy-Black", sans-serif !default;
|
||||
$Gilroy-Italic: "Gilroy-Italic", sans-serif !default;
|
||||
$Gilroy-LightItalic: "Gilroy-LightItalic", sans-serif !default;
|
||||
$Gilroy-MediumItalic: "Gilroy-MediumItalic", sans-serif !default;
|
||||
$Gilroy-BoldItalic: "Gilroy-BoldItalic", sans-serif !default;
|
||||
|
||||
// Replace default body fonts
|
||||
|
||||
// @import "../../node_modules/vuetify/src/styles/styles.sass";
|
||||
// $body-font-family: $Gilroy-Regular;
|
||||
// $heading-font-family: $Gilroy-Regular;
|
||||
|
||||
// @import "~vuetify/src/styles/settings/variables";
|
||||
// $body-font-family: $Gilroy-Regular;
|
||||
// $heading-font-family: $Gilroy-Regular;
|
||||
|
||||
// Replace typography fonts
|
||||
|
||||
.v-application {
|
||||
font-family: $Gilroy-Regular !important;
|
||||
.display-4,
|
||||
.display-3 {
|
||||
font-family: $Gilroy-Light !important;
|
||||
}
|
||||
.display-2,
|
||||
.display-1,
|
||||
.headline,
|
||||
.subtitle-1,
|
||||
.body-1,
|
||||
.body-2,
|
||||
.caption,
|
||||
.overline,
|
||||
.font-regular,
|
||||
.font-weight-regular {
|
||||
font-family: $Gilroy-Regular !important;
|
||||
}
|
||||
.title,
|
||||
.subtitle-2,
|
||||
.font-weight-medium {
|
||||
font-family: $Gilroy-Medium !important;
|
||||
}
|
||||
.font-weight-light {
|
||||
font-family: $Gilroy-Condensed-Light !important;
|
||||
}
|
||||
.font-weight-thin {
|
||||
font-family: $Gilroy-Thin !important;
|
||||
}
|
||||
.font-weight-bold {
|
||||
font-family: $Gilroy-Bold !important;
|
||||
}
|
||||
.font-weight-black {
|
||||
font-family: $Gilroy-Black !important;
|
||||
}
|
||||
.font-italic {
|
||||
font-family: $Gilroy-Italic !important;
|
||||
}
|
||||
.font-italic.font-weight-light {
|
||||
font-family: $Gilroy-LightItalic !important;
|
||||
}
|
||||
.font-italic.font-weight-medium {
|
||||
font-family: $Gilroy-MediumItalic !important;
|
||||
}
|
||||
.font-italic.font-weight-bold {
|
||||
font-family: $Gilroy-BoldItalic !important;
|
||||
}
|
||||
}
|
||||
|
||||
$body-font-family: $Gilroy-Regular !important;
|
||||
|
||||
// Change default font colour
|
||||
|
||||
$mainColor: #323947;
|
||||
|
||||
.fontColor, .theme--light.v-application, .theme--light.v-sheet {
|
||||
// color: $mainColor !important;
|
||||
color: red !important;
|
||||
.theme--light.v-application,
|
||||
.fontColor,
|
||||
.theme--light.v-sheet {
|
||||
color: $mainColor !important;
|
||||
}
|
||||
|
||||
10
src/scss/appbar.scss
Normal file
10
src/scss/appbar.scss
Normal file
@@ -0,0 +1,10 @@
|
||||
@import "../scss/_variables.scss";
|
||||
|
||||
$vsm-menu-link-height: 35px !default;
|
||||
$vsm-color: $mainColor !default;
|
||||
$vsm-color-hover: $mainColor !default;
|
||||
$vsm-media: 768px !default;
|
||||
$vsm-menu-border-radius: 15px !default;
|
||||
$vsm-menu-transform-content: 150px !default;
|
||||
|
||||
@import "~vue-stripe-menu/src/scss/index";
|
||||
162
src/views/Backgrounds.vue
Normal file
162
src/views/Backgrounds.vue
Normal file
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<h1>Backgrounds</h1>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1440 320"
|
||||
style="width: 500px;"
|
||||
>
|
||||
<path
|
||||
fill="#0099ff"
|
||||
fill-opacity="1"
|
||||
d="M0,0L48,42.7C96,85,192,171,288,176C384,181,480,107,576,101.3C672,96,768,160,864,154.7C960,149,1056,75,1152,85.3C1248,96,1344,192,1392,240L1440,288L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"
|
||||
></path>
|
||||
</svg>
|
||||
</v-row>
|
||||
<v-row class="mt-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320">
|
||||
<path
|
||||
fill="#0099ff"
|
||||
fill-opacity="0.5"
|
||||
d="M0,0L48,42.7C96,85,192,171,288,176C384,181,480,107,576,101.3C672,96,768,160,864,154.7C960,149,1056,75,1152,85.3C1248,96,1344,192,1392,240L1440,288L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"
|
||||
transform="rotate(-10 50 100)"
|
||||
></path>
|
||||
<path
|
||||
fill="#0099ff"
|
||||
fill-opacity="0.6"
|
||||
d="M0,0L48,42.7C96,85,192,171,288,176C384,181,480,107,576,101.3C672,96,768,160,864,154.7C960,149,1056,75,1152,85.3C1248,96,1344,192,1392,240L1440,288L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"
|
||||
transform="rotate(10 50 100)"
|
||||
></path>
|
||||
</svg>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<svg
|
||||
width="200"
|
||||
height="200"
|
||||
viewBox="0 0 600 600"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g transform="translate(300,300)">
|
||||
<path
|
||||
d="M154.5,-209.4C196.2,-182.4,223.2,-131.8,227.9,-82.3C232.7,-32.8,215.3,15.8,199.3,64.8C183.4,113.8,169,163.3,136,199.9C103.1,236.5,51.5,260.3,3.5,255.4C-44.5,250.5,-89,217.1,-129.7,183C-170.4,148.9,-207.4,114.2,-226.4,70.2C-245.4,26.2,-246.3,-27.1,-228.4,-71.7C-210.5,-116.4,-173.7,-152.4,-132.5,-179.6C-91.3,-206.7,-45.7,-224.8,5.4,-232.2C56.4,-239.7,112.9,-236.3,154.5,-209.4Z"
|
||||
fill="#FFB4BC"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-img src="https://cdn.vuetifyjs.com/images/cards/server-room.jpg">
|
||||
<v-col class="fill-height d-flex align-center justify-center">
|
||||
<h1 class="display-4 black--text">Text</h1>
|
||||
</v-col>
|
||||
</v-img>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<v-container fluid class="newtriangle">
|
||||
<v-row class="fill-height d-flex align-center">
|
||||
<v-col class="">
|
||||
<h1 class="display-2 white--text">
|
||||
CSS polygon background with clip-path.
|
||||
</h1>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col class="fill-height d-flex justify-center">
|
||||
<svg
|
||||
width="120"
|
||||
height="120"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<defs>
|
||||
<radialGradient
|
||||
id="Gradient"
|
||||
cx="0.5"
|
||||
cy="0.5"
|
||||
r="0.5"
|
||||
fx="0.25"
|
||||
fy="0.25"
|
||||
>
|
||||
<stop offset="0%" stop-color="red" />
|
||||
<stop offset="100%" stop-color="blue" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
|
||||
<rect
|
||||
x="10"
|
||||
y="10"
|
||||
rx="15"
|
||||
ry="15"
|
||||
width="100"
|
||||
height="100"
|
||||
fill="url(#Gradient)"
|
||||
stroke="black"
|
||||
stroke-width="2"
|
||||
/>
|
||||
|
||||
<circle
|
||||
cx="60"
|
||||
cy="60"
|
||||
r="50"
|
||||
fill="transparent"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
/>
|
||||
<circle cx="35" cy="35" r="2" fill="white" stroke="white" />
|
||||
<circle cx="60" cy="60" r="2" fill="white" stroke="white" />
|
||||
<text
|
||||
x="38"
|
||||
y="40"
|
||||
fill="white"
|
||||
font-family="sans-serif"
|
||||
font-size="10pt"
|
||||
>
|
||||
(fx,fy)
|
||||
</text>
|
||||
<text
|
||||
x="63"
|
||||
y="63"
|
||||
fill="white"
|
||||
font-family="sans-serif"
|
||||
font-size="10pt"
|
||||
>
|
||||
(cx,cy)
|
||||
</text>
|
||||
</svg>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.newtriangle {
|
||||
width: 105vw;
|
||||
height: 50vh;
|
||||
background-image: radial-gradient(
|
||||
circle farthest-corner at 7.5% 54.1%,
|
||||
rgba(0, 0, 0, 1) 0%,
|
||||
rgba(39, 0, 89, 1) 74.9%
|
||||
);
|
||||
-webkit-clip-path: polygon(0 0, 100% 35%, 100% 65%, 0% 100%);
|
||||
clip-path: polygon(0 0, 100% 35%, 100% 65%, 0% 100%);
|
||||
}
|
||||
</style>
|
||||
@@ -5,6 +5,10 @@
|
||||
Hello
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-btn color="primary">Hello</v-btn>
|
||||
<v-btn color="secondary">Hello</v-btn>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
|
||||
118
src/views/Playground.vue
Normal file
118
src/views/Playground.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-container fluid class="ma-0 pa-0 full-screen d-flex">
|
||||
<img
|
||||
src="../assets/images/pipebackground_1.svg"
|
||||
style=""
|
||||
class="d-flex align-end ma-0 pa-0 justify-end new-background-image"
|
||||
/>
|
||||
<v-container
|
||||
fill-height
|
||||
class="d-flex align-center"
|
||||
style="position: static; z-index: 10;"
|
||||
>
|
||||
<v-row>
|
||||
<v-col class="d-flex justify-center">
|
||||
<h1 class="display-2">Playground</h1>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<h1 class="display-2">Playground</h1>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<h1 class="display-2">{{ viewportHeight - 64 }}</h1>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<h1 class="display-2">{{ viewportWidth }}</h1>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<h1 class="display-2">{{ backgroundWidth }}</h1>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
viewportHeight: window.innerHeight,
|
||||
viewportWidth: window.innerWidth,
|
||||
backgroundWidth: ""
|
||||
};
|
||||
},
|
||||
created() {
|
||||
window.addEventListener("resize", this.updateHeight);
|
||||
window.addEventListener("resize", this.updateWidth);
|
||||
this.querySelectorsPlayground();
|
||||
},
|
||||
destroyed() {
|
||||
window.removeEventListener("resize", this.updateHeight);
|
||||
window.addEventListener("resize", this.updateWidth);
|
||||
},
|
||||
mounted() {
|
||||
// this.getBackgroundWidth();
|
||||
},
|
||||
methods: {
|
||||
updateHeight() {
|
||||
this.viewportHeight = window.innerHeight;
|
||||
},
|
||||
updateWidth() {
|
||||
this.viewportWidth = window.innerWidth;
|
||||
},
|
||||
getBackgroundWidth() {
|
||||
var background = document.querySelector("#backgroundsvg");
|
||||
this.backgroundWidth = background.clientWidth;
|
||||
},
|
||||
querySelectorsPlayground() {
|
||||
console.log(document.images);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$background-width: 795px;
|
||||
|
||||
.full-screen {
|
||||
height: calc(100vh - 64px);
|
||||
}
|
||||
|
||||
img.new-background-image {
|
||||
height: calc(100vh);
|
||||
position: absolute;
|
||||
object-fit: cover;
|
||||
// object-position: left;
|
||||
// width: 100%;
|
||||
// max-width: 100%;
|
||||
right: 0;
|
||||
// overflow: hidden;
|
||||
@media screen and (max-width: $background-width) {
|
||||
left: 0px;
|
||||
}
|
||||
@media #{map-get($display-breakpoints, 'md-and-up')} {
|
||||
top: -64px;
|
||||
}
|
||||
@media #{map-get($display-breakpoints, 'sm-and-down')} {
|
||||
top: -56px;
|
||||
}
|
||||
}
|
||||
|
||||
.background-image {
|
||||
position: absolute;
|
||||
height: calc(100vh - 64px);
|
||||
// width: 100%;
|
||||
max-width: 1115px;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
border-style: dashed;
|
||||
object-fit: cover;
|
||||
object-position: right top;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
145
src/views/Triangle.vue
Normal file
145
src/views/Triangle.vue
Normal file
@@ -0,0 +1,145 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-container fluid class="pa-0">
|
||||
<v-row class="d-flex newtriangle" style="position: absolute; z-index: 1;">
|
||||
<v-col
|
||||
class="d-flex align-center pt-0 ml-8"
|
||||
style="position: relative; z-index: 10;"
|
||||
>
|
||||
<v-card flat color="rgb(0, 0, 0, 0)">
|
||||
<h1 class="display" style="position: relative;">
|
||||
Welcome to Savvy Firebox Tutorial
|
||||
</h1>
|
||||
<v-btn
|
||||
x-large
|
||||
color="primary"
|
||||
style="position: relative; z-index: 10;"
|
||||
class="lighten-1"
|
||||
>Click Here</v-btn
|
||||
>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<v-container>
|
||||
<v-row class="d-flex" style="position: relative; height: 50vh;"> </v-row>
|
||||
<v-row class="d-flex justify-space-around">
|
||||
<v-col class="d-flex justify-center" md="6" xs="12">
|
||||
<v-card
|
||||
flat
|
||||
color="rgb(0, 0, 0, 0)"
|
||||
class="d-flex align-center justify-center flex-column pa-6"
|
||||
data-aos="zoom-in"
|
||||
data-aos-duration="3000"
|
||||
>
|
||||
<v-card-title>
|
||||
<span class="display-2 font-weight-bold">Learn more</span>
|
||||
</v-card-title>
|
||||
<v-card-text class="d-flex justify-center flex-column align-center">
|
||||
<transition name="bounce">
|
||||
<v-img
|
||||
src="@/assets/images/11-Casino chip.png"
|
||||
max-height="150px"
|
||||
max-width="150px"
|
||||
class="mb-5"
|
||||
></v-img>
|
||||
</transition>
|
||||
<span
|
||||
class="d-flex justify-center display body-1"
|
||||
style="color: black;"
|
||||
>
|
||||
More information about what we do and why.
|
||||
</span>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn color="secondary" medium>Click here</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col class="d-flex justify-center" md="6" xs="12">
|
||||
<v-card
|
||||
flat
|
||||
color="rgb(0, 0, 0, 0)"
|
||||
class="d-flex align-center justify-center flex-column pa-6"
|
||||
data-aos="test-roll"
|
||||
data-aos-duration="3000"
|
||||
data-aos-easing="new-easing"
|
||||
>
|
||||
<v-card-title>
|
||||
<span class="display-2 font-weight-bold">See more</span>
|
||||
</v-card-title>
|
||||
<v-card-text class="d-flex flex-column justify-center align-center">
|
||||
<v-img
|
||||
src="@/assets/images/12-Casino chip.png"
|
||||
max-height="150px"
|
||||
max-width="150px"
|
||||
class="mb-5"
|
||||
></v-img>
|
||||
<span
|
||||
class="d-flex justify-center display body-1"
|
||||
style="color: black;"
|
||||
>
|
||||
Additional things about what it is.
|
||||
</span>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn color="secondary" medium>Click here</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<!-- <v-col md="1" xs="0"></v-col> -->
|
||||
</v-row>
|
||||
</v-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
animate: false
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.newtriangle {
|
||||
width: 105vw;
|
||||
height: 50vh;
|
||||
background-image: radial-gradient(
|
||||
circle farthest-corner at 7.5% 54.1%,
|
||||
rgba(0, 0, 0, 1) 0%,
|
||||
rgba(39, 0, 89, 1) 74.9%
|
||||
);
|
||||
-webkit-clip-path: polygon(0 0, 100% 35%, 100% 65%, 0% 100%);
|
||||
clip-path: polygon(0 0, 100% 35%, 100% 65%, 0% 100%);
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
[data-aos="test-roll"] {
|
||||
-webkit-transform: translateX(-1000px) rotate(-720deg);
|
||||
transform: translateX(-1000px) rotate(-720deg);
|
||||
-webkit-filter: blur(50px);
|
||||
filter: blur(50px);
|
||||
opacity: 0;
|
||||
transition-property: transform, opacity, filter;
|
||||
&.aos-animate {
|
||||
-webkit-transform: translateX(0) rotate(0deg);
|
||||
transform: translateX(0) rotate(0deg);
|
||||
-webkit-filter: blur(0);
|
||||
filter: blur(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
[data-aos] {
|
||||
body[data-aos-easing="new-easing"] &,
|
||||
&[data-aos][data-aos-easing="new-easing"] {
|
||||
transition-timing-function: cubic-bezier(0.25, 1, 0.57, 0.55);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
218
src/views/forms/LoginForm.vue
Normal file
218
src/views/forms/LoginForm.vue
Normal file
@@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<v-container fluid fill-height class="d-flex align-center justify-center">
|
||||
<v-row>
|
||||
<v-col
|
||||
sm="6"
|
||||
cols="12"
|
||||
align-self="stretch"
|
||||
class="d-flex justify-sm-end justify-center pb-10 pb-sm-0 pr-sm-10"
|
||||
>
|
||||
<div class="d-flex flex-column align-end justify-space-around">
|
||||
<v-card
|
||||
color="rgb(0, 0, 0, 0)"
|
||||
flat
|
||||
class="d-flex align-center justify-center flex-column"
|
||||
width="100%"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-column align-sm-end align-center justify-center"
|
||||
:class="alignOnViewport"
|
||||
>
|
||||
<h1 class="whiteText title">
|
||||
Savvy Firebase Tutorial
|
||||
</h1>
|
||||
<p class="whiteText mb-0 mt-2">Log in or create an account.</p>
|
||||
</div>
|
||||
</v-card>
|
||||
<v-card color="rgb(0, 0, 0, 0)" flat width="100%">
|
||||
<div
|
||||
class="text-align-right d-flex flex-column align-sm-end align-center justify-center"
|
||||
>
|
||||
<p class="whiteText mb-0">Don't have an account? Create one.</p>
|
||||
</div>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col
|
||||
cols="12"
|
||||
sm="6"
|
||||
class="d-flex justify-sm-start justify-center pl-sm-10"
|
||||
>
|
||||
<v-card
|
||||
color="rgb(0, 0, 0, 0)"
|
||||
flat
|
||||
class="d-flex align-center flex-column"
|
||||
>
|
||||
<v-icon color="white" size="3em" class="pb-4"
|
||||
>mdi-account-circle</v-icon
|
||||
>
|
||||
<v-form
|
||||
v-model="valid"
|
||||
ref="form"
|
||||
class="pt-4 d-flex flex-column align-center justify-start"
|
||||
>
|
||||
<v-text-field
|
||||
v-for="field in formFields"
|
||||
:key="field.name"
|
||||
outlined
|
||||
rounded
|
||||
required
|
||||
:type="field.password ? 'password' : 'text'"
|
||||
background-color="rgb(100%, 100%, 100%, 10%)"
|
||||
color="rgb(100%, 100%, 100%, 20%)"
|
||||
class="white-placeholder full-width"
|
||||
v-model="field.value"
|
||||
:rules="field.rules"
|
||||
:label="field.placeholder"
|
||||
:success="!!field.value"
|
||||
@click:append="field.showIconData = !field.showIconData"
|
||||
>
|
||||
<template #prepend-inner>
|
||||
<v-icon color="white" class="pr-3">
|
||||
{{ field.prependIcon }}
|
||||
</v-icon>
|
||||
</template>
|
||||
<template #append>
|
||||
<div class="innerIcon">
|
||||
<v-btn
|
||||
v-if="field.appendIconShow"
|
||||
icon
|
||||
text
|
||||
x-small
|
||||
@click="
|
||||
() => {
|
||||
field.showIconData = !field.showIconData;
|
||||
field.password = !field.password;
|
||||
}
|
||||
"
|
||||
>
|
||||
<v-icon color="white">
|
||||
{{
|
||||
field.showIconData
|
||||
? field.appendIconShow
|
||||
: field.appendIconHide
|
||||
}}
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
</v-text-field>
|
||||
<v-btn
|
||||
depressed
|
||||
large
|
||||
color="primary"
|
||||
class="lighten-3"
|
||||
:loading="load"
|
||||
@click="submit"
|
||||
>Submit</v-btn
|
||||
>
|
||||
</v-form>
|
||||
<p class="whiteText mb-0 pt-5">Forgot password?</p>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "LoginForm",
|
||||
data() {
|
||||
return {
|
||||
valid: false,
|
||||
load: false,
|
||||
formFields: [
|
||||
{
|
||||
name: "Email",
|
||||
rules: [
|
||||
v => !!v || "You must enter an email address.",
|
||||
v => /.+@.+/.test(v) || "Email is not valid."
|
||||
],
|
||||
placeholder: "Email",
|
||||
successmessage: "Email is valid.",
|
||||
prependIcon: "mdi-at",
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
name: "Password",
|
||||
rules: [
|
||||
v => !!v || "You must enter a password.",
|
||||
v => (v && v.length >= 8) || "Minimum 8 characters."
|
||||
],
|
||||
placeholder: "Password",
|
||||
successmessage: "Password is valid.",
|
||||
prependIcon: "mdi-lock",
|
||||
appendIconShow: "mdi-eye",
|
||||
appendIconHide: "mdi-eye-off",
|
||||
showIconData: false,
|
||||
value: "",
|
||||
password: true
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async submit() {
|
||||
this.load = !this.load;
|
||||
console.log("loading");
|
||||
if (this.$refs.form.validate()) {
|
||||
console.log(`Email: ${this.formFields[0].value}`);
|
||||
console.log(`Password: ${this.formFields[1].value}`);
|
||||
} else {
|
||||
console.log("Not valid");
|
||||
this.load = !this.load;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
alignOnViewport() {
|
||||
return this.$vuetify.breakpoint.xsOnly
|
||||
? "text-align-center"
|
||||
: "text-align-right";
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// @import "../../scss/_variables.scss";
|
||||
|
||||
.whiteText {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.red-text {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.text-align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text-align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2rem !important;
|
||||
}
|
||||
|
||||
.white-placeholder ::v-deep input::placeholder {
|
||||
color: white !important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.white-placeholder ::v-deep input {
|
||||
color: white !important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.white-placeholder ::v-deep .v-label {
|
||||
color: white !important;
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
28
src/views/stripe-appbar/Random.vue
Normal file
28
src/views/stripe-appbar/Random.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<v-container style="width: 300px; height: 300px;">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-card flat>
|
||||
<p class="ma-0 pa-0 headline">Random Content</p>
|
||||
Random content that doesn't fit.
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-card flat>
|
||||
<ul>
|
||||
<li>Item one</li>
|
||||
<li>Item two</li>
|
||||
</ul>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
21
src/views/stripe-appbar/Welcome.vue
Normal file
21
src/views/stripe-appbar/Welcome.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-card flat class="ma-0 pa-0">
|
||||
<p class="headline">Welcome Pages</p>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.centre-text {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
19
src/views/stripe-appbar/WelcomeSecondary.vue
Normal file
19
src/views/stripe-appbar/WelcomeSecondary.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col style="width: 300px;">
|
||||
Welcome Secondary Content
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
653
temp.md
Normal file
653
temp.md
Normal file
@@ -0,0 +1,653 @@
|
||||
# Temp notes
|
||||
|
||||
## React to height change
|
||||
|
||||
### Get current height of page
|
||||
|
||||
To create content based on viewport height change you should use an event listener: `window.addEventListener`.
|
||||
|
||||
A list of all events you can listen for is here: <https://developer.mozilla.org/en-US/docs/Web/Events>
|
||||
|
||||
The current height can be obtained from `window.innerHeight`.
|
||||
|
||||
You should add `created` and `destroyed` to the script, and create a method to do something on the trigger:
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
viewportHeight: window.innerHeight
|
||||
};
|
||||
},
|
||||
created() {
|
||||
window.addEventListener("resize", this.updateHeight);
|
||||
},
|
||||
destroyed() {
|
||||
window.removeEventListener("resize", this.updateHeight);
|
||||
},
|
||||
methods: {
|
||||
updateHeight() {
|
||||
this.viewportHeight = window.innerHeight;
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
This can be useful if you need to pass the current height to a prop for an image component that you might want to fill the page:
|
||||
|
||||
```html
|
||||
<v-img
|
||||
src="../assets/images/newbackground.png"
|
||||
:height="this.viewportHeight - 64"
|
||||
width="auto"
|
||||
contain
|
||||
position="bottom 0px right 0px"
|
||||
class="ma-0 pa-0"
|
||||
id="backgroundsvg"
|
||||
></v-img>
|
||||
```
|
||||
|
||||
You can also get the height in the css. This way you can have an image set its own width or height as css parameters.
|
||||
|
||||
```css
|
||||
.full-screen {
|
||||
height: calc(100vh - 64px);
|
||||
}
|
||||
```
|
||||
|
||||
You might also want to add browser compatibility options:
|
||||
|
||||
Opera:
|
||||
`height: -o-calc(100% - 65px);`
|
||||
|
||||
Google/Safari:
|
||||
`height: -webkit-calc(100% - 65px);`
|
||||
|
||||
### Get current height of an object
|
||||
|
||||
Simiarly, you can add a watcher to get the width of any element. You should add a css class to the object you want to get the width of. Then you can use a `querySelector` to get it:
|
||||
|
||||
```javascript
|
||||
getBackgroundWidth() {
|
||||
var background = document.querySelector("#backgroundsvg");
|
||||
this.backgroundWidth = background.clientWidth;
|
||||
}
|
||||
```
|
||||
|
||||
Documentation for `querySelector`: <https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector>
|
||||
|
||||
You can see all the methods and properties for document here:
|
||||
<https://developer.mozilla.org/en-US/docs/Web/API/Document>
|
||||
|
||||
## Using `<v-content>` to fill the page
|
||||
|
||||
`fill-height` is useful for child components if you want them to fill to the height of the parent.
|
||||
|
||||
To make a fullscreen element use fluid with 0 margins, and set the height to 100vh. Then any children `<v-component>` can use the `fill-height` prop.
|
||||
|
||||
## v-for for n times repetition
|
||||
|
||||
You can repeat things n times using a `v-for`:
|
||||
|
||||
```html
|
||||
<v-container v-for="index in 10" :key="index"></v-container>
|
||||
```
|
||||
|
||||
Use `<v-container fill-height class="d-flex justify-center align-content-center">`
|
||||
to get content like - screenshot of central content with pipe background
|
||||
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
|
||||
## Images as backgrounds
|
||||
|
||||
You can use `background-size: cover;` in the css to dynamically have a background image adjust to the viewport.
|
||||
<https://www.webfx.com/blog/web-design/responsive-background-image/>
|
||||
|
||||
Demo: <https://www.webfx.com/blog/images/assets/cdn.sixrevisions.com/0431-01_responsive_background_image_demo/responsive-full-background-image-demo.html>
|
||||
|
||||
You can use aditional controls to set how the image should scale itself:
|
||||
<https://css-tricks.com/perfect-full-page-background-image/>
|
||||
|
||||
Cropping images with `object-fit: cover;`
|
||||
<https://alligator.io/css/cropping-images-object-fit/>
|
||||
|
||||
### SVG elements as a background
|
||||
|
||||
You can use an svg (from envato) as a fullscreen background image. To do this you should decide if you need a transparent appbar or not.
|
||||
|
||||
If you do not need a transparent appbar:
|
||||
|
||||
- Set an image
|
||||
- with `position: absolute;`
|
||||
- with `height: calc(100vh - 64px)`
|
||||
|
||||
## Images that autoscale (zoom)
|
||||
|
||||
This is a good example on how you can dynamically zoom in/out of an image:
|
||||
<https://css-tricks.com/crop-top/>
|
||||
|
||||
Quick method:
|
||||
|
||||
To set an image to auto scale (zoom style)
|
||||
|
||||
Use `max-width` to the value you want the image to be
|
||||
Use `width: 100%;`
|
||||
Use `height: auto;`
|
||||
Use `max-height` to the value you want the image to be
|
||||
|
||||
## Using envato EPS
|
||||
|
||||
Open the EPS file in Graphic. Hide and delete all the layers you don't need. When finished, create a new canvas and copy and paste the images to it. Position it accordingly and resize everything. Export as svg and edit the svg to remove the height and width.
|
||||
|
||||
## Transparent appbar
|
||||
|
||||
You can have the appbar be transparent to have a background image fullscreen. To do this you should:
|
||||
|
||||
- Set an image
|
||||
- with `position: absolute;`
|
||||
-
|
||||
|
||||
## To Do
|
||||
|
||||
Image looks good on `left: 50%;`
|
||||
|
||||
Organise these notes!
|
||||
|
||||
Set dynamic navbar content (cols)
|
||||
|
||||
Get image cropping from more than one direction
|
||||
|
||||
Document all up and move into firebase.md
|
||||
|
||||
Do stripe menu
|
||||
|
||||
Do waves/headers with backgrounds
|
||||
Do a fullscreen blob landing page
|
||||
Do Tailwind layout (moveable side content)
|
||||
Do <https://elements.envato.com/masty-business-html-landing-page-template-WQGEWXK> (using clippath on an image with an overlay colour?)
|
||||
Do Liquidlight (using big headers)
|
||||
Do <https://elements.envato.com/appstorm-app-startup-template-L74LLT> (use 100vh on background image as in playground with transparent appbar)
|
||||
|
||||
Position a triangle top right as in <https://elements.envato.com/set-of-medical-web-page-design-templates-5RRCL9>
|
||||
|
||||
And position random blobs as in <https://elements.envato.com/set-of-web-page-design-templates-EHNRLP>
|
||||
|
||||
More images: <https://elements.envato.com/set-of-medical-web-page-design-templates-VYMDPA>
|
||||
|
||||
Do buttons: <https://www.gatsbyjs.org>
|
||||
|
||||
Mention using media query to unset the right position when the breakpoint is met (find the breakpoint in vuetify)
|
||||
<https://www.w3schools.com/css/css_rwd_mediaqueries.asp>
|
||||
|
||||
Can use dynamic classes with vuetify.
|
||||
|
||||
Navbar gets slightly smaller on smaller breakpoints - can we dynamically set the hight on this?
|
||||
|
||||
56 on small breakpoint
|
||||
64 on medium and up
|
||||
|
||||
List of breakpoints:
|
||||
<https://vuetifyjs.com/en/customization/breakpoints/#breakpoints>
|
||||
|
||||
Small: `600px >< 960px`
|
||||
Medium: `960px >< 1264px`
|
||||
|
||||
When at width of image background, can set to right:0 to crop from left, and left:0 to crop from right.
|
||||
|
||||
Doc setting an image as background without transparent appbar
|
||||
Should show how to dynamically change height and left/right based on viewport (shorter appbar on small)
|
||||
|
||||
Doc setting an image with transparent appbar
|
||||
Rather than change height you need to set top to negative
|
||||
|
||||
Have examples of both of these to refer back to^
|
||||
|
||||
## Stripe appbar menu
|
||||
|
||||
## React to height change
|
||||
|
||||
### Get current height of page
|
||||
|
||||
To create content based on viewport height change you should use an event listener: `window.addEventListener`.
|
||||
|
||||
A list of all events you can listen for is here: <https://developer.mozilla.org/en-US/docs/Web/Events>
|
||||
|
||||
The current height can be obtained from `window.innerHeight`.
|
||||
|
||||
You should add `created` and `destroyed` to the script, and create a method to do something on the trigger:
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
viewportHeight: window.innerHeight
|
||||
};
|
||||
},
|
||||
created() {
|
||||
window.addEventListener("resize", this.updateHeight);
|
||||
},
|
||||
destroyed() {
|
||||
window.removeEventListener("resize", this.updateHeight);
|
||||
},
|
||||
methods: {
|
||||
updateHeight() {
|
||||
this.viewportHeight = window.innerHeight;
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
This can be useful if you need to pass the current height to a prop for an image component that you might want to fill the page:
|
||||
|
||||
```html
|
||||
<v-img
|
||||
src="../assets/images/newbackground.png"
|
||||
:height="this.viewportHeight - 64"
|
||||
width="auto"
|
||||
contain
|
||||
position="bottom 0px right 0px"
|
||||
class="ma-0 pa-0"
|
||||
id="backgroundsvg"
|
||||
></v-img>
|
||||
```
|
||||
|
||||
You can also get the height in the css. This way you can have an image set its own width or height as css parameters.
|
||||
|
||||
```css
|
||||
.full-screen {
|
||||
height: calc(100vh - 64px);
|
||||
}
|
||||
```
|
||||
|
||||
You might also want to add browser compatibility options:
|
||||
|
||||
Opera:
|
||||
`height: -o-calc(100% - 65px);`
|
||||
|
||||
Google/Safari:
|
||||
`height: -webkit-calc(100% - 65px);`
|
||||
|
||||
### Get current height of an object
|
||||
|
||||
Simiarly, you can add a watcher to get the width of any element. You should add a css class to the object you want to get the width of. Then you can use a `querySelector` to get it:
|
||||
|
||||
```javascript
|
||||
getBackgroundWidth() {
|
||||
var background = document.querySelector("#backgroundsvg");
|
||||
this.backgroundWidth = background.clientWidth;
|
||||
}
|
||||
```
|
||||
|
||||
Documentation for `querySelector`: <https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector>
|
||||
|
||||
You can see all the methods and properties for document here:
|
||||
<https://developer.mozilla.org/en-US/docs/Web/API/Document>
|
||||
|
||||
## Using `<v-content>` to fill the page
|
||||
|
||||
`fill-height` is useful for child components if you want them to fill to the height of the parent.
|
||||
|
||||
To make a fullscreen element use fluid with 0 margins, and set the height to 100vh. Then any children `<v-component>` can use the `fill-height` prop.
|
||||
|
||||
## v-for for n times repetition
|
||||
|
||||
You can repeat things n times using a `v-for`:
|
||||
|
||||
```html
|
||||
<v-container v-for="index in 10" :key="index"></v-container>
|
||||
```
|
||||
|
||||
Use `<v-container fill-height class="d-flex justify-center align-content-center">`
|
||||
to get content like - screenshot of central content with pipe background
|
||||
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
|
||||
## Images as backgrounds
|
||||
|
||||
You can use `background-size: cover;` in the css to dynamically have a background image adjust to the viewport.
|
||||
<https://www.webfx.com/blog/web-design/responsive-background-image/>
|
||||
|
||||
Demo: <https://www.webfx.com/blog/images/assets/cdn.sixrevisions.com/0431-01_responsive_background_image_demo/responsive-full-background-image-demo.html>
|
||||
|
||||
You can use aditional controls to set how the image should scale itself:
|
||||
<https://css-tricks.com/perfect-full-page-background-image/>
|
||||
|
||||
Cropping images with `object-fit: cover;`
|
||||
<https://alligator.io/css/cropping-images-object-fit/>
|
||||
|
||||
### SVG elements as a background
|
||||
|
||||
You can use an svg (from envato) as a fullscreen background image. To do this you should decide if you need a transparent appbar or not.
|
||||
|
||||
If you do not need a transparent appbar:
|
||||
|
||||
- Set an image
|
||||
- with `position: absolute;`
|
||||
- with `height: calc(100vh - 64px)`
|
||||
|
||||
## Images that autoscale (zoom)
|
||||
|
||||
This is a good example on how you can dynamically zoom in/out of an image:
|
||||
<https://css-tricks.com/crop-top/>
|
||||
|
||||
Quick method:
|
||||
|
||||
To set an image to auto scale (zoom style)
|
||||
|
||||
Use `max-width` to the value you want the image to be
|
||||
Use `width: 100%;`
|
||||
Use `height: auto;`
|
||||
Use `max-height` to the value you want the image to be
|
||||
|
||||
## Using envato EPS
|
||||
|
||||
Open the EPS file in Graphic. Hide and delete all the layers you don't need. When finished, create a new canvas and copy and paste the images to it. Position it accordingly and resize everything. Export as svg and edit the svg to remove the height and width.
|
||||
|
||||
## Fullscreen image as a background
|
||||
|
||||
### Transparent appbar
|
||||
|
||||
You can have the appbar be transparent to have a background image fullscreen.
|
||||
|
||||
```html
|
||||
<v-app-bar
|
||||
flat
|
||||
app
|
||||
hide-on-scroll
|
||||
color="rgba(93.3%, 93.3%, 93.3%, 0.5)"
|
||||
v-if="!this.$store.getters.fullScreen"
|
||||
style="z-index: 15;"
|
||||
></v-app-bar>
|
||||
```
|
||||
|
||||
### Adjust image height to match that of dynamic appbar
|
||||
|
||||
### Using CSS media queries for dynamic classes
|
||||
|
||||
The appbar will adjust its own height based on the viewport.
|
||||
|
||||
On medium and above it will be 64px, on small and below it will be 56px.
|
||||
|
||||
On the image itself you should adjust the `top` css property to account for this:
|
||||
|
||||
```scss
|
||||
img.new-background-image {
|
||||
height: calc(100vh);
|
||||
position: absolute;
|
||||
right: 0;
|
||||
@media screen and (max-width: $background-width) {
|
||||
left: 0px;
|
||||
}
|
||||
@media #{map-get($display-breakpoints, 'md-and-up')} {
|
||||
top: -64px;
|
||||
}
|
||||
@media #{map-get($display-breakpoints, 'sm-and-down')} {
|
||||
top: -56px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Stripe appbar menu
|
||||
|
||||
Example: <https://git.panaetius.co.uk/web-development/savvy-firebase/src/branch/base-template/src/components/Appbar.vue>
|
||||
|
||||
Install with yarn:
|
||||
`yarn add vue-stripe-menu`
|
||||
|
||||
Add to `main.js`:
|
||||
|
||||
```javascript
|
||||
import Vue from "Vue";
|
||||
import VueStripeMenu from "vue-stripe-menu";
|
||||
Vue.use(VueStripeMenu);
|
||||
// Import build styles
|
||||
import "vue-stripe-menu/dist/vue-stripe-menu.css";
|
||||
```
|
||||
|
||||
You should create Vue components for the content you want to display on hover.
|
||||
|
||||
To use these in the appbar component, import the components:
|
||||
|
||||
```javascript
|
||||
import Welcome from "./views/stripe-appbar/Welcome";
|
||||
import WelcomeSecondary from "./views/stripe-appbar/WelcomeSecondary";
|
||||
```
|
||||
|
||||
Then you should create a menu object in `data`:
|
||||
|
||||
```javascript
|
||||
data() {
|
||||
return {
|
||||
menu: [
|
||||
{
|
||||
title: "Welcome",
|
||||
dropdown: "welcome",
|
||||
content: Welcome,
|
||||
secondary: WelcomeSecondary,
|
||||
element: "span"
|
||||
},
|
||||
{
|
||||
title: "Welcome",
|
||||
dropdown: "welcome",
|
||||
content: Welcome,
|
||||
secondary: WelcomeSecondary
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Then in the html you should create the appbar layout you need:
|
||||
|
||||
```html
|
||||
<vsm-menu ref="header" :menu="menu" :screen-offset="25">
|
||||
<template #default="data">
|
||||
<component :is="data.item.content" class="content" />
|
||||
<component :is="data.item.secondary" class="content--secondary" />
|
||||
</template>
|
||||
</vsm-menu>
|
||||
```
|
||||
|
||||
The `ref` is so you can refer to the menu object in javascript using `this.$header` later on. The menu prop should point to the list which contains the objects for each component you want to render.
|
||||
|
||||
You can use css to control how the components should be rendered:
|
||||
|
||||
```css
|
||||
.content {
|
||||
padding: 20px;
|
||||
}
|
||||
.content--secondary {
|
||||
padding: 20px;
|
||||
}
|
||||
```
|
||||
|
||||
To control the width, you should set the `width` in the css in the components themsevles:
|
||||
|
||||
```html
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col style="width: 300px;">
|
||||
Welcome Secondary Content
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
```
|
||||
|
||||
To have two menu content sections top and bottom: use `content` and `secondary`.
|
||||
To have two menu content sections side by side: create the full layout in the Vue component.
|
||||
|
||||
If you just want a link and no component as a dropdown, you should reference a `routerLink` object inside the list's object.
|
||||
|
||||
```javascript
|
||||
{
|
||||
title: "Playground",
|
||||
routerLink: { name: "Playground" }
|
||||
}
|
||||
```
|
||||
|
||||
Then you can use a `<router-link>` component with a `v-if="data.item.routerLink"`:
|
||||
|
||||
```html
|
||||
<template #default="data">
|
||||
<component :is="data.item.content" class="content" />
|
||||
<component :is="data.item.secondary" class="content--secondary" />
|
||||
</template>
|
||||
<template #title="menu" class="ma-0 pa-0">
|
||||
<router-link
|
||||
:to="menu.item.routerLink"
|
||||
v-if="menu.item.routerLink"
|
||||
style="padding-bottom: -20px;"
|
||||
>
|
||||
<p class="ma-0 pa-0 underline routerLink">
|
||||
{{ menu.item.title }}
|
||||
</p>
|
||||
</router-link>
|
||||
</template>
|
||||
```
|
||||
|
||||
Using the title prop controls what text should be rendered for each object's title. We can use an if with a router-link to control whether it should be a link or not.
|
||||
|
||||
To control the scss variables you should create an appbar.scss file in the `./scss/` folder. This file should override the default scss variables of the component.
|
||||
|
||||
<https://github.com/Alexeykhr/vue-stripe-menu/blob/master/src/scss/_variables.scss>
|
||||
|
||||
```scss
|
||||
@import "../scss/_variables.scss";
|
||||
|
||||
$vsm-menu-link-height: 35px !default;
|
||||
$vsm-color: $mainColor !default;
|
||||
$vsm-color-hover: $mainColor !default;
|
||||
$vsm-media: 768px !default;
|
||||
$vsm-menu-border-radius: 15px !default;
|
||||
$vsm-menu-transform-content: 150px !default;
|
||||
|
||||
@import "~vue-stripe-menu/src/scss/index";
|
||||
```
|
||||
|
||||
We can import the default `_variables.scss` to use the font colour variable. Once we have overwritten the variables we should import the default scss file. Then in your `main.js` file you should import this scss file instead:
|
||||
|
||||
```javascript
|
||||
import "./scss/appbar.scss";
|
||||
```
|
||||
|
||||
You can use this file to set the breakpoint width that Vuetify uses. If your appbar changes on sm and below, you can set the `$vsm-media` variable to this pixel viewport.
|
||||
|
||||
To allow the appbar to function in a Vuetify appbar component, you should set the `z-index` in the css of the element:
|
||||
|
||||
```html
|
||||
<v-app-bar
|
||||
flat
|
||||
app
|
||||
hide-on-scroll
|
||||
color="rgba(93.3%, 93.3%, 93.3%, 0.5)"
|
||||
v-if="!this.$store.getters.fullScreen"
|
||||
style="z-index: 15;"
|
||||
></v-app-bar>
|
||||
```
|
||||
|
||||
## Getting sass to talk to javascript
|
||||
|
||||
<https://css-tricks.com/making-sass-talk-to-javascript-with-json/>
|
||||
|
||||
## Using Vuetify Sass variables for dynamic css
|
||||
|
||||
## Using SASS variables for viewport
|
||||
|
||||
Vuetify has SASS variables that you can use in your css blocks.
|
||||
|
||||
<https://vuetifyjs.com/en/customization/sass-variables/>
|
||||
|
||||
To control CSS based on the viewport, you can either set the class dynamically, or you can use SCSS itself.
|
||||
|
||||
You can use `$display-breakpoints` with a `map-get` in the sass to set a css property dynamically (check the documentation for the options that `$display-breakpoints` offers).
|
||||
|
||||
For example, you can apply css to a class based on whether or not the viewport is met:
|
||||
|
||||
```scss
|
||||
img.new-background-image {
|
||||
height: calc(100vh);
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -64px;
|
||||
@media #{map-get($display-breakpoints, 'sm-and-down')} {
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you want to break on a specific width (say when the background image width is met to align it), you can use a scss variable:
|
||||
|
||||
```scss
|
||||
$background-width: 795px;
|
||||
|
||||
img.new-background-image {
|
||||
height: calc(100vh);
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -64px;
|
||||
@media screen and (max-width: $background-width) {
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## To Do
|
||||
|
||||
Image looks good on `left: 50%;`
|
||||
|
||||
Organise these notes!
|
||||
|
||||
Set dynamic navbar content (cols)
|
||||
|
||||
Get image cropping from more than one direction
|
||||
|
||||
Document all up and move into firebase.md
|
||||
|
||||
Do stripe menu
|
||||
|
||||
Do waves/headers with backgrounds
|
||||
Do a fullscreen blob landing page
|
||||
Do Tailwind layout (moveable side content)
|
||||
Do <https://elements.envato.com/masty-business-html-landing-page-template-WQGEWXK> (using clippath on an image with an overlay colour?)
|
||||
Do Liquidlight (using big headers)
|
||||
Do <https://elements.envato.com/appstorm-app-startup-template-L74LLT> (use 100vh on background image as in playground with transparent appbar)
|
||||
|
||||
Position a triangle top right as in <https://elements.envato.com/set-of-medical-web-page-design-templates-5RRCL9>
|
||||
|
||||
And position random blobs as in <https://elements.envato.com/set-of-web-page-design-templates-EHNRLP>
|
||||
|
||||
More images: <https://elements.envato.com/set-of-medical-web-page-design-templates-VYMDPA>
|
||||
|
||||
Do buttons: <https://www.gatsbyjs.org>
|
||||
|
||||
Mention using media query to unset the right position when the breakpoint is met (find the breakpoint in vuetify)
|
||||
<https://www.w3schools.com/css/css_rwd_mediaqueries.asp>
|
||||
|
||||
Can use dynamic classes with vuetify.
|
||||
|
||||
Navbar gets slightly smaller on smaller breakpoints - can we dynamically set the hight on this?
|
||||
|
||||
56 on small breakpoint
|
||||
64 on medium and up
|
||||
|
||||
List of breakpoints:
|
||||
<https://vuetifyjs.com/en/customization/breakpoints/#breakpoints>
|
||||
|
||||
Small: `600px >< 960px`
|
||||
Medium: `960px >< 1264px`
|
||||
|
||||
When at width of image background, can set to right:0 to crop from left, and left:0 to crop from right.
|
||||
|
||||
Doc setting an image as background without transparent appbar
|
||||
Should show how to dynamically change height and left/right based on viewport (shorter appbar on small)
|
||||
|
||||
Doc setting an image with transparent appbar
|
||||
Rather than change height you need to set top to negative
|
||||
|
||||
Have examples of both of these to refer back to^
|
||||
@@ -1,11 +1,11 @@
|
||||
module.exports = {
|
||||
css: {
|
||||
loaderOptions: {
|
||||
scss: {
|
||||
prependData: `
|
||||
@import "@/scss/_variables.scss";
|
||||
`
|
||||
}
|
||||
// scss: {
|
||||
// prependData: `
|
||||
// @import "@/scss/_variables.scss";
|
||||
// `
|
||||
// }
|
||||
}
|
||||
},
|
||||
transpileDependencies: ["vuetify"]
|
||||
|
||||
37
yarn.lock
37
yarn.lock
@@ -1445,6 +1445,15 @@ anymatch@~3.1.1:
|
||||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
aos@^3.0.0-beta.6:
|
||||
version "3.0.0-beta.6"
|
||||
resolved "https://registry.yarnpkg.com/aos/-/aos-3.0.0-beta.6.tgz#75148e3be4bb1add53f5a1828623bf82b67691e9"
|
||||
integrity sha512-VLWrpq8bfAWcetynVHMMrqdC+89Qq/Ym6UBJbHB4crIwp3RR8uq1dNGgsFzoDl03S43rlVMK+na3r5+oUCZsYw==
|
||||
dependencies:
|
||||
classlist-polyfill "^1.2.0"
|
||||
lodash.debounce "^4.0.8"
|
||||
lodash.throttle "^4.1.1"
|
||||
|
||||
aproba@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npm.taobao.org/aproba/download/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
||||
@@ -2133,6 +2142,11 @@ class-utils@^0.3.5:
|
||||
isobject "^3.0.0"
|
||||
static-extend "^0.1.1"
|
||||
|
||||
classlist-polyfill@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/classlist-polyfill/-/classlist-polyfill-1.2.0.tgz#935bc2dfd9458a876b279617514638bcaa964a2e"
|
||||
integrity sha1-k1vC39lFiodrJ5YXUUY4vKqWSi4=
|
||||
|
||||
clean-css@4.2.x:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.npm.taobao.org/clean-css/download/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
|
||||
@@ -4914,6 +4928,11 @@ locate-path@^5.0.0:
|
||||
dependencies:
|
||||
p-locate "^4.1.0"
|
||||
|
||||
lodash.debounce@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
|
||||
|
||||
lodash.defaultsdeep@^4.6.1:
|
||||
version "4.6.1"
|
||||
resolved "https://registry.npm.taobao.org/lodash.defaultsdeep/download/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6"
|
||||
@@ -4934,6 +4953,11 @@ lodash.memoize@^4.1.2:
|
||||
resolved "https://registry.npm.taobao.org/lodash.memoize/download/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
||||
|
||||
lodash.throttle@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
|
||||
integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=
|
||||
|
||||
lodash.transform@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.npm.taobao.org/lodash.transform/download/lodash.transform-4.6.0.tgz#12306422f63324aed8483d3f38332b5f670547a0"
|
||||
@@ -8020,6 +8044,11 @@ vue-loader@^15.8.3:
|
||||
vue-hot-reload-api "^2.3.0"
|
||||
vue-style-loader "^4.1.0"
|
||||
|
||||
vue-page-transition@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/vue-page-transition/-/vue-page-transition-0.2.2.tgz#a7c607ccc8dc67e7c05e66a5a9d54bd27d252d56"
|
||||
integrity sha512-qOx+llJ28XX0VwJNJ4GVaeNBPRmPMZac2QQgrIHVUhpXyJx2CQ2XvoQOpGD1ge7QMY3PjZ6fwTbdBwZkA3I9qA==
|
||||
|
||||
vue-responsive-video-background-player@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/vue-responsive-video-background-player/-/vue-responsive-video-background-player-1.0.8.tgz#c0c95b82aa48a13e92f72c6051cc7ec8ff44058d"
|
||||
@@ -8030,6 +8059,14 @@ vue-router@^3.1.5:
|
||||
resolved "https://registry.npm.taobao.org/vue-router/download/vue-router-3.1.6.tgz?cache=0&sync_timestamp=1584203224109&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-router%2Fdownload%2Fvue-router-3.1.6.tgz#45f5a3a3843e31702c061dd829393554e4328f89"
|
||||
integrity sha1-RfWjo4Q+MXAsBh3YKTk1VOQyj4k=
|
||||
|
||||
vue-stripe-menu@^1.2.8:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/vue-stripe-menu/-/vue-stripe-menu-1.2.8.tgz#435b992fc4dd519f5711c0d882b32ed7bf883151"
|
||||
integrity sha512-4btZ1/s8+fFGQexcgCMVGoIW6zxUg1jJ+sYgM/gcCYPtrWVMvcHQ2Hx2gBcAQaCat9WD/Hy/ddx2pgzXvljBNg==
|
||||
dependencies:
|
||||
core-js "^3.6.4"
|
||||
vue "^2.6.11"
|
||||
|
||||
vue-style-loader@^4.1.0, vue-style-loader@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.npm.taobao.org/vue-style-loader/download/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8"
|
||||
|
||||
Reference in New Issue
Block a user