diff options
| -rw-r--r-- | frontend/site/projects/museum/views/petros.nav.css | 19 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/petros.nav.js | 7 | ||||
| -rw-r--r-- | frontend/site/projects/museum/views/petros.text.js | 57 |
3 files changed, 79 insertions, 4 deletions
diff --git a/frontend/site/projects/museum/views/petros.nav.css b/frontend/site/projects/museum/views/petros.nav.css index 1a68032..6720f5f 100644 --- a/frontend/site/projects/museum/views/petros.nav.css +++ b/frontend/site/projects/museum/views/petros.nav.css @@ -1,16 +1,18 @@ .petros-left { position: absolute; - bottom: 70px; + bottom: 50px; left: 40px; cursor: pointer; opacity: 0.0; + transform: scale(0.9); transition: opacity 0.4s; pointer-events: none; } .petros-right { position: absolute; - bottom: 70px; + bottom: 50px; right: 40px; + transform: scale(0.9); cursor: pointer; opacity: 0.0; transition: opacity 0.4s; @@ -40,9 +42,20 @@ max-width: calc(100vw - 400px); text-align: center; font-family: 'Druk Wide', sans-serif; - font-size: 2vw; + font-size: 1.5vw; pointer-events: none; color: #fff; text-shadow: 0 0 3px #fff; transition: opacity 0.4s; } + +.fade-words span { + opacity: 0; + transition: opacity 0.2s; +} +.fade-words span:after { + content: ' '; +} +.fade-words span.visible { + opacity: 1; +} diff --git a/frontend/site/projects/museum/views/petros.nav.js b/frontend/site/projects/museum/views/petros.nav.js index db7737b..fda1bb8 100644 --- a/frontend/site/projects/museum/views/petros.nav.js +++ b/frontend/site/projects/museum/views/petros.nav.js @@ -12,6 +12,8 @@ import { preloadImage } from "app/utils" import actions from "site/actions" import { generateTransform } from 'app/views/tile/tile.utils' +import PetrosText from "./petros.text" + const RESET_STATE = { ready: false, hovering: null, @@ -57,6 +59,8 @@ const TEXT_HIDE_TIMEOUT = 15000 *FASTFORWARD const SUBTITLE_COUNT = 12 +const TIME_PER_WORD = 250 + class PetrosNav extends Component { state = { ...RESET_STATE, @@ -68,6 +72,7 @@ class PetrosNav extends Component { this.handleEnter = this.handleEnter.bind(this) this.handleLeave = this.handleLeave.bind(this) this.handleClickText = this.handleClickText.bind(this) + this.textComplete = this.textComplete.bind(this) this.navigate = this.navigate.bind(this) } @@ -276,7 +281,7 @@ class PetrosNav extends Component { )} {!textActive && text && ( <div className="petros-subtitle" style={{ opacity: textOpacity }}> - {text} + <PetrosText ready={textOpacity} text={text} timePerWord={TIME_PER_WORD} onComplete={this.textComplete} /> </div> )} </div> diff --git a/frontend/site/projects/museum/views/petros.text.js b/frontend/site/projects/museum/views/petros.text.js new file mode 100644 index 0000000..96f5565 --- /dev/null +++ b/frontend/site/projects/museum/views/petros.text.js @@ -0,0 +1,57 @@ +/** + * Text special effect for Petros where each word fades in + */ + +import React, { Component } from 'react' + +export class PetrosText extends Component { + constructor(props) { + super(props) + this.state = { index: 0, words: [] } + this.next = this.next.bind(this) + } + + componentDidUpdate(prevProps) { + if (this.props.ready && !prevProps.ready) { + this.start() + } else { + clearTimeout(this.timeout) + } + } + + componentDidUnmount() { + clearTimeout(this.timeout) + } + + start() { + const { perWord, text } = this.props + this.setState({ + words: this.props.text.trim().split(" "), + index: -1 + }) + clearTimeout(this.timeout) + this.timeout = setTimeout(this.next, perWord) + } + + next() { + const { timePerWord, onComplete } = this.props + const { index, words } = this.state + if (index < words.length) { + this.timeout = setTimeout(this.next, timePerWord) + this.setState({ index: index + 1 }) + } else { + onComplete() + } + } + + render() { + const { index, words } = this.state + return ( + <div className="fade-words"> + {words.map((word, i) => ( + <span key={i} className={i <= index ? "visible" : ""}>{word}</span> + ))} + </div> + ) + } +} |
