split demo vue templates into separate files

This commit is contained in:
Leon Chen
2016-10-06 03:03:12 -04:00
parent c49b74dde2
commit 4b546dc56c
19 changed files with 321 additions and 206 deletions
-1
View File
@@ -1,2 +1 @@
*.buf filter=lfs diff=lfs merge=lfs -text
notebooks/* linguist-documentation
+1 -1
View File
@@ -15,7 +15,7 @@ body {
}
#github-corner-link:hover {
background-color: rgba(27, 188, 155, 0.7);
background-color: rgba(27, 188, 155, 0.6);
}
#github-corner-link .github-logo {
+1 -1
View File
@@ -16,7 +16,7 @@
<div id="app">
<div class="columns">
<div class="column is-3" style="min-width: 350px; max-width: 450px;">
<menu></menu>
<menu :current-view="currentView"></menu>
</div>
<div class="column is-9">
<component :is="currentView"></component>
+2
View File
@@ -1,4 +1,6 @@
$color-1: #1BBC9B;
$color-1-light: rgba(27, 188, 155, 0.6);
$color-1-lighter: rgba(27, 188, 155, 0.3);
$color-2: #69707a;
$color-3: #393E46;
+1 -7
View File
@@ -1,12 +1,6 @@
/* global Vue */
import './home.css'
export const Home = Vue.extend({
template: `
<div class="demo home">
<div class="title">Home</div>
</div>
`
template: require('raw!./home.template.html')
})
+3
View File
@@ -0,0 +1,3 @@
<div class="demo home">
<div class="title"><span>Home</span></div>
</div>
+56 -4
View File
@@ -13,10 +13,14 @@ body {
.title {
width: 100%;
color: $color-1;
display: flex;
flex-direction: row;
align-items: center;
span {
color: $color-1;
margin-right: 20px;
}
}
.subtitle {
@@ -50,11 +54,59 @@ body {
.mdl-switch.is-checked {
.mdl-switch__thumb {
background: rgba(27, 188, 155, 0.6);
background: $color-1-light;
}
.mdl-switch__track {
background: $color-1-lighter;
}
}
.mdl-textfield {
.mdl-textfield__input {
border-bottom-color: $color-1-light;
font-family: $font-2;
font-size: 16px;;
}
.mdl-switch__track {
background: rgba(27, 188, 155, 0.3);
.mdl-textfield__label {
font-family: $font-2;
color: $color-1-light;
}
.mdl-icon-toggle__label {
color: $color-1-light;
}
}
.mdl-textfield.is-focused {
.mdl-textfield__input {
border-color: $color-1;
}
.mdl-textfield__label {
color: $color-1;
&::after {
background-color: $color-1;
}
}
.mdl-icon-toggle__label {
color: $color-1;
}
}
.mdl-menu {
.mdl-menu__item {
font-family: $font-2;
font-size: 16px;;
color: $color-2;
&:hover {
background-color: $color-1-light;
color: white;
}
}
}
}
+4 -1
View File
@@ -6,11 +6,13 @@ import { Menu } from './menu'
import { Home } from './home'
import { MnistCnn } from './mnist-cnn'
import { MnistVae } from './mnist-vae'
import { ResNet50 } from './resnet50'
Vue.component('menu', Menu)
Vue.component('home', Home)
Vue.component('mnist-cnn', MnistCnn)
Vue.component('mnist-vae', MnistVae)
Vue.component('resnet50', ResNet50)
Vue.use(VueMdl.default)
@@ -26,7 +28,8 @@ const app = new Vue({
function matchRoute () {
const routes = [
'mnist-cnn',
'mnist-vae'
'mnist-vae',
'resnet50'
]
const { hash } = window.location
+9 -4
View File
@@ -5,7 +5,7 @@
margin: 20px;
background: white;
border-radius: 10px;
box-shadow: 6px 6px #CCCCCC;
box-shadow: 5px 5px #CCCCCC;
h1 {
color: #CCCCCC;
@@ -16,6 +16,11 @@
.menu-list {
li {
color: $color-2;
border-left: 2px solid white;
}
li.active {
border-left: 2px solid $color-1;
}
a {
@@ -44,14 +49,14 @@
}
a {
color: #AAAAAA;
color: $color-1;
padding: 0;
display: inline-flex;
background-color: none;
transition: color 0.2s ease-in;
&hover {
color: $color-1;
&:hover {
color: $color-1-light;
background: none;
}
}
+2 -33
View File
@@ -1,38 +1,7 @@
/* global Vue */
import './menu.css'
export const Menu = Vue.extend({
template: `
<aside class="menu">
<h1>Keras.js Demos</h1>
<p class="menu-label">
Demos
</p>
<ul class="menu-list">
<li><a href="#/">Home</a></li>
<li><a href="#/mnist-cnn">Basic Convnet - MNIST</a></li>
<li><a href="#/mnist-vae">Convolutional VAE - MNIST</a></li>
</ul>
<p class="menu-label">
Links
</p>
<ul class="menu-list">
<li>
<a href="https://github.com/transcranial/keras-js" target="_blank">
<svg height="24" width="24" class="github-logo" viewBox="0 0 16 16" version="1.1" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
GitHub repo
</a>
</li>
</ul>
<p class="menu-label">
Contact
</p>
<ul class="menu-list contact">
<li><a href="https://github.com/transcranial" target="_blank">Leon Chen <@transcranial></a></li>
<li></li>
</ul>
</aside>
`
props: ['currentView'],
template: require('raw!./menu.template.html')
})
+30
View File
@@ -0,0 +1,30 @@
<aside class="menu">
<h1>Keras.js Demos</h1>
<p class="menu-label">
Demos
</p>
<ul class="menu-list">
<li v-bind:class="{ 'active': currentView === 'home' }"><a href="#/">Home</a></li>
<li v-bind:class="{ 'active': currentView === 'mnist-cnn' }"><a href="#/mnist-cnn">Basic Convnet - MNIST</a></li>
<li v-bind:class="{ 'active': currentView === 'mnist-vae' }"><a href="#/mnist-vae">Convolutional VAE - MNIST</a></li>
<li v-bind:class="{ 'active': currentView === 'resnet50' }"><a href="#/resnet50">Residual Network (50-layer) - ImageNet</a></li>
</ul>
<p class="menu-label">
Links
</p>
<ul class="menu-list">
<li>
<a href="https://github.com/transcranial/keras-js" target="_blank">
<svg height="24" width="24" class="github-logo" viewBox="0 0 16 16" version="1.1" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
GitHub repo
</a>
</li>
</ul>
<p class="menu-label">
Contact
</p>
<ul class="menu-list contact">
<li><a href="https://github.com/transcranial" target="_blank">Leon Chen <@transcranial></a></li>
<li></li>
</ul>
</aside>
+4 -4
View File
@@ -34,11 +34,11 @@
display: inline-flex;
justify-content: flex-end;
margin: 10px 0;
border: 15px solid rgba(27, 188, 155, 0.3);
border: 15px solid $color-1-lighter;
transition: border-color 0.2s ease-in;
&:hover {
border-color: rgba(27, 188, 155, 0.6);
border-color: $color-1-light;
}
canvas {
@@ -58,7 +58,7 @@
transition: color 0.2s ease-in;
&:hover {
color: rgba(27, 188, 155, 0.3);
color: $color-1-lighter;
cursor: pointer;
}
}
@@ -87,7 +87,7 @@
align-items: center;
justify-content: center;
padding: 0 6px;
border-bottom: 2px solid rgba(27, 188, 155, 0.3);
border-bottom: 2px solid $color-1-lighter;
.output-label {
font-family: 'Inconsolata', sans-serif;
+1 -74
View File
@@ -1,5 +1,4 @@
/* global Vue */
import './mnist-cnn.css'
import debounce from 'lodash/debounce'
@@ -82,79 +81,7 @@ const LAYER_DISPLAY_CONFIG = {
*
*/
export const MnistCnn = Vue.extend({
template: `
<div class="demo mnist-cnn">
<div class="title">Basic Convnet for MNIST</div>
<div class="loading-progress" v-if="modelLoading && loadingProgress < 100">
Loading...{{ loadingProgress }}%
</div>
<div class="columns input-output">
<div class="column input-column">
<div class="input-container">
<div class="input-label">Draw any digit (0-9) here <span class="arrow">⤸</span></div>
<div class="canvas-container">
<canvas
id="input-canvas" width="240" height="240"
@mousedown="activateDraw"
@mouseup="deactivateDrawAndPredict"
@mouseleave="deactivateDrawAndPredict"
@mousemove="draw"
@touchstart="activateDraw"
@touchend="deactivateDrawAndPredict"
@touchmove="draw"
></canvas>
<canvas id="input-canvas-scaled" width="28" height="28" style="display:none;"></canvas>
<canvas id="input-canvas-centercrop" style="display:none;"></canvas>
</div>
<div class="input-clear" v-on:click="clear">
<i class="material-icons">clear</i>CLEAR
</div>
</div>
</div>
<div class="column is-2 controls-column">
<mdl-switch :checked.sync="useGpu" @click="toggleGpu">Use GPU</mdl-switch>
</div>
<div class="column output-column">
<div class="output">
<div class="output-class"
v-bind:class="{ 'predicted': i === predictedClass }"
v-for="i in outputClasses"
>
<div class="output-label">{{ i }}</div>
<div class="output-bar"
style="height: {{ Math.round(100 * output[i]) }}px; background: rgba(27, 188, 155, {{ output[i].toFixed(2) }});"
></div>
</div>
</div>
</div>
</div>
<div class="layer-results-container">
<div class="bg-line"></div>
<div
v-for="layerResult in layerResultImages"
class="layer-result"
>
<div class="layer-result-heading">
<span class="layer-class">{{ layerResult.layerClass }}</span>
<span> {{ layerDisplayConfig[layerResult.name].heading }}</span>
</div>
<div class="layer-result-canvas-container">
<canvas v-for="image in layerResult.images"
id="intermediate-result-{{ $parent.$index }}-{{ $index }}"
width="{{ image.width }}"
height="{{ image.height }}"
style="display:none;"
></canvas>
<canvas v-for="image in layerResult.images"
id="intermediate-result-{{ $parent.$index }}-{{ $index }}-scaled"
width="{{ layerDisplayConfig[layerResult.name].scalingFactor * image.width }}"
height="{{ layerDisplayConfig[layerResult.name].scalingFactor * image.height }}"
></canvas>
</div>
</div>
</div>
</div>
`,
template: require('raw!./mnist-cnn.template.html'),
data: function () {
return {
+74
View File
@@ -0,0 +1,74 @@
<div class="demo mnist-cnn">
<div class="title">
<span>Basic Convnet for MNIST</span>
<mdl-spinner v-if="modelLoading && loadingProgress < 100"></mdl-spinner>
</div>
<div class="loading-progress" v-if="modelLoading && loadingProgress < 100">
Loading...{{ loadingProgress }}%
</div>
<div class="columns input-output">
<div class="column input-column">
<div class="input-container">
<div class="input-label">Draw any digit (0-9) here <span class="arrow"></span></div>
<div class="canvas-container">
<canvas
id="input-canvas" width="240" height="240"
@mousedown="activateDraw"
@mouseup="deactivateDrawAndPredict"
@mouseleave="deactivateDrawAndPredict"
@mousemove="draw"
@touchstart="activateDraw"
@touchend="deactivateDrawAndPredict"
@touchmove="draw"
></canvas>
<canvas id="input-canvas-scaled" width="28" height="28" style="display:none;"></canvas>
<canvas id="input-canvas-centercrop" style="display:none;"></canvas>
</div>
<div class="input-clear" v-on:click="clear">
<i class="material-icons">clear</i>CLEAR
</div>
</div>
</div>
<div class="column is-2 controls-column">
<mdl-switch :checked.sync="useGpu" @click="toggleGpu">Use GPU</mdl-switch>
</div>
<div class="column output-column">
<div class="output">
<div class="output-class"
v-bind:class="{ 'predicted': i === predictedClass }"
v-for="i in outputClasses"
>
<div class="output-label">{{ i }}</div>
<div class="output-bar"
style="height: {{ Math.round(100 * output[i]) }}px; background: rgba(27, 188, 155, {{ output[i].toFixed(2) }});"
></div>
</div>
</div>
</div>
</div>
<div class="layer-results-container">
<div class="bg-line"></div>
<div
v-for="layerResult in layerResultImages"
class="layer-result"
>
<div class="layer-result-heading">
<span class="layer-class">{{ layerResult.layerClass }}</span>
<span> {{ layerDisplayConfig[layerResult.name].heading }}</span>
</div>
<div class="layer-result-canvas-container">
<canvas v-for="image in layerResult.images"
id="intermediate-result-{{ $parent.$index }}-{{ $index }}"
width="{{ image.width }}"
height="{{ image.height }}"
style="display:none;"
></canvas>
<canvas v-for="image in layerResult.images"
id="intermediate-result-{{ $parent.$index }}-{{ $index }}-scaled"
width="{{ layerDisplayConfig[layerResult.name].scalingFactor * image.width }}"
height="{{ layerDisplayConfig[layerResult.name].scalingFactor * image.height }}"
></canvas>
</div>
</div>
</div>
</div>
+2 -2
View File
@@ -35,11 +35,11 @@
display: inline-flex;
justify-content: flex-end;
margin: 10px 0;
border: 15px solid rgba(27, 188, 155, 0.3);
border: 15px solid $color-1-lighter;
transition: border-color 0.2s ease-in;
&:hover {
border-color: rgba(27, 188, 155, 0.6);
border-color: $color-1-light;
}
canvas {
+1 -74
View File
@@ -1,5 +1,4 @@
/* global Vue */
import './mnist-vae.css'
import * as utils from './utils'
@@ -60,79 +59,7 @@ const LAYER_DISPLAY_CONFIG = {
*
*/
export const MnistVae = Vue.extend({
template: `
<div class="demo mnist-vae">
<div class="title">Convolutional Variational Autoencoder, trained on MNIST</div>
<div class="loading-progress" v-if="modelLoading && loadingProgress < 100">
Loading...{{ loadingProgress }}%
</div>
<div class="columns input-output">
<div class="column input-column">
<div class="input-container">
<div class="input-label">Click around the latent space <span class="arrow">⤸</span></div>
<div class="canvas-container">
<canvas
id="input-canvas" width="200" height="200"
@mouseenter="activateCrosshairs"
@mouseleave="deactivateCrosshairs"
@mousemove="draw"
@click="selectCoordinates"
@touchend="selectCoordinates"
></canvas>
<div class="axis x-axis">
<span>-1.5</span>
<span>x</span>
<span>1.5</span>
</div>
<div class="axis y-axis">
<span>-1.5</span>
<span>y</span>
<span>1.5</span>
</div>
</div>
</div>
</div>
<div class="column is-2 controls-column">
<mdl-switch :checked.sync="useGpu" @click="toggleGpu">Use GPU</mdl-switch>
<div class="coordinates">
<div class="coordinates-x">x: {{ inputCoordinates[0] < 0 ? inputCoordinates[0].toFixed(2) : inputCoordinates[0].toFixed(3) }}</div>
<div class="coordinates-y">y: {{ inputCoordinates[1] < 0 ? inputCoordinates[1].toFixed(2) : inputCoordinates[1].toFixed(3) }}</div>
</div>
</div>
<div class="column output-column">
<div class="output">
<canvas id="output-canvas-scaled" width="150" height="150"></canvas>
<canvas id="output-canvas" width="27" height="27" style="display:none;"></canvas>
</div>
</div>
</div>
<div class="layer-results-container">
<div class="bg-line"></div>
<div
v-for="layerResult in layerResultImages"
class="layer-result"
>
<div class="layer-result-heading">
<span class="layer-class">{{ layerResult.layerClass }}</span>
<span> {{ layerDisplayConfig[layerResult.name].heading }}</span>
</div>
<div class="layer-result-canvas-container">
<canvas v-for="image in layerResult.images"
id="intermediate-result-{{ $parent.$index }}-{{ $index }}"
width="{{ image.width }}"
height="{{ image.height }}"
style="display:none;"
></canvas>
<canvas v-for="image in layerResult.images"
id="intermediate-result-{{ $parent.$index }}-{{ $index }}-scaled"
width="{{ layerDisplayConfig[layerResult.name].scalingFactor * image.width }}"
height="{{ layerDisplayConfig[layerResult.name].scalingFactor * image.height }}"
></canvas>
</div>
</div>
</div>
</div>
`,
template: require('raw!./mnist-vae.template.html'),
data: function () {
return {
+74
View File
@@ -0,0 +1,74 @@
<div class="demo mnist-vae">
<div class="title">
<span>Convolutional Variational Autoencoder, trained on MNIST</span>
<mdl-spinner v-if="modelLoading && loadingProgress < 100"></mdl-spinner>
</div>
<div class="loading-progress" v-if="modelLoading && loadingProgress < 100">
Loading...{{ loadingProgress }}%
</div>
<div class="columns input-output">
<div class="column input-column">
<div class="input-container">
<div class="input-label">Click around the latent space <span class="arrow"></span></div>
<div class="canvas-container">
<canvas
id="input-canvas" width="200" height="200"
@mouseenter="activateCrosshairs"
@mouseleave="deactivateCrosshairs"
@mousemove="draw"
@click="selectCoordinates"
@touchend="selectCoordinates"
></canvas>
<div class="axis x-axis">
<span>-1.5</span>
<span>x</span>
<span>1.5</span>
</div>
<div class="axis y-axis">
<span>-1.5</span>
<span>y</span>
<span>1.5</span>
</div>
</div>
</div>
</div>
<div class="column is-2 controls-column">
<mdl-switch :checked.sync="useGpu" @click="toggleGpu">Use GPU</mdl-switch>
<div class="coordinates">
<div class="coordinates-x">x: {{ inputCoordinates[0] < 0 ? inputCoordinates[0].toFixed(2) : inputCoordinates[0].toFixed(3) }}</div>
<div class="coordinates-y">y: {{ inputCoordinates[1] < 0 ? inputCoordinates[1].toFixed(2) : inputCoordinates[1].toFixed(3) }}</div>
</div>
</div>
<div class="column output-column">
<div class="output">
<canvas id="output-canvas-scaled" width="150" height="150"></canvas>
<canvas id="output-canvas" width="27" height="27" style="display:none;"></canvas>
</div>
</div>
</div>
<div class="layer-results-container">
<div class="bg-line"></div>
<div
v-for="layerResult in layerResultImages"
class="layer-result"
>
<div class="layer-result-heading">
<span class="layer-class">{{ layerResult.layerClass }}</span>
<span> {{ layerDisplayConfig[layerResult.name].heading }}</span>
</div>
<div class="layer-result-canvas-container">
<canvas v-for="image in layerResult.images"
id="intermediate-result-{{ $parent.$index }}-{{ $index }}"
width="{{ image.width }}"
height="{{ image.height }}"
style="display:none;"
></canvas>
<canvas v-for="image in layerResult.images"
id="intermediate-result-{{ $parent.$index }}-{{ $index }}-scaled"
width="{{ layerDisplayConfig[layerResult.name].scalingFactor * image.width }}"
height="{{ layerDisplayConfig[layerResult.name].scalingFactor * image.height }}"
></canvas>
</div>
</div>
</div>
</div>
+55
View File
@@ -0,0 +1,55 @@
<div class="demo resnet50">
<div class="title">
<span>50-layer Residual Network, trained on ImageNet</span>
<mdl-spinner v-if="modelLoading && loadingProgress < 100"></mdl-spinner>
</div>
<div class="loading-progress" v-if="modelLoading && loadingProgress < 100">
Loading...{{ loadingProgress }}%
</div>
<div class="input-container">
<div class="input-label">Enter an image URL or select from dropdown</div>
<div class="image-url">
<mdl-textfield floating-label="enter image url" :value.sync="imageURL" spellcheck="false"></mdl-textfield>
<span>or</span>
<mdl-select label="select image" id="image-url-select" :value.sync="imageURL" :options="imageURLSelectList" style="width:200px;"></mdl-select>
</div>
</div>
<div class="columns input-output">
<div class="column input-column">
<div class="canvas-container">
<canvas id="input-canvas" width="224" height="224"></canvas>
</div>
</div>
<div class="column is-2 controls-column">
<mdl-switch :checked.sync="useGpu" @click="toggleGpu">Use GPU</mdl-switch>
</div>
<div class="column output-column">
<div class="output">
</div>
</div>
</div>
<div class="layer-results-container">
<div
v-for="layerResult in layerResultImages"
class="layer-result"
>
<div class="layer-result-heading">
<span class="layer-class">{{ layerResult.layerClass }}</span>
<span> {{ layerDisplayConfig[layerResult.name].heading }}</span>
</div>
<div class="layer-result-canvas-container">
<canvas v-for="image in layerResult.images"
id="intermediate-result-{{ $parent.$index }}-{{ $index }}"
width="{{ image.width }}"
height="{{ image.height }}"
style="display:none;"
></canvas>
<canvas v-for="image in layerResult.images"
id="intermediate-result-{{ $parent.$index }}-{{ $index }}-scaled"
width="{{ layerDisplayConfig[layerResult.name].scalingFactor * image.width }}"
height="{{ layerDisplayConfig[layerResult.name].scalingFactor * image.height }}"
></canvas>
</div>
</div>
</div>
</div>
+1
View File
@@ -58,6 +58,7 @@
"http-server": "^0.9.0",
"postcss-loader": "^0.13.0",
"precss": "^1.4.0",
"raw-loader": "^0.5.1",
"standard": "^8.3.0",
"style-loader": "^0.13.1",
"webpack": "^2.1.0-beta.25"