mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-24 08:08:15 -05:00
More blingstrositization for the HeroVictoryModal.
This commit is contained in:
parent
a71c591f54
commit
de7985fc2e
3 changed files with 88 additions and 37 deletions
|
@ -19,6 +19,10 @@
|
|||
#victory-header
|
||||
display: block
|
||||
margin: 15px auto 0
|
||||
@include transition(0.25s ease-in)
|
||||
|
||||
&.out
|
||||
margin-top: -100px
|
||||
|
||||
.modal-header
|
||||
height: 85px
|
||||
|
@ -78,6 +82,17 @@
|
|||
float: left
|
||||
margin: 0 1.8px
|
||||
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
|
||||
top: 8px
|
||||
|
@ -116,7 +131,6 @@
|
|||
white-space: nowrap
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
|
||||
|
||||
//- Pulse effect
|
||||
|
||||
|
@ -125,15 +139,18 @@
|
|||
max-width: 56px
|
||||
max-height: 55px
|
||||
50%
|
||||
width: 72px
|
||||
max-width: 72px
|
||||
max-height: 72px
|
||||
width: 66px
|
||||
max-width: 66px
|
||||
max-height: 66px
|
||||
to
|
||||
max-width: 56px
|
||||
max-height: 55px
|
||||
|
||||
.pulse
|
||||
.xp .pulse
|
||||
@include animation(rewardPulse 0.15s infinite)
|
||||
|
||||
.gems .pulse
|
||||
@include animation(rewardPulse 0.25s infinite)
|
||||
|
||||
//- Footer
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
extends /templates/modal/modal_base
|
||||
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
|
||||
|
||||
|
@ -14,13 +14,13 @@ block modal-body-content
|
|||
div.achievement-rewards
|
||||
- var worth = achievement.get('worth', true);
|
||||
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')
|
||||
img(src="/images/pages/play/level/modal/reward_icon_xp.png")
|
||||
.reward-text= animate ? 'x0' : '+'+worth
|
||||
|
||||
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')
|
||||
img(src="/images/pages/play/level/modal/reward_icon_gems.png")
|
||||
.reward-text= animate ? 'x0' : '+'+rewards.gems
|
||||
|
@ -28,7 +28,7 @@ block modal-body-content
|
|||
if rewards.heroes
|
||||
for hero in rewards.heroes
|
||||
- var hero = thangTypes[hero];
|
||||
.reward-panel
|
||||
.reward-panel.hero
|
||||
.reward-image-container(class=animate?'':'show')
|
||||
img(src=hero.getPortraitURL())
|
||||
.reward-text= hero.get('name')
|
||||
|
@ -36,7 +36,7 @@ block modal-body-content
|
|||
if rewards.items
|
||||
for item in rewards.items
|
||||
- var item = thangTypes[item];
|
||||
.reward-panel
|
||||
.reward-panel.item
|
||||
.reward-image-container(class=animate?'':'show')
|
||||
img(src=item.getPortraitURL())
|
||||
.reward-text= item.get('name')
|
||||
|
|
|
@ -25,6 +25,7 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
@achievements = @supermodel.loadCollection(achievements, 'achievements').model
|
||||
@listenToOnce @achievements, 'sync', @onAchievementsLoaded
|
||||
@readyToContinue = false
|
||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'victory'
|
||||
|
||||
onAchievementsLoaded: ->
|
||||
thangTypeOriginals = []
|
||||
|
@ -73,12 +74,17 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
achievement.completedAWhileAgo = new Date() - Date.parse(earnedAchievement.get('created')) > 30 * 1000
|
||||
c.achievements = @achievements.models
|
||||
|
||||
## for testing the three states
|
||||
# for testing the three states
|
||||
#if c.achievements.length
|
||||
# c.achievements = [c.achievements[0].clone(), c.achievements[0].clone(), c.achievements[0].clone()]
|
||||
#for achievement, index in c.achievements
|
||||
# achievement.completed = index > 0
|
||||
# achievement.completedAWhileAgo = index > 1
|
||||
## achievement.completed = index > 0
|
||||
## 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
|
||||
return c
|
||||
|
@ -87,6 +93,7 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
super()
|
||||
return unless @supermodel.finished()
|
||||
@updateSavingProgressStatus()
|
||||
@$el.find('#victory-header').delay(250).queue(-> $(@).removeClass('out').dequeue())
|
||||
complete = _.once(_.bind(@beginAnimateNumbers, @))
|
||||
@animatedPanels = $()
|
||||
panels = @$el.find('.achievement-panel')
|
||||
|
@ -94,15 +101,15 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
panel = $(panel)
|
||||
continue unless panel.data('animate')
|
||||
@animatedPanels = @animatedPanels.add(panel)
|
||||
panel.delay(500)
|
||||
panel.delay(500) # Waiting for victory header to show up and fall
|
||||
panel.queue(->
|
||||
$(this).addClass('earned') # animate out the grayscale
|
||||
$(this).dequeue()
|
||||
$(@).addClass('earned') # animate out the grayscale
|
||||
$(@).dequeue()
|
||||
)
|
||||
panel.delay(500)
|
||||
panel.queue(->
|
||||
$(this).find('.reward-image-container').addClass('show')
|
||||
$(this).dequeue()
|
||||
$(@).find('.reward-image-container').addClass('show')
|
||||
$(@).dequeue()
|
||||
)
|
||||
panel.delay(500)
|
||||
panel.queue(-> complete())
|
||||
|
@ -116,36 +123,59 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
unit: $(panel).data('number-unit')
|
||||
})
|
||||
|
||||
itemPanel.rootEl.find('.reward-image-container img').addClass('pulse') for itemPanel in @numericalItemPanels
|
||||
@numberAnimationStart = new Date()
|
||||
@totalXP = 0
|
||||
@totalXP += panel.number for panel in @numericalItemPanels when panel.unit is 'xp'
|
||||
@totalGems = 0
|
||||
@totalGems += panel.number for panel in @numericalItemPanels when panel.unit is 'gem'
|
||||
@gemEl = $('#gem-total')
|
||||
@XPEl = $('#xp-total')
|
||||
@numberAnimationInterval = setInterval(@tickNumberAnimation, 15 / 1000)
|
||||
@totalXPAnimated = @totalGemsAnimated = @lastTotalXP = @lastTotalGems = 0
|
||||
@numberAnimationStart = new Date()
|
||||
@numberAnimationInterval = setInterval(@tickNumberAnimation, 1000 / 60)
|
||||
|
||||
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: add easing so that the counts start slow and speed up, then end slow (easeInOut)
|
||||
# TODO: make each animation slightly longer if it has lots of stuff to animate, faster if not much to animate
|
||||
ratio = Math.min(1, (new Date() - @numberAnimationStart) / 1500)
|
||||
panel.textEl.text('+'+parseInt(panel.number * ratio)) for panel in @numericalItemPanels
|
||||
@XPEl.text('+'+parseInt(@totalXP * ratio))
|
||||
@gemEl.text('+'+parseInt(@totalGems * ratio))
|
||||
@endAnimateNumbers() if ratio is 1
|
||||
xpTrigger = 'xp-' + (parseInt(panel.number * ratio) % 6) # 6 xp sounds
|
||||
gemTrigger = 'gem-' + (parseInt(panel.number * ratio) % 4) # 4 gem sounds
|
||||
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
|
||||
return @endAnimateNumbers() unless panel = @numericalItemPanels[0]
|
||||
duration = Math.log10(panel.number + 1) * 1000
|
||||
ratio = @getEaseRatio (new Date() - @numberAnimationStart), duration
|
||||
if panel.unit is 'xp'
|
||||
totalXP = @totalXPAnimated + Math.floor(ratio * panel.number)
|
||||
if totalXP isnt @lastTotalXP
|
||||
panel.textEl.text('+' + totalXP)
|
||||
@XPEl.text('+' + totalXP)
|
||||
xpTrigger = 'xp-' + (totalXP % 6) # 6 xp sounds
|
||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: xpTrigger, 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: ->
|
||||
@$el.find('.pulse').removeClass('pulse')
|
||||
clearInterval(@numberAnimationInterval)
|
||||
clearInterval @numberAnimationInterval
|
||||
@animationComplete = true
|
||||
@updateSavingProgressStatus()
|
||||
|
||||
|
@ -155,3 +185,7 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
@$el.find('#continue-button').toggleClass('hide', not @readyToContinue)
|
||||
|
||||
# TODO: award heroes/items and play an awesome sound when you get one
|
||||
|
||||
destroy: ->
|
||||
clearInterval @numberAnimationInterval
|
||||
super()
|
||||
|
|
Loading…
Reference in a new issue