adding about screen with video

This commit is contained in:
Yotam Mann 2017-01-13 16:47:58 -05:00
parent 8bb728c2e0
commit 27564c9791
5 changed files with 410 additions and 39 deletions

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-335 665 180 180" enable-background="new -335 665 180 180" xml:space="preserve">
<path d="M-245,669c-47.5,0-86,38.5-86,86s38.5,86,86,86s86-38.5,86-86S-197.5,669-245,669z"/>
<g>
<g>
<g>
<path fill="#FFFFFF" d="M-261.9,720.9c-0.5-0.3-0.8-0.1-0.8,0.4v67.2c0,0.5,0.4,0.7,0.8,0.4l49.9-33.5c0.5-0.3,0.5-0.8,0-1.1
L-261.9,720.9z"/>
</g>
<g>
<path fill="#FFFFFF" d="M-262.8,789.6v-69.2"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 711 B

View File

@ -0,0 +1,118 @@
/**
* Copyright 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'style/about.css'
import YouTubeIframeLoader from 'youtube-iframe'
import events from 'events'
const magentaLink = 'https://github.com/tensorflow/magenta'
const sourceCode = 'https://github.com/googlecreativelab/aiexperiments-ai-duet'
const toneLink = 'https://github.com/Tonejs/Tone.js'
const blurbCopy = `Built by Yotam Mann with friends on the Magenta and Creative Lab teams at Google.
It uses <a target='_blank' href='${toneLink}'>Tone.js</a> and tools
from the <a target='_blank' href='${magentaLink}'>Magenta project</a>.
The open-source code is <a target='_blank' href='${sourceCode}'>available here</a>.`
export class About extends events.EventEmitter{
constructor(container){
super()
this._container = document.createElement('div')
this._container.id = 'about'
container.appendChild(this._container)
this._toggleButton = document.createElement('div')
this._toggleButton.id = 'aboutButton'
this._toggleButton.classList.add('open')
container.appendChild(this._toggleButton)
this._toggleButton.addEventListener('click', (e) => {
e.preventDefault()
if (this.isOpen()){
this.close()
} else {
this.open()
}
})
const content = document.createElement('div')
content.id = 'content'
this._container.appendChild(content)
const title = document.createElement('div')
title.id = 'title'
title.textContent = 'A.I. Duet'
content.appendChild(title)
const video = document.createElement('div')
video.id = 'video'
//vid YT0k99hCY5I
video.innerHTML = `<iframe id='youtube-iframe' src="https://www.youtube.com/embed/0ZE1bfPtvZo?modestbranding=0&showinfo=0&enablejsapi=1" frameborder="0" allowfullscreen></iframe>`
content.appendChild(video)
this._ytplayer = null
this._playButton = document.createElement('div')
this._playButton.id = 'playButton'
this._playButton.classList.add('visible')
video.appendChild(this._playButton)
YouTubeIframeLoader.load((YT) => {
this._ytplayer = new YT.Player('youtube-iframe', {
events : {
onStateChange : (state) => {
this._playButton.classList.remove('visible')
}
}
})
})
const blurb = document.createElement('div')
blurb.id = 'blurb'
content.appendChild(blurb)
blurb.innerHTML = blurbCopy
}
close(){
this._toggleButton.classList.remove('close')
this._toggleButton.classList.add('open')
this._container.classList.remove('visible')
if (this._ytplayer){
this._ytplayer.stopVideo()
}
this.emit('close')
if (window.ga){
ga('send', 'event', 'AI-Duet', 'Click', 'About - Close')
}
}
open(){
this._toggleButton.classList.add('close')
this._toggleButton.classList.remove('open')
this._playButton.classList.add('visible')
this._container.classList.add('visible')
this.emit('open')
if (window.ga){
ga('send', 'event', 'AI-Duet', 'Click', 'About - Open')
}
}
isOpen(){
return this._container.classList.contains('visible')
}
}

View File

@ -23,7 +23,7 @@ class Splash extends events.EventEmitter{
constructor(container){ constructor(container){
super() super()
const splash = document.createElement('div') const splash = this._splash = document.createElement('div')
splash.id = 'splash' splash.id = 'splash'
container.appendChild(splash) container.appendChild(splash)
@ -42,26 +42,39 @@ class Splash extends events.EventEmitter{
titleContainer.appendChild(subTitle) titleContainer.appendChild(subTitle)
subTitle.textContent = 'Trade melodies with a neural network.' subTitle.textContent = 'Trade melodies with a neural network.'
const loader = new Loader(titleContainer) this._clicked = false
const loader = this._loader = new Loader(titleContainer)
loader.on('click', () => { loader.on('click', () => {
splash.classList.add('disappear') splash.classList.add('disappear')
this._clicked = true
this.emit('click') this.emit('click')
}) })
const magenta = document.createElement('div')
magenta.id = 'magentaLink'
titleContainer.appendChild(magenta)
magenta.innerHTML = 'Built using <a href="https://github.com/tensorflow/magenta" target="_blank">Magenta</a>'
const badges = document.createElement('div')
badges.id = 'badges'
splash.appendChild(badges)
const aiExperiments = document.createElement('a') const aiExperiments = document.createElement('a')
aiExperiments.id = 'aiExperiments' aiExperiments.id = 'aiExperiments'
aiExperiments.href = 'https://aiexperiments.withgoogle.com' aiExperiments.href = 'https://aiexperiments.withgoogle.com'
aiExperiments.target = '_blank' aiExperiments.target = '_blank'
splash.appendChild(aiExperiments) aiExperiments.classList.add('badge')
badges.appendChild(aiExperiments)
// break // break
const badgeBreak = document.createElement('div') const badgeBreak = document.createElement('div')
badgeBreak.id = 'badgeBreak' badgeBreak.id = 'badgeBreak'
splash.appendChild(badgeBreak) badges.appendChild(badgeBreak)
const googleFriends = document.createElement('a') const googleFriends = document.createElement('a')
googleFriends.id = 'googleFriends' googleFriends.id = 'googleFriends'
splash.appendChild(googleFriends) googleFriends.classList.add('badge')
badges.appendChild(googleFriends)
const privacyAndTerms = document.createElement('div') const privacyAndTerms = document.createElement('div')
privacyAndTerms.id = 'privacyAndTerms' privacyAndTerms.id = 'privacyAndTerms'
@ -69,6 +82,22 @@ class Splash extends events.EventEmitter{
splash.appendChild(privacyAndTerms) splash.appendChild(privacyAndTerms)
} }
get loaded(){
return this._loader.loaded
}
isOpen(){
return !this._clicked
}
show(){
this._splash.classList.remove('disappear')
}
hide(){
this._splash.classList.add('disappear')
}
} }
export {Splash} export {Splash}

155
static/style/about.css Normal file
View File

@ -0,0 +1,155 @@
/**
* Copyright 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import 'common.scss';
#aboutButton {
$closeSize : 30px;
position: absolute;
top: 15px;
right: 15px;
width: $closeSize;
height: $closeSize;
cursor: pointer;
z-index: 1000;
transition: transform 0.1s;
text-align: center;
&:hover {
transform: scale(1.1);
}
&:before{
font-family: $font-family;
font-weight: bold;
width: 100%;
height: 100%;
position: absolute;
top: 0px;
right: 0px;
line-height: $closeSize;
}
&.close:before{
content: "✕";
font-size: 25px;
color: white;
background-color: transparent;
}
&.open:before{
content: "?";
background-color: white;
border-radius: 50%;
}
}
#about {
width: 100%;
height: 100%;
z-index: 10;
top: 0px;
left: 0px;
position: absolute;
overflow-y: auto;
display: none;
&.visible {
display: initial;
}
#content {
width: 90%;
margin: 50px auto 30px auto;
min-width: 300px;
max-width: 800px;
height: auto;
position: relative;
color: white;
font-family: $font-family;
position: relative;
#title {
font-family: $font-family;
font-size: 40px;
line-height: 30px;
margin: 20px 0px 30px 0px;
position: relative;
}
$smallScreen : 450px;
$mediumScreen : 700px;
#video {
width: 100%;
cursor: pointer;
position: relative;
@media (max-width: $smallScreen) {
height: 200px;
}
@media (min-width: $smallScreen) and (max-width: $mediumScreen) {
height: 380px;
}
@media (min-width: $mediumScreen){
height: 450px;
}
iframe {
width: 100%;
height: 100%;
}
#playButton {
pointer-events: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
background-image: url(../images/play_button.svg);
background-size: 100% 100%;
display: none;
&.visible {
display: initial;
}
}
&:hover #playButton svg{
fill: blue;
}
}
#blurb {
position: relative;
text-transform: none;
margin-top: 30px;
font-size: 16px;
line-height: 25px;
a {
color: $orange;
}
}
}
}

View File

@ -1,6 +1,6 @@
@import 'common.scss'; @import 'common.scss';
$topMargin: 50px; $topMargin: 40px;
#splash { #splash {
position: absolute; position: absolute;
@ -9,7 +9,7 @@ $topMargin: 50px;
top: 0px; top: 0px;
left: 0px; left: 0px;
z-index: 100; z-index: 100;
font-family: 'Quicksand', sans-serif; font-family: $font-family;
font-weight: bold; font-weight: bold;
color: white; color: white;
transition: opacity 0.2s; transition: opacity 0.2s;
@ -54,6 +54,30 @@ $topMargin: 50px;
font-weight: normal; font-weight: normal;
} }
#magentaLink {
margin-top: $topMargin * 0.8;
letter-spacing: 0.8px;
line-height: 30px;
font-size: 20px;
width: 100%;
margin-left: auto;
margin-right: auto;
text-align: center;
font-weight: normal;
color: #aaa;
font-size: 14px;
a {
color: $orange;
text-decoration: underline;
cursor: pointer;
&:hover:active {
color: white;
}
}
}
$loaderWidth: 200px; $loaderWidth: 200px;
$loaderHeight: 60px; $loaderHeight: 60px;
@ -144,50 +168,78 @@ $topMargin: 50px;
margin-top: $topMargin; margin-top: $topMargin;
} }
$badgeWidth : 80px; $badgeWidth : 110px;
$badgeHeight: 50px; $badgeHeight: 60px;
$badgeMargin : 20px; $badgeMargin : 20px;
$badegOpacity: 0.7; $badegOpacity: 0.7;
#aiExperiments, #googleFriends { $smallScreen : 500px;
width: $badgeWidth; $smallBadgeWidth : 70px;
height: $badgeHeight; $smallBadgeHeight: 40px;
#badges {
position: absolute; position: absolute;
display: inline-block;
bottom: $badgeMargin; bottom: $badgeMargin;
opacity: $badegOpacity;
background-repeat: no-repeat;
background-size: 100% 100%;
}
#aiExperiments {
left: $badgeMargin; left: $badgeMargin;
background-image: url(../images/badgeAI_master.svg);
&:hover { @media (max-width: $smallScreen) {
opacity: 1; // bottom: $badgeMargin * 0.5;
}
&:active { .badge {
opacity: 0.3; display: inline-block;
position: relative;
margin-right: $badgeMargin;
width: $badgeWidth;
height: $badgeHeight;
background-repeat: no-repeat;
background-size: 100% 100%;
opacity: $badegOpacity;
@media (max-width: $smallScreen) {
width: $smallBadgeWidth;
height: $smallBadgeHeight;
}
}
#aiExperiments {
background-image: url(../images/badgeAI_master.svg);
&:hover {
opacity: 1;
&:active {
opacity: 0.3;
}
}
}
#googleFriends {
cursor: initial;
background-image: url(../images/badgeFriends_master.svg);
}
#badgeBreak{
display: inline-block;
position: relative;
margin-right: $badgeMargin;
$breakScale : 0.95;
$breakHeight: $badgeHeight * $breakScale;
height: $breakHeight;
background-color: white;
opacity: $badegOpacity / 2;
width: 1px;
@media (max-width: $smallScreen) {
$smallBreakHeight: $smallBadgeHeight * $breakScale;
height: $smallBreakHeight;
} }
} }
} }
#googleFriends {
cursor: initial;
left: $badgeWidth + $badgeMargin * 3;
background-image: url(../images/badgeFriends_master.svg);
}
#badgeBreak{
$breakHeight: $badgeHeight * 0.8;
height: $breakHeight;
left: $badgeWidth + $badgeMargin * 1.8;
background-color: white;
opacity: $badegOpacity / 2;
position: absolute;
width: 1px;
bottom: $badgeMargin + ($badgeHeight - $breakHeight) / 2;
}
#privacyAndTerms { #privacyAndTerms {
position: absolute; position: absolute;
@ -199,7 +251,7 @@ $topMargin: 50px;
* { * {
height: 14px; height: 14px;
line-height: 14px; line-height: 14px;
font-size: 14px; font-size: 10px;
color: white; color: white;
display: inline; display: inline;
opacity: $badegOpacity; opacity: $badegOpacity;