Advertisement

#1 Creating an Animatable Splash Screen

In this article we will talk about the settings and configuration that were used when the project was created and from there we will create a couple of new components for our application. We will start with creating a splash screen component and then an animatable item component. We will be using the animatable item as its name suggests to provide the logic for animating other components. We will finish up by using some facilities form rxjs to allow for communication between our splash screen and its animatable item.

Project creation

Of course we have start by creating a new project for us to work on. In order to do this I used the vue user interface application that is installed when you install the vue cli. In (a) you can see which features have been enabled, which is all of them, and in (b) you can see the configuration options that were chosen.

Image showing the cli features that were enabled during project creation.
(a) Image showing the cli features that were enabled during project creation.
Image showing the cli configuration that was used during project creation.
(b) Image showing the cli configuration that was used during project creation.

package.json

  • root
    • package.json

When the project is created with these settings the cli generates the corresponding project.json file shown in (c).

package.json

{
  "name": "project-name",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "test:e2e": "vue-cli-service test:e2e",
    "test:unit": "vue-cli-service test:unit"
  },
  "dependencies": {
    "core-js": "^2.6.5",
    "register-service-worker": "^1.6.2",
    "vue": "^2.6.10",
    "vue-class-component": "^7.0.2",
    "vue-property-decorator": "^8.1.0",
    "vue-router": "^3.0.3",
    "vuex": "^3.0.1"
  },
  "devDependencies": {
    "@types/jest": "^23.1.4",
    "@ue/cli-plugin-babel": "^3.8.0",
    "@ue/cli-plugin-e2e-cypress": "^3.8.0",
    "@vue/cli-plugin-pwa": "^3.8.0",
    "@vue/cli-plugin-typescript": "^3.8.0",
    "@vue/cli-plugin-unit-jest": "^3.8.0",
    "@vue/cli-service": "^3.8.0",
    "@vue/test-utils": "1.0.0-beta.29",
    "babel-core": "7.0.0-bridge.0",
    "node-sass": "^4.9.0",
    "sass-loader": "^7.1.0",
    "ts-jest": "^23.0.0",
    "typescript": "^3.4.3",
    "vue-cli-plugin-pug": "^1.0.7",
    "vue-template-compiler": "^2.6.10"
  }
}
(c) The package.json file that is generated for us when we use the vue ui with the settings shown previously.

We need another package to start with

  • root
    • package.json

The one other package that we are going to need to start with is rxjs . In order to install the package we just need to use npm install rxjs --save command in our terminal. The version that I installed at the time of the writing of this article is shown in (d).

package.json

{
  ...
  "dependencies": {
    ...
    "rxjs": "^6.5.2",
    ...
  },
  ...
}
(d) The version of rxjs that was installed at the time of the writing of this article.

The splash screen

  • root
    • src
      • components
        • TheSplashScreen.vue

The first thing we are going to do now that our project is set up is create a stub of our splash screen just to make sure we have everything set up correctly. The template is shown in (e) and the script is shown in (f).

To facilitate code syntax highlighting in the articles I will be breaking down the components of a .vue file into separate code blocks. One for the template, one for the script and if needed one for the style tags.

TheSplashScreen.vue

<template lang="pug">
div SplashScreen
</template>
(e) The stub template for our splash screen.

TheSplashScreen.vue

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

@Component
export default class TheSplashScreen extends Vue {
    
}
</script>
(f) The stub script for our splash screen.
Advertisement

Updating our app

  • root
    • src
      • App.vue

Next up is updating of our App.vue file. Part of the updating is to convert the tags inside of the file to use the file formats that I want to use and the other is to add the splash screen component to our rendered output. First up is converting the template from html to pug and adding in our splash screen (g).

App.vue

<template lang="pug">
div#app
    SplashScreen/
    div#nav
        router-link(to="/") Home
        router-link(to="/about") About
    router-view
</template>
(g) Converting the template to pug syntax and adding in our splash screen component.

Moving on we are now ready to update the script to use the class syntax and of course import in our splash screen (h).

App.vue

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

import SplashScreen from "@/components/TheSplashScreen.vue";

@Component({
    components:  {
        SplashScreen,
    }
})
export default class App extends Vue { }
</script>
(h) Converting the script to use the class syntax and importing our splash screen component.

Last but not least I have decided I want to use the sass syntax, at least for a while, to see how everything goes. I prefer the syntax whether or not I continue to use it is a matter of support within the tools we are using (i).

App.vue

<style lang="sass">
@import "./development.site"
#app
    font-family: 'Avenir', Helvetica, Arial, sans-serif
    -webkit-font-smoothing: antialiased
    -moz-osx-font-smoothing: grayscale
    text-align: center
    color: #2c3e50

    #nav 
        padding: 30px
        a
            font-weight: bold
            color: #2c3e50
            &.router-link-exact-active
                color: #42b983
</style>
(i) Converting our style tag to use the sass syntax.

Animation an item

  • root
    • src
      • components
        • animations
          • AnimatableItem.vue

In the end we are going to want to be able to animate not only our splash screen but many other elements of our user interface. To make it easier to apply these animations to different components we are going to encapsulate the functionality into a separate component that will just handle the animations. Once again we are just going to stub everything out to start with. We begin with the template (j).

AnimatableItem.vue

<template lang="pug">
div Animatable Item
    slot
</template>
(j) Stub template for our animatable item component.

Following the template we have the stub for our script (k).

AnimatableItem.vue

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

@Component
export default class AnimatableItem extends Vue {
    
}
</script>
(k) Stub script for our animatable item component.

Wrapping our splash screen

  • root
    • src
      • components
        • TheSplashScreen.vue

Now that we have created our animatable item we will return to our splash screen and wrap its contents in one by updating the template (l).

TheSplashScreen.vue

<template lang="pug">
AnimatableItem
    div SplashScreen
</template>
(l) Wrapping the contents of our splash screen with an animatable item component.

Of course since we are using it in our template we need to update our script to properly define it (m).

TheSplashScreen.vue

<script lang="ts">
...
import AnimatableItem from "@/components/animations/AnimatableItem.vue";

@Component({
    components: {
        AnimatableItem,
    }
})
export default class TheSplashScreen extends Vue {
    
}
</script>
(m) Importing and declaring our animatable item so that it is available for use in our template.

Communicating with the animatable item

  • root
    • src
      • components
        • animations
          • AnimatableItem.vue

Now that we have the animatable item we are going to need a way to communicate with it in order to tell it when and which animation to play. First up we will start by updating the animatable item's script to declare that we expect to be provided a rxjs subject as a prop and while we are at it we will take care of both subscribing and unsubscribing from it (n).

AnimatableItem.vue

<script lang="ts">
import { ..., Prop, ... } from "vue-property-decorator";
import { Observable, Subject } from "rxjs";
import { takeUntil } from "rxjs/operators";

@Component
export default class AnimatableItem extends Vue {
    @Prop() private readonly subject!: Subject<string>;

    private readonly unsubscribe = new Subject<void>();

    private beforeDestroy() {
        this.unsubscribe.next();
        this.unsubscribe.complete();
    }

    private created() {
        this.subject
            .asObservable()
            .pipe(takeUntil(this.unsubscribe))
            .subscribe(this.animate);
    }

    private animate(animation: string) {
        console.log(animation);
    }
}
</script>
(n) Adding the ability to communicate with our animatable item by using a rxjs subject that will be passed as a prop and taking care of subscribing and unsubscribing to it.

Our first communication

  • root
    • src
      • components
        • TheSplashScreen.vue

Now that we have the ability to communicate with our animatable object we need to once again update the splash screen itself. First up we will update our template to pass in a subject and add a button that we can use to send a message using it (o).

TheSplashScreen.vue

<template lang="pug">
AnimatableItem(v-bind:subject="animationSubject")
    div SplashScreen
    button(v-on:click.prevent="click") Test
</template>
(o) Adding a binding to our animatable object that will pass a subject to it and creating a button that we can use to cause a message to be sent to our animatable item.

Last thing we need to accomplish for this article is updating our script to provide a subject to our template and create the event handler that will send the message (p).

TheSplashScreen.vue

<script lang="ts">
...
import { Subject } from "rxjs";
...
export default class TheSplashScreen extends Vue {
    private readonly animationSubject = new Subject<string>();

    private beforeDestroy() {
        this.animationSubject.complete();
    }

    private click() {
        this.animationSubject.next("test");
    }
}
</script>
(p) Creating our subject that will be passed into our animatable object and adding an event handler to send a message using it.
Exciton Interactive LLC
Advertisement