More blingstrositization for the HeroVictoryModal.

This commit is contained in:
Nick Winter 2014-10-17 20:15:41 -07:00
parent a71c591f54
commit de7985fc2e
3 changed files with 88 additions and 37 deletions

View file

@ -19,6 +19,10 @@
#victory-header #victory-header
display: block display: block
margin: 15px auto 0 margin: 15px auto 0
@include transition(0.25s ease-in)
&.out
margin-top: -100px
.modal-header .modal-header
height: 85px height: 85px
@ -78,6 +82,17 @@
float: left float: left
margin: 0 1.8px margin: 0 1.8px
position: relative position: relative
z-index: 1
@include transition(0.25s ease)
&.animating
@include scale(1.5)
z-index: 2
.reward-text
font-size: 18px
overflow: visible
bottom: 9px
.reward-image-container .reward-image-container
top: 8px top: 8px
@ -116,7 +131,6 @@
white-space: nowrap white-space: nowrap
overflow: hidden overflow: hidden
text-overflow: ellipsis text-overflow: ellipsis
//- Pulse effect //- Pulse effect
@ -125,15 +139,18 @@
max-width: 56px max-width: 56px
max-height: 55px max-height: 55px
50% 50%
width: 72px width: 66px
max-width: 72px max-width: 66px
max-height: 72px max-height: 66px
to to
max-width: 56px max-width: 56px
max-height: 55px max-height: 55px
.pulse .xp .pulse
@include animation(rewardPulse 0.15s infinite) @include animation(rewardPulse 0.15s infinite)
.gems .pulse
@include animation(rewardPulse 0.25s infinite)
//- Footer //- Footer

View file

@ -1,6 +1,6 @@
extends /templates/modal/modal_base extends /templates/modal/modal_base
block modal-header-content block modal-header-content
img(src="/images/pages/play/level/modal/victory_word.png")#victory-header img(src="/images/pages/play/level/modal/victory_word.png")#victory-header.out
block modal-body-content block modal-body-content
@ -14,13 +14,13 @@ block modal-body-content
div.achievement-rewards div.achievement-rewards
- var worth = achievement.get('worth', true); - var worth = achievement.get('worth', true);
if worth if worth
.reward-panel.numerical(data-number=worth, data-number-unit='xp') .reward-panel.numerical.xp(data-number=worth, data-number-unit='xp')
.reward-image-container(class=animate?'':'show') .reward-image-container(class=animate?'':'show')
img(src="/images/pages/play/level/modal/reward_icon_xp.png") img(src="/images/pages/play/level/modal/reward_icon_xp.png")
.reward-text= animate ? 'x0' : '+'+worth .reward-text= animate ? 'x0' : '+'+worth
if rewards.gems if rewards.gems
.reward-panel.numerical(data-number=rewards.gems, data-number-unit='gem') .reward-panel.numerical.gems(data-number=rewards.gems, data-number-unit='gem')
.reward-image-container(class=animate?'':'show') .reward-image-container(class=animate?'':'show')
img(src="/images/pages/play/level/modal/reward_icon_gems.png") img(src="/images/pages/play/level/modal/reward_icon_gems.png")
.reward-text= animate ? 'x0' : '+'+rewards.gems .reward-text= animate ? 'x0' : '+'+rewards.gems
@ -28,7 +28,7 @@ block modal-body-content
if rewards.heroes if rewards.heroes
for hero in rewards.heroes for hero in rewards.heroes
- var hero = thangTypes[hero]; - var hero = thangTypes[hero];
.reward-panel .reward-panel.hero
.reward-image-container(class=animate?'':'show') .reward-image-container(class=animate?'':'show')
img(src=hero.getPortraitURL()) img(src=hero.getPortraitURL())
.reward-text= hero.get('name') .reward-text= hero.get('name')
@ -36,7 +36,7 @@ block modal-body-content
if rewards.items if rewards.items
for item in rewards.items for item in rewards.items
- var item = thangTypes[item]; - var item = thangTypes[item];
.reward-panel .reward-panel.item
.reward-image-container(class=animate?'':'show') .reward-image-container(class=animate?'':'show')
img(src=item.getPortraitURL()) img(src=item.getPortraitURL())
.reward-text= item.get('name') .reward-text= item.get('name')

View file

@ -25,6 +25,7 @@ module.exports = class HeroVictoryModal extends ModalView
@achievements = @supermodel.loadCollection(achievements, 'achievements').model @achievements = @supermodel.loadCollection(achievements, 'achievements').model
@listenToOnce @achievements, 'sync', @onAchievementsLoaded @listenToOnce @achievements, 'sync', @onAchievementsLoaded
@readyToContinue = false @readyToContinue = false
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'victory'
onAchievementsLoaded: -> onAchievementsLoaded: ->
thangTypeOriginals = [] thangTypeOriginals = []
@ -73,12 +74,17 @@ module.exports = class HeroVictoryModal extends ModalView
achievement.completedAWhileAgo = new Date() - Date.parse(earnedAchievement.get('created')) > 30 * 1000 achievement.completedAWhileAgo = new Date() - Date.parse(earnedAchievement.get('created')) > 30 * 1000
c.achievements = @achievements.models c.achievements = @achievements.models
## for testing the three states # for testing the three states
#if c.achievements.length #if c.achievements.length
# c.achievements = [c.achievements[0].clone(), c.achievements[0].clone(), c.achievements[0].clone()] # c.achievements = [c.achievements[0].clone(), c.achievements[0].clone(), c.achievements[0].clone()]
#for achievement, index in c.achievements #for achievement, index in c.achievements
# achievement.completed = index > 0 ## achievement.completed = index > 0
# achievement.completedAWhileAgo = index > 1 ## achievement.completedAWhileAgo = index > 1
# achievement.completed = true
# achievement.completedAWhileAgo = false
# achievement.attributes.worth = (index + 1) * achievement.get('worth')
# rewards = achievement.get('rewards')
# rewards.gems *= (index + 1)
c.thangTypes = @thangTypes c.thangTypes = @thangTypes
return c return c
@ -87,6 +93,7 @@ module.exports = class HeroVictoryModal extends ModalView
super() super()
return unless @supermodel.finished() return unless @supermodel.finished()
@updateSavingProgressStatus() @updateSavingProgressStatus()
@$el.find('#victory-header').delay(250).queue(-> $(@).removeClass('out').dequeue())
complete = _.once(_.bind(@beginAnimateNumbers, @)) complete = _.once(_.bind(@beginAnimateNumbers, @))
@animatedPanels = $() @animatedPanels = $()
panels = @$el.find('.achievement-panel') panels = @$el.find('.achievement-panel')
@ -94,15 +101,15 @@ module.exports = class HeroVictoryModal extends ModalView
panel = $(panel) panel = $(panel)
continue unless panel.data('animate') continue unless panel.data('animate')
@animatedPanels = @animatedPanels.add(panel) @animatedPanels = @animatedPanels.add(panel)
panel.delay(500) panel.delay(500) # Waiting for victory header to show up and fall
panel.queue(-> panel.queue(->
$(this).addClass('earned') # animate out the grayscale $(@).addClass('earned') # animate out the grayscale
$(this).dequeue() $(@).dequeue()
) )
panel.delay(500) panel.delay(500)
panel.queue(-> panel.queue(->
$(this).find('.reward-image-container').addClass('show') $(@).find('.reward-image-container').addClass('show')
$(this).dequeue() $(@).dequeue()
) )
panel.delay(500) panel.delay(500)
panel.queue(-> complete()) panel.queue(-> complete())
@ -116,36 +123,59 @@ module.exports = class HeroVictoryModal extends ModalView
unit: $(panel).data('number-unit') unit: $(panel).data('number-unit')
}) })
itemPanel.rootEl.find('.reward-image-container img').addClass('pulse') for itemPanel in @numericalItemPanels
@numberAnimationStart = new Date()
@totalXP = 0 @totalXP = 0
@totalXP += panel.number for panel in @numericalItemPanels when panel.unit is 'xp' @totalXP += panel.number for panel in @numericalItemPanels when panel.unit is 'xp'
@totalGems = 0 @totalGems = 0
@totalGems += panel.number for panel in @numericalItemPanels when panel.unit is 'gem' @totalGems += panel.number for panel in @numericalItemPanels when panel.unit is 'gem'
@gemEl = $('#gem-total') @gemEl = $('#gem-total')
@XPEl = $('#xp-total') @XPEl = $('#xp-total')
@numberAnimationInterval = setInterval(@tickNumberAnimation, 15 / 1000) @totalXPAnimated = @totalGemsAnimated = @lastTotalXP = @lastTotalGems = 0
@numberAnimationStart = new Date()
@numberAnimationInterval = setInterval(@tickNumberAnimation, 1000 / 60)
tickNumberAnimation: => tickNumberAnimation: =>
# TODO: make these tick serially
# TODO: make each panel huge while it's ticking
# TODO: only play a sound when an integer tick up happens
# TODO: make sure the animation pulses happen when the numbers go up and sounds play (up to a max speed) # TODO: make sure the animation pulses happen when the numbers go up and sounds play (up to a max speed)
# TODO: add easing so that the counts start slow and speed up, then end slow (easeInOut) return @endAnimateNumbers() unless panel = @numericalItemPanels[0]
# TODO: make each animation slightly longer if it has lots of stuff to animate, faster if not much to animate duration = Math.log10(panel.number + 1) * 1000
ratio = Math.min(1, (new Date() - @numberAnimationStart) / 1500) ratio = @getEaseRatio (new Date() - @numberAnimationStart), duration
panel.textEl.text('+'+parseInt(panel.number * ratio)) for panel in @numericalItemPanels if panel.unit is 'xp'
@XPEl.text('+'+parseInt(@totalXP * ratio)) totalXP = @totalXPAnimated + Math.floor(ratio * panel.number)
@gemEl.text('+'+parseInt(@totalGems * ratio)) if totalXP isnt @lastTotalXP
@endAnimateNumbers() if ratio is 1 panel.textEl.text('+' + totalXP)
xpTrigger = 'xp-' + (parseInt(panel.number * ratio) % 6) # 6 xp sounds @XPEl.text('+' + totalXP)
gemTrigger = 'gem-' + (parseInt(panel.number * ratio) % 4) # 4 gem sounds xpTrigger = 'xp-' + (totalXP % 6) # 6 xp sounds
Backbone.Mediator.publish 'audio-player:play-sound', trigger: xpTrigger, volume: 0.5 + ratio / 2 Backbone.Mediator.publish 'audio-player:play-sound', trigger: xpTrigger, volume: 0.5 + ratio / 2
Backbone.Mediator.publish 'audio-player:play-sound', trigger: gemTrigger, volume: 0.5 + ratio / 2 @lastTotalXP = totalXP
else
totalGems = @totalGemsAnimated + Math.floor(ratio * panel.number)
if totalGems isnt @lastTotalGems
panel.textEl.text('+' + totalGems)
@gemEl.text('+' + totalGems)
gemTrigger = 'gem-' + (parseInt(panel.number * ratio) % 4) # 4 gem sounds
Backbone.Mediator.publish 'audio-player:play-sound', trigger: gemTrigger, volume: 0.5 + ratio / 2
@lastTotalGems = totalGems
if ratio is 1
panel.rootEl.removeClass('animating').find('.reward-image-container img').removeClass('pulse')
@numberAnimationStart = new Date()
if panel.unit is 'xp'
@totalXPAnimated += panel.number
else
@totalGemsAnimated += panel.number
@numericalItemPanels.shift()
return
panel.rootEl.addClass('animating').find('.reward-image-container img').addClass('pulse')
getEaseRatio: (timeSinceStart, duration) ->
# Ease in/out quadratic - http://gizma.com/easing/
timeSinceStart = Math.min timeSinceStart, duration
t = 2 * timeSinceStart / duration
if t < 1
return 0.5 * t * t
--t
-0.5 * (t * (t - 2) - 1)
endAnimateNumbers: -> endAnimateNumbers: ->
@$el.find('.pulse').removeClass('pulse') clearInterval @numberAnimationInterval
clearInterval(@numberAnimationInterval)
@animationComplete = true @animationComplete = true
@updateSavingProgressStatus() @updateSavingProgressStatus()
@ -155,3 +185,7 @@ module.exports = class HeroVictoryModal extends ModalView
@$el.find('#continue-button').toggleClass('hide', not @readyToContinue) @$el.find('#continue-button').toggleClass('hide', not @readyToContinue)
# TODO: award heroes/items and play an awesome sound when you get one # TODO: award heroes/items and play an awesome sound when you get one
destroy: ->
clearInterval @numberAnimationInterval
super()