Vue Weather Notifier

https://codepen.io/sdras/pen/YNpaoJ https://css-tricks.com/intro-to-vue-4-vuex/

by Megi93

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.0.0/vuex.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/CustomEase.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/DrawSVGPlugin.min.js"></script>
<div id="app">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="00 695.3 452.7" aria-labelledby="title" class="notifier-svg">
        <app-defs></app-defs>
        <title id="title">
            Phone Notifications
        </title>
        <g style="isolation:isolate">
            <g id="Layer_1" data-name="Layer 1">
                <path fill="#92278f" d="M0 54H695.3V452.67H0z" />
                <path id="phoneshadow" fill="url(#linear-gradient)" d="M389.2 381.2L559.3 404.3 562.7 220.3 203.5 237.7 389.2 381.2z" />
                <path id="phonebase" d="M454.5,248.4l-.5,8.9-52,60c-5.3,8.7-28.7,4.7-28.7,4.7L141.4,261.4h0l-.7-.2h-.1a4.5,4.5,0,0,1-3.2-3.4h0v-.5a0,0,0,0,1,0,0l-.6-11.3Z" transform="translate(0 58)" fill="url(#linear-gradient-2)" />
                <path d="M445.1,240c8.5,2.3,12,7.8,7.8,12.3L398.2,311c-4.2,4.5-14.5,6.4-23,4.1l-229-60.6c-8.5-2.3-12-7.8-7.8-12.3L193,183.5c4.2-4.5,14.5-6.4,23-4.1Z" transform="translate(0 58)" fill="url(#linear-gradient-3)" />
                <path d="M418.1,240.2c2.3.6,3.1,2.2,1.9,3.6l-54.5,58.5c-1.3,1.4-4.2,2-6.5,1.4L167,252.7c-2.3-.6-3.1-2.2-1.9-3.6l54.5-58.5c1.3-1.4,4.2-2,6.5-1.4Z" transform="translate(0 58)" fill="url(#linear-gradient-4)" />
                <path d="M189.1,207.6c.8.2,1.1.7.7,1.1l-15.8,17a2.3,2.3,0,0,1-2,.4h0c-.8-.2-1.1-.7-.7-1.1l15.8-17a2.3,2.3,0,0,1,2-.4Z" transform="translate(0 58)" fill="#313131" />
                <g id="phonebutton" @click="updateTemplate" v-if="!showWeather">
                    <transition @before-enter="beforeEnterStroke"...

CSS

body {
    background: #92278f;
}

.notifier-svg {
    max-width: 1300px;
    margin: 0 auto;
    display: table;
}

#app {
    font-family: 'Titillium Web', sans-serif;
}

.press {
    visibility: hidden;
}

.fadeout-enter-active,
.fadeout-leave-active {
    -webkit-transition: opacity 0.25s;
    transition: opacity 0.25s;
}

.fadeout-enter,
.fadeout-leave-to {
    opacity: 0;
}

#thx-button,
#phonebutton {
    cursor: pointer;
}

#wind {
    -webkit-transform: translate(-20px, 59px);
    transform: translate(-20px, 59px);
    opacity: 0.9;
}

#tornado {
    -webkit-transform: translate(5px, 54px);
    transform: translate(5px, 54px);
}

#rainbow {
    -webkit-transform: translate(0px, 50px);
    transform: translate(0px, 50px);
}

@media screen and (max-width: 700px) {
    .notifier-svg {
        width: 120vw;
        height: 120vh;
        margin-top: -120px;
        margin-left: -50px;
    }
}

JavaScript

'use strict';

// The code is a little different in codepen, if you'd like to see the setup that's more true to real-life, it's in this repo: https://github.com/sdras/vue-weather-notifier
//I had to change a bunch of things around to use vuex in one script tag, most notably that this.$store became just store

var store = new Vuex.Store({
    state: {
        showWeather: false,
        template: 0
    },
    mutations: {
        toggle: function toggle(state) {
            return state.showWeather = !state.showWeather;
        },
        updateTemplate: function updateTemplate(state) {
            state.template = (state.template + 1) % 4;
            state.showWeather = !state.showWeather;
        }
    }
});

var Defs = {
    template: '#defs'
};

var Dialog = {
    template: '#dialog',
    computed: {
        template: function template() {
            return store.state.template;
        }
    },
    methods: {
        toggle: function toggle() {
            store.commit('toggle');
        }
    },
    mounted: function mounted() {
        //enter weather
        var tl = new TimelineMax();

        tl.add("enter");

        tl.fromTo("#dialog", 2, {
            opacity: 0
        }, {
            opacity: 1
        }, "enter");

        tl.fromTo("#dialog", 2, {
            rotation: -4
        }, {
            rotation: 0,
            transformOrigin: "50% 100%",
            ease: Elastic.easeOut
        }, "enter");
    }
};

var Droparea = {
    template: '#droparea',
    mounted: function mounted() {
        var audio = new Audio('https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/rain.mp3'),
            tl = new TimelineMax();

        audio.play();
        tl.add("drops");

        //drops in
        tl.staggerFromTo("#droplet-groups g path", 0.3, {
            drawSVG: "0% -10%"
        }, {
            drawSVG: "100% 110%",
            repeat: 3,
            repeatDelay: 1,
            ease: Sine.easeIn
        }, 0.5, "drops");

       ...