Mithril Animated #Mine

by Sam Fereday

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/mithril/1.1.3/mithril.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>

CSS

body {
  overflow: hidden;
}

main {
  opacity: 0;
  position: relative;
  z-index: 10;
  translateX: -250;
}

.in-transition {
  position: absolute;
  z-index: 1;
}


/*
* Skeleton V2.0.4
* Copyright 2014, Dave Gamache
* www.getskeleton.com
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
* 12/29/2014
*/


/* Table of contents
––––––––––––––––––––––––––––––––––––––––––––––––––
- Grid
- Base Styles
- Typography
- Links
- Buttons
- Forms
- Lists
- Code
- Tables
- Spacing
- Utilities
- Clearing
- Media Queries
*/


/* Grid
–––––––––––––––––––––––––––––––––––––––––––––––––– */

.container {
  position: relative;
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  padding: 0 20px;
  box-sizing: border-box;
}

.column,
.columns {
  width: 100%;
  float: left;
  box-sizing: border-box;
}


/* For devices larger than 400px */

@media (min-width: 400px) {
  .container {
    width: 85%;
    padding: 0;
  }
}


/* For devices larger than 550px */

@media (min-width: 550px) {
  .container {
    width: 80%;
  }
  .column,
  .columns {
    margin-left: 4%;
  }
  .column:first-child,
  .columns:first-child {
    margin-left: 0;
  }
  .one.column,
  .one.columns {
    width: 4.66666666667%;
  }
  .two.columns {
    width: 13.3333333333%;
  }
  .three.columns {
    width: 22%;
  }
  .four.columns {
    width: 30.6666666667%;
  }
  .five.columns {
    width: 39.3333333333%;
  }
  .six.columns {
    width: 48%;
  }
  .seven.columns {
    width: 56.6666666667%;
  }
  .eight.columns {
    width: 65.3333333333%;
  }
  .nine.columns {
    width: 74.0%;
  }
  .ten.columns {
    width: 82.6666666667%;
  }
  .eleven.columns {
    width: 91.3333333333%;
  }
  .twelve.columns {
    width: 100%;
    margin-left: 0;
  }
  .one-third.column {
    width: 30.6666666667%;
  }
  .two-thirds.column {
    width: 65.3333333333%;
  }
  .one-half.column {
    width: 48%;
  }
  /* Offsets */
  .offset-by-one.column,
  .offset-by-one.columns {
    margin-left:...

JavaScript

let root = document.body;
let durationIn = 200;
let durationOut = 200;
let delayIn = durationOut * 2;
let delayOut = 0;

/// Some animations to use
function afade(targets, goTo, duration, delay, callback) {

  return anime({
    targets: targets,
    opacity: goTo,
    duration: duration,
    delay: delay,
    update: callback,
    easing: 'linear' // Stops bouncing effect on opacity
  });

}

function aslide(targets, goTo, duration, callback) {

  return anime({
    targets: targets,
    translateX: goTo,
    duration: duration,
    update: callback
  });

}

/// Page Model (in case you'd like to keep track of routes, etc)
let pageModel = {
  routeName: ""
}

/// View Events (delayIn matches the outward transition of the previous view)
function onCreate(vnode) {
  return afade(vnode.dom, 1, durationIn, delayIn);
}

function onBeforeRemove(vnode) {
  return new Promise(function(resolve) {
    vnode.dom.classList.add("in-transition");
    afade(vnode.dom, 0, durationOut, delayOut).finished.then(function() {
      vnode.dom.classList.remove("in-transition");
      resolve();
    });
  });
}

/// 
let routeItems = [{
  "url": "splash",
  "component": {
    oncreate: onCreate,
    onbeforeremove: onBeforeRemove,
    view: function(model) {
      return m("main", [
        m("h1", {
          class: "title"
        }, "Page 1"),
        m("a", {
          href: "/hello",
          oncreate: m.route.link
        }, "Page 2")
      ]);
    }
  }
}, {
  "url": "hello",
  "component": {
    oncreate: onCreate,
    onbeforeremove: onBeforeRemove,
    view: function(model) {
      return m("main", [
        m("h1", {
          class: "title"
        }, "Page 2"),
        m("a", {
          href: "/splash",
          oncreate: m.route.link
        }, "Page 1")
      ]);
    }
  }
}]

/// Route-resolver (intercept routing calls)
function createRouteResolver(model) {

  return routeItems.reduce(function(acc, cur, i) {
    acc["/" + cur.url] = {
      onmatch: function(params,...