import anime from 'animejs/lib/anime.es.js'
import { interpolate, separate } from "flubber"
import Music from '../music'
import {$id, $class, $query, $create, ajax, analyzeAudio} from '../utils'
class Old
marquees: undefined
anchorWrapper: undefined
anchors: undefined
anchorsTooltip: undefined
# Gallery screen
screen: undefined
# Reply to indicator
replyButton: undefined
# Comment form
form: undefined
sections: [
'Status'
'About Us'
'About'
'Home'
'Music'
'Gallery'
'Comments'
]
# Fast Fourier Transform size
fft: 16
# Music class for visualization
player: undefined
# Default frequency array
frequencyArray: Array.from Array(16), ->
0
# Currently playing element
playing: undefined
# Music visualizer canvas
canvas: undefined
ctx: undefined
interpolator = separate 'M12,9l12,7l-12,7V9z', ['M10,10h4v12h-4V10z', 'M18,10h4v12h-4V10z'], { single: true }
interpolatorX = interpolate 'm30.76 25.49c-1.5812 1.5681-3.101 2.9516-4.5596 4.5197-0.60059 0.64567-0.91928 0.4612-1.4586 0-2.6965-2.7672-5.4789-5.5343-8.1754-8.3015-0.57608-0.55343-0.89476-0.55343-1.4341 0-2.672 2.7672-5.4299 5.4421-8.0896 8.2092-0.72316 0.73791-1.1154 0.64567-1.7773-0.092241-1.0909-1.1991-2.2063-2.306-3.4442-3.4128-0.89476-0.73791-0.66188-1.1991 0.061285-1.937 2.672-2.5827 5.2583-5.2576 7.9548-7.8403 0.66188-0.64567 0.68639-1.0146 0.02451-1.6603-2.672-2.5827-5.2583-5.2576-7.9548-7.8403-0.85799-0.83015-0.74768-1.2913 0.061285-2.0293 1.1522-1.0146 2.243-2.0293 3.2481-3.2284 0.68639-0.75636 1.1154-0.90394 1.9489-0.092239 2.5862 2.7672 5.2828 5.3498 7.869 8.0248 0.66188 0.64567 1.0051 0.64567 1.667 0 2.5862-2.6749 5.3073-5.2576 7.869-8.0248 0.80896-0.8117 1.2625-0.70101 1.9856 0.092239 1.0909 1.1991 2.243 2.3982 3.4442 3.4128 0.74768 0.73791 0.57608 1.1069-0.06129 1.7525-2.6965 2.5827-5.3441 5.2576-8.0406 7.9325-0.66188 0.64567-0.72316 1.0146-0.02451 1.6603z', 'M 26.354091,4.1273218 11.905265,18.588593 5.6453529,12.328679 1.0033099,16.970721 11.905265,27.872678 30.996134,8.7693646 Z'
constructor: (@container, sliders, paused = true) ->
@marquees = $class 'marquee'
# Only do these if on actual page
if sliders
@anchorWrapper = $id 'anchors'
@anchors = $class 'anchor'
@screen = $id 'gallery-screen'
@replyButton = $id 'replying-to'
@anchorsTooltip = $id 'tooltip'
@canvas = $id 'old-visualizer'
@ctx = @canvas.getContext '2d'
@form = $id 'comment-form'
do @resizeCanvas
do sliders.verticalSlider.keyboard.disable
do sliders.verticalSlider.mousewheel.disable
setTimeout ->
sliders.verticalSlider.slideTo 1
return
, 4000
anime(
targets: '.old-letter'
duration: 2000,
delay: anime.stagger 200
easing: 'easeOutBounce'
translateY: window.innerHeight / 2
)
anime(
targets: '.old-letter img'
direction: 'alternate'
duration: 300
easing: 'linear'
loop: true
rotateZ: 2
)
@player = new Music @fft
do @getStatus
do @getComments
self = @
do (self) ->
window.addEventListener 'resize', ->
do self.resizeCanvas
# Make anchors got to slides
for anchor, i in self.anchors
index = i
do (index) ->
anchor.addEventListener 'click', ->
sliders.horizontalSlider.slideTo index
# TODO: Improve this
anchor.addEventListener 'mouseenter', ->
self.anchorsTooltip.innerHTML = self.sections[index]
self.anchorsTooltip.style.opacity = 1
if anchor.classList.contains 'anchor_small'
rect = do @getClientRects
if index > Math.floor self.anchors.length / 2
self.anchorsTooltip.style.right = "#{window.innerWidth - rect[0].x}px"
self.anchorsTooltip.style.left = "initial"
else
self.anchorsTooltip.style.left = "#{rect[0].x + rect[0].width}px"
self.anchorsTooltip.style.right = "initial"
else
if index > Math.floor self.anchors.length / 2
self.anchorsTooltip.style.left = "65vw"
else
self.anchorsTooltip.style.left = "20vw"
anchor.addEventListener 'mouseleave', ->
self.anchorsTooltip.style.opacity = 0
# Change anchor styles according to the active slide
sliders.verticalSlider.on 'slideChangeTransitionStart', ->
if @activeIndex is 1
self.anchorWrapper.classList.remove 'anchors_hidden'
sliders.horizontalSlider.on 'slideChangeTransitionStart', ->
for anchor in self.anchors
unless @activeIndex is 3
anchor.classList.add 'anchor_small'
self.anchorsTooltip.classList.add 'anchors__tooltip_small'
else
self.anchorWrapper.classList.remove 'anchors_stored'
anchor.classList.remove 'anchor_small'
self.anchorsTooltip.classList.remove 'anchors__tooltip_small'
self.anchorWrapper.addEventListener 'mouseenter', ->
unless sliders.horizontalSlider.activeIndex is 3
@classList.remove 'anchors_stored'
self.anchorWrapper.addEventListener 'mouseleave', ->
unless sliders.horizontalSlider.activeIndex is 3
@classList.add 'anchors_stored'
# Change about page
aboutLess = $id 'about-less'
aboutMore = $id 'about-more'
aboutLess.addEventListener 'click', ->
self.changePage 'old-about', -1
aboutMore.addEventListener 'click', ->
self.changePage 'old-about', 1
# Listen for music changes
self.player.player.addEventListener 'play', ->
do self.startPlaying
self.player.player.addEventListener 'pause', ->
do self.pausePlaying
# Change music page
songsLess = $id 'songs-less'
songsMore = $id 'songs-more'
songsLess.addEventListener 'click', ->
self.changePage 'old-songs', -1
songsMore.addEventListener 'click', ->
self.changePage 'old-songs', 1
# Rotate board perspective
board = $id 'board'
$id('mousearea').addEventListener 'mousemove', (e) ->
windowWidth = window.innerWidth
windowHeight = window.innerHeight
board.style.transform = "rotateX(#{-(e.pageY - window.innerHeight/2)/50}deg) rotateY(#{(e.pageX - window.innerWidth/2)/50}deg)"
# Associate gallery links
galleryLinks = $class 'old-board__layer'
for link in galleryLinks
link.addEventListener 'click', ->
sliders.horizontalSlider.allowSlidePrev = false
sliders.horizontalSlider.allowSlideNext = false
do self.clearScreen
cat = @dataset.cat
list = $id "gallery-#{cat}"
list.classList.add 'old-gallery__list_active'
self.screen.classList.add 'old-gallery__screen_active'
for frame in list.getElementsByClassName 'old-gallery__frame'
if cat is 'video'
img = $create 'video'
img.src = "https://aya.volk.pt/video/#{frame.dataset.src}"
else
img = new Image()
img.src = "/public/images/galleries/thumbnails/#{frame.dataset.src.replace /\.\w+$/, '.jpg'}"
img.className = 'old-gallery__thumb'
frame.appendChild img
frame.addEventListener 'click', ->
do self.clearScreen
if cat is 'video'
img = $create 'video'
img.src = "https://aya.volk.pt/video/#{@dataset.src}"
img.autoplay = true
img.controls = true
else
img = new Image()
img.src = "/public/images/galleries/#{@dataset.src}"
img.className = 'old-gallery__image'
self.screen.appendChild img
$id('gallery-back').addEventListener 'click', ->
self.screen.classList.remove 'old-gallery__screen_active'
$query('.old-gallery__list_active').classList.remove 'old-gallery__list_active'
sliders.horizontalSlider.allowSlidePrev = true
sliders.horizontalSlider.allowSlideNext = true
videoLayer = $query '.old-board__layer[data-cat=video]'
videoLayerVideo = videoLayer.querySelector('video')
videoLayer.addEventListener 'mouseenter', ->
do videoLayerVideo.play
videoLayer.addEventListener 'mouseleave', ->
do videoLayerVideo.pause
$id('comment-text').addEventListener 'keyup', ->
button = $query '.old-form__icon path'
if @value.length
button.classList.add 'old-form__path_ok'
anime(
targets: t: 0
t: 1
duration: 300
update: (anim) =>
button.setAttribute "d", interpolatorX anim.progress / 100
)
else
button.classList.remove 'old-form__path_ok'
anime(
targets: t: 0
t: 1
duration: 300
update: (anim) =>
button.setAttribute "d", interpolatorX 1 - anim.progress / 100
)
$id('submit').addEventListener 'click', ->
do self.postComment
self.form.addEventListener 'submit', (e) ->
do e.preventDefault
do self.postComment
do @createBars
@animateMarquees paused
resizeCanvas: =>
@canvas.width = window.innerWidth
@canvas.height =window.innerHeight
animateMarquees: (paused) =>
# unless @paused
for marquee in @marquees
marquee.style.animationPlayState = if @paused then 'paused' else 'running'
if paused is true
@paused = true
requestAnimationFrame @animateMarquees
return
clearScreen: =>
if @screen.children.length > 1
do @screen.lastElementChild.remove
startPlaying: =>
do @pausePlaying
@playing = $query('.play-button_playing').parentElement.parentElement
button = $query '.play-button_playing path'
button.classList.add 'morphed'
anime(
targets: t: 0
t: 1
duration: 300
update: (anim) =>
button.setAttribute "d", interpolator anim.progress / 100
)
@interpolator
pausePlaying: =>
if @playing
@playing.style.transform = 'initial'
@playing = undefined
button = $query '.morphed'
if button
button.classList.remove 'morphed'
anime(
targets: t: 0
t: 1
duration: 300
update: (anim) =>
button.setAttribute "d", interpolator 1 - anim.progress / 100
)
createBars: =>
# Semi blue
@ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'
# Clear canvas
@ctx.clearRect 0, 0, @canvas.width, @canvas.height
# Analyze audio
if @player and @player.audio isnt undefined
@averageFrequency = analyzeAudio @player, @fft
@frequencyArray = @player.dataArray
if @playing
@playing.style.transform = "scale(#{1 + @averageFrequency / 512})"
for bar, i in @frequencyArray
b = bar * 2
w = @canvas.width / 16
@ctx.fillRect w * i, @canvas.height - b, w, b
requestAnimationFrame @createBars
return
changePage: (className, dir) =>
pages = Array.from $class "#{className}__page"
i = pages.findIndex (p) => p.classList.contains "#{className}__page_active"
cur = pages[i]
next = pages[i + dir]
cur.classList.remove "#{className}__page_active"
next.classList.add "#{className}__page_active"
prev = $query ".#{className}__link_dir_left"
more = $query ".#{className}__link_dir_right"
if i + dir is 0
prev.classList.add "#{className}__link_hidden"
else
prev.classList.remove "#{className}__link_hidden"
if i + dir is pages.length - 1
more.classList.add "#{className}__link_hidden"
else
more.classList.remove "#{className}__link_hidden"
getStatus: =>
ajax 'GET', 'https://aya.volk.pt/status/status.json', null, (data) =>
status = $id 'status'
posts = JSON.parse data
for post in posts
div = $create 'div'
div.className = 'old-status'
div.innerHTML = "<div class='old-status__date'>#{@timeToDate(post.date)}</div><div class='old-status__text'>#{post.text}</div><div class='old-status__byebye'>See you next time!</div>"
status.appendChild div
getComments: =>
ajax 'GET', 'https://aya.volk.pt/comments', null, (data) =>
comments = $id 'comments'
posts = JSON.parse data
for post in posts
@createPost post
createPost: (data) =>
comments = $id 'comments'
thread = $create 'div'
thread.className = 'old-comments__thread'
thread.id = "thread-#{data.id}"
div = $create 'div'
div.className = 'old-comment'
div.innerHTML = "#{data.text}<div class='old-comment__name'>#{data.name || 'Anonymous'}</div><div class='old-comment__date'>#{@timeToDate(data.time)}</div><div class='old-comment__reply'>Reply</div><div class='old-comment__id'>##{data.id}</div>"
thread.appendChild div
if data.reply is null
comments.prepend thread
else
$id("thread-#{data.reply}").appendChild thread
thread.querySelector('.old-comment__reply').addEventListener 'click', =>
@replyButton.innerHTML = "Replying to ##{data.id}"
@replyButton.dataset.id = data.id
@replyButton.classList.add 'old-form__reply_active'
postComment: =>
post =
name: $id('comment-name').value
text: $id('comment-text').value
reply: $id('replying-to').dataset.id or null
last = 0
for id in $class 'old-comment__id'
num = parseInt id.textContent.substring 1
if num > last
last = num
ajax 'POST', @form.action, JSON.stringify(post), (data) =>
@createPost
id: last + 1
name: post.name
text: post.text
reply: post.reply
time: do new Date().getTime
, (error) ->
alert error.response
timeToDate: (t) =>
date = new Date t
"#{do date.getDate}/#{do date.getMonth + 1}/#{do date.getFullYear - 2000}"
export default Old