add clue animation

This commit is contained in:
Felix Niklas 2015-06-09 16:17:56 +02:00
parent d92b6e292d
commit 7679024a5d
4 changed files with 144 additions and 73 deletions

View file

@ -943,7 +943,7 @@ App.Config.set( 'layout_ref/highlight', highlightRef, 'Routes' )
class cluesRef extends App.ControllerContent class cluesRef extends App.ControllerContent
clues: [ clues: [
{ {
container: '.search-holder' container: '.search-holder'
@ -986,7 +986,12 @@ class cluesRef extends App.ControllerContent
} }
] ]
elements:
'.js-positionOrigin': 'modalWindow'
'.js-backdrop': 'backdrop'
events: events:
'click': 'stopPropagation'
'click .js-next': 'next' 'click .js-next': 'next'
'click .js-previous': 'previous' 'click .js-previous': 'previous'
'click .js-close': 'close' 'click .js-close': 'close'
@ -1006,6 +1011,9 @@ class cluesRef extends App.ControllerContent
@position = 0 @position = 0
@render() @render()
stopPropagation: (event) ->
event.stopPropagation()
next: (event) => next: (event) =>
event.stopPropagation() event.stopPropagation()
@navigate 1 @navigate 1
@ -1017,28 +1025,43 @@ class cluesRef extends App.ControllerContent
close: => close: =>
@cleanUp() @cleanUp()
@options.onComplete() @options.onComplete()
@remove()
navigate: (direction) -> remove: ->
@cleanUp()
@position += direction
if @position < @clues.length
@render()
else
@options.onComplete()
cleanUp: ->
clue = @clues[@position]
container = $(clue.container)
container.removeClass('selected-clue')
# undo click perform by doing it again
if clue.actions
@perform clue.actions, container
@$('.modal').remove() @$('.modal').remove()
navigate: (direction) ->
@cleanUp =>
@position += direction
if @position < @clues.length
@showClue()
else
@options.onComplete()
@remove()
cleanUp: (callback) ->
@hideWindow =>
clue = @clues[@position]
container = $(clue.container)
container.removeClass('selected-clue')
# undo click perform by doing it again
if clue.actions
@perform clue.actions, container
callback()
render: -> render: ->
@html App.view('layout_ref/clues')
@backdrop.velocity
properties:
opacity: [1, 0]
options:
duration: 300
complete: @showClue
showClue: =>
clue = @clues[@position] clue = @clues[@position]
container = $(clue.container) container = $(clue.container)
container.addClass('selected-clue') container.addClass('selected-clue')
@ -1054,20 +1077,47 @@ class cluesRef extends App.ControllerContent
x: boundingBox.left + boundingBox.width/2 x: boundingBox.left + boundingBox.width/2
y: boundingBox.top + boundingBox.height/2 y: boundingBox.top + boundingBox.height/2
@html App.view('layout_ref/clues') @modalWindow.html App.view('layout_ref/clue_content')
headline: clue.headline headline: clue.headline
text: clue.text text: clue.text
width: boundingBox.width
height: boundingBox.height
center: center
position: @position position: @position
max: @clues.length max: @clues.length
@placeWindow(boundingBox) @placeWindow(boundingBox)
@backdrop.velocity
properties:
translateX: center.x
translateY: center.y
translateZ: 0
options:
duration: 300
complete: @showWindow
showWindow: =>
@modalWindow.velocity
properties:
scale: [1, 0.2]
opacity: [1, 0]
options:
duration: 300
easing: [0.34,1.61,0.7,1]
hideWindow: (callback) =>
@modalWindow.velocity
properties:
scale: [0.2, 1]
opacity: 0
options:
duration: 200
complete: callback
placeWindow: (target) -> placeWindow: (target) ->
modalElement = @$('.js-positionOrigin') # reset scale in order to get correct measurements
modal = modalElement.get(0).getBoundingClientRect() $.Velocity.hook(@modalWindow, 'scale', 1)
modal = @modalWindow.get(0).getBoundingClientRect()
position = '' position = ''
left = 0 left = 0
top = 0 top = 0
@ -1117,16 +1167,43 @@ class cluesRef extends App.ControllerContent
moveArrow = modal.height/2 + maxHeight - (top + modal.height) moveArrow = modal.height/2 + maxHeight - (top + modal.height)
top = maxHeight - modal.height top = maxHeight - modal.height
# show window transformOrigin = @getTransformOrigin(modal, position)
modalElement
.addClass "is-visible is-#{ position }"
.css
'left': left
'top': top
if moveArrow if moveArrow
parameter = if position is 'above' or position is 'below' then 'left' else 'top' parameter = if position is 'above' or position is 'below' then 'left' else 'top'
modalElement.find('.js-arrow').css(parameter, moveArrow) # move arrow
@modalWindow.find('.js-arrow').css(parameter, moveArrow)
# adjust transform origin
if position is 'above' or position is 'below'
transformOrigin.x = moveArrow
else
transformOrigin.y = moveArrow
# place window
@modalWindow
.attr 'data-position', position
.css
left: left
top: top
transformOrigin: "#{transformOrigin.x}px #{transformOrigin.y}px"
getTransformOrigin: (modal, position) ->
positionDictionary =
above:
x: modal.width/2
y: modal.height + @transformOriginPadding
below:
x: modal.width/2
y: -@transformOriginPadding
left:
x: modal.width + @transformOriginPadding
y: modal.height/2
right:
x: -@transformOriginPadding
y: modal.height/2
return positionDictionary[position]
getVisibleBoundingBox: (el) -> getVisibleBoundingBox: (el) ->
### ###

View file

@ -0,0 +1,21 @@
<div class="modal-content">
<div class="modal-arrow js-arrow"></div>
<div class="modal-close js-close">
<svg class="icon-diagonal-cross"><use xlink:href="#icon-diagonal-cross" /></svg>
</div>
<div class="modal-header"><%= @headline %></div>
<div class="modal-body"><%- @text %></div>
<div class="modal-controls">
<div class="modal-control">
<div class="<% if @position is 0: %>is-disabled <% end %>btn btn--text js-previous"><%- @T( 'Previous' ) %></div>
</div>
<div class="modal-control clue-count"><%= @position+1 %>/<%= @max %></div>
<div class="modal-control">
<% if @position+1 is @max: %>
<div class="btn btn--text js-next"><%- @T( 'Finish' ) %></div>
<% else: %>
<div class="btn btn--text js-next"><%- @T( 'Next' ) %></div>
<% end %>
</div>
</div>
</div>

View file

@ -1,33 +1,4 @@
<div class="modal modal--clue"> <div class="modal modal--clue">
<div class="modal-backdrop" style="background: <div class="modal-backdrop js-backdrop"></div>
radial-gradient( <div class="modal-spacer js-positionOrigin"></div>
ellipse <%= @width + 400 %>px <%= @height + 400 %>px
at <%= @center.x %>px <%= @center.y %>px,
hsla(202,68%,54%,.4),
hsla(202,68%,54%,.9)
)
"></div>
<div class="modal-spacer js-positionOrigin">
<div class="modal-content">
<div class="modal-arrow js-arrow"></div>
<div class="modal-close js-close">
<svg class="icon-diagonal-cross"><use xlink:href="#icon-diagonal-cross" /></svg>
</div>
<div class="modal-header"><%= @headline %></div>
<div class="modal-body"><%- @text %></div>
<div class="modal-controls">
<div class="modal-control">
<div class="<% if @position is 0: %>is-disabled <% end %>btn btn--text js-previous"><%- @T( 'Previous' ) %></div>
</div>
<div class="modal-control clue-count"><%= @position+1 %>/<%= @max %></div>
<div class="modal-control">
<% if @position+1 is @max: %>
<div class="btn btn--text js-next"><%- @T( 'Finish' ) %></div>
<% else: %>
<div class="btn btn--text js-next"><%- @T( 'Next' ) %></div>
<% end %>
</div>
</div>
</div>
</div>
</div> </div>

View file

@ -930,16 +930,17 @@ textarea,
.modal-backdrop { .modal-backdrop {
bottom: 0; bottom: 0;
width: 200%;
height: 200%;
left: -100%;
top: -100%;
background: radial-gradient(hsla(202,68%,54%,0.1), hsla(202,68%,54%,.9));
} }
.modal-spacer { .modal-spacer {
position: absolute; position: absolute;
opacity: 0; opacity: 0;
padding: 18px; padding: 18px;
&.is-visible {
opacity: 1;
}
} }
.modal-arrow { .modal-arrow {
@ -953,18 +954,18 @@ textarea,
transform: rotate(45deg); transform: rotate(45deg);
} }
.modal-spacer.is-above .modal-arrow { .modal-spacer[data-position="above"] .modal-arrow {
left: 50%; left: 50%;
top: 100%; top: 100%;
background: hsl(210,5%,97%); background: hsl(210,5%,97%);
} }
.modal-spacer.is-below .modal-arrow { .modal-spacer[data-position="below"] .modal-arrow {
left: 50%; left: 50%;
top: 0; top: 0;
} }
.modal-spacer.is-left .modal-arrow { .modal-spacer[data-position="left"] .modal-arrow {
left: 100%; left: 100%;
top: 50%; top: 50%;
} }
@ -1007,10 +1008,11 @@ textarea,
} }
kbd { kbd {
background: hsl(200,8%,21%); background: hsl(200,8%,90%);
border-radius: 3px; border-radius: 3px;
box-shadow: 0 1px 1px black; border: 1px solid hsl(240,7%,77%);
color: white; box-shadow: 0 1px rgba(0,0,0,.08);
color: hsl(240,7%,37%);
display: inline-block; display: inline-block;
font-size: 12px; font-size: 12px;
margin: 0 1px; margin: 0 1px;