Mithril Animated
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
svg {
height: 450px;
width: 90%;
border: 1px solid #DEDEDE;
}
svg path {
fill: transparent;
}
svg text {
cursor: inherit;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
path {
fill: rgba(200, 200, 200, 1);
stroke: black;
}
rect {
stroke: black;
fill: rgba(200, 200, 200, 1);
}
.app-hdr {
background-color: #efefef;
margin-bottom: 10px;
padding: 5px;
width: 90%;
}
.app-hdr > button {
font-weight: bold;
margin-right: 2px;
}
.note {
color: grey;
font-family: monospace;
font-size: 0.9em;
}
.app-hdr > .note {
display: none;
}
.line {
border-bottom: inset;
width: 90%;
}
.square {
background-color: cyan;
height: 25px;
width: 25px;
}
.stretched {
height: 2px;
margin-bottom: 2px;
}
.circle {
background-color: cyan;
border-radius: 50%;
height: 25px;
width: 25px;
}
.triangle {
border-color: transparent transparent cyan transparent;
border-style: solid;
border-width: 0 14px 24px 14px;
height: 0;
pointer-events: none;
position: relative;
width: 0;
}
.demos {
display: flex;
flex-wrap: wrap;
width: 90%;
}
.demo {
box-sizing: border-box;
flex: 1 0 300px;
margin-bottom: 20px;
}
.demo-hdr {
font-family: monospace;
margin-bottom: 5px;
}
.timeline-controls button {
border-radius: 5px;
width: 60px;
}
.timeline-controls input[type='range'] {
position: relative;
top: 5px;
width: 100px;
}
.switch-widget {
overflow-x: hidden;
}
.widget {
border-radius: 3px;
cursor: pointer;
font-size: x-large;
padding: 5px 10px;
width: 175px
}
.widget > .note {
font-size: x-small;
}
.widget1 {
background-color: cyan;
}
.widget2 {
border: 3px solid cyan;
}
.switch-route {
align-items: center;
border: 1px solid grey;
border-radius: 5px;
display: flex;
height: 50px;
...
JavaScript
/* https://github.com/pakx/the-mithril-diaries/wiki/ui-animation/AnimeJS#gallery-main */
function main() {
var settings = {
paths: [{
name: "A",
route: "/A"
}, {
name: "B",
route: "/B"
}]
},
model = createModel(settings),
actions = createActions(model),
routeResolver = createRouteResolver(model, actions),
defaultRoute = settings.paths[0].route
m.route(document.body, defaultRoute, routeResolver)
}
function createModel(settings) {
var elasticItems = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
initialStates = [{
translateX: 0
}, {
rotate: "0turn",
scale: 1
}, {
rotate: 0,
scale: 1,
translateX: 0
}, {
elasticItems: elasticItems.map(function(itm) {
return {
translateX: 0
}
})
}, {
backgroundColor: "#00FFFF",
translateX: 0
}, {
height: 25,
translateX: 0,
width: 25
}, {
square: {
translateX: 0,
translateY: 0
},
circle: {
translateX: 0,
translateY: 0
},
triangle: {
translateX: 0,
translateY: 0
},
progress: 0,
callbacks: {} // populated in createActions()
}, {
points: "64 69.17821114346133 8.574" + " 99.96373240273172 62.94848110067368 67.35649303236691" + " 64 3.9637324027317162 65.05151889932631 67.35649303236691" + " 119.426 99.96373240273172"
}
// switch-widgets
, {
translateX: 0,
widgetId: 0,
isAnimating: false
}
// switch-route
, {
rotate: 0,
scale: 1,
translateX: 0,
opacity: 1,
isAnimating: false
}
]
return {
paths: settings.paths.slice(),
routeName: undefined,
viewstate: {
demos: initialStates.map(function(itm, idx) {
return Object.assign(itm, {
...