add clue animation
This commit is contained in:
parent
d92b6e292d
commit
7679024a5d
4 changed files with 144 additions and 73 deletions
|
@ -986,7 +986,12 @@ class cluesRef extends App.ControllerContent
|
|||
}
|
||||
]
|
||||
|
||||
elements:
|
||||
'.js-positionOrigin': 'modalWindow'
|
||||
'.js-backdrop': 'backdrop'
|
||||
|
||||
events:
|
||||
'click': 'stopPropagation'
|
||||
'click .js-next': 'next'
|
||||
'click .js-previous': 'previous'
|
||||
'click .js-close': 'close'
|
||||
|
@ -1006,6 +1011,9 @@ class cluesRef extends App.ControllerContent
|
|||
@position = 0
|
||||
@render()
|
||||
|
||||
stopPropagation: (event) ->
|
||||
event.stopPropagation()
|
||||
|
||||
next: (event) =>
|
||||
event.stopPropagation()
|
||||
@navigate 1
|
||||
|
@ -1017,28 +1025,43 @@ class cluesRef extends App.ControllerContent
|
|||
close: =>
|
||||
@cleanUp()
|
||||
@options.onComplete()
|
||||
@remove()
|
||||
|
||||
navigate: (direction) ->
|
||||
@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
|
||||
|
||||
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: ->
|
||||
@html App.view('layout_ref/clues')
|
||||
@backdrop.velocity
|
||||
properties:
|
||||
opacity: [1, 0]
|
||||
options:
|
||||
duration: 300
|
||||
complete: @showClue
|
||||
|
||||
showClue: =>
|
||||
clue = @clues[@position]
|
||||
container = $(clue.container)
|
||||
container.addClass('selected-clue')
|
||||
|
@ -1054,20 +1077,47 @@ class cluesRef extends App.ControllerContent
|
|||
x: boundingBox.left + boundingBox.width/2
|
||||
y: boundingBox.top + boundingBox.height/2
|
||||
|
||||
@html App.view('layout_ref/clues')
|
||||
@modalWindow.html App.view('layout_ref/clue_content')
|
||||
headline: clue.headline
|
||||
text: clue.text
|
||||
width: boundingBox.width
|
||||
height: boundingBox.height
|
||||
center: center
|
||||
position: @position
|
||||
max: @clues.length
|
||||
|
||||
@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) ->
|
||||
modalElement = @$('.js-positionOrigin')
|
||||
modal = modalElement.get(0).getBoundingClientRect()
|
||||
# reset scale in order to get correct measurements
|
||||
$.Velocity.hook(@modalWindow, 'scale', 1)
|
||||
|
||||
modal = @modalWindow.get(0).getBoundingClientRect()
|
||||
position = ''
|
||||
left = 0
|
||||
top = 0
|
||||
|
@ -1117,16 +1167,43 @@ class cluesRef extends App.ControllerContent
|
|||
moveArrow = modal.height/2 + maxHeight - (top + modal.height)
|
||||
top = maxHeight - modal.height
|
||||
|
||||
# show window
|
||||
modalElement
|
||||
.addClass "is-visible is-#{ position }"
|
||||
.css
|
||||
'left': left
|
||||
'top': top
|
||||
transformOrigin = @getTransformOrigin(modal, position)
|
||||
|
||||
if moveArrow
|
||||
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) ->
|
||||
###
|
||||
|
|
|
@ -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>
|
|
@ -1,33 +1,4 @@
|
|||
<div class="modal modal--clue">
|
||||
<div class="modal-backdrop" style="background:
|
||||
radial-gradient(
|
||||
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 class="modal-backdrop js-backdrop"></div>
|
||||
<div class="modal-spacer js-positionOrigin"></div>
|
||||
</div>
|
|
@ -930,16 +930,17 @@ textarea,
|
|||
|
||||
.modal-backdrop {
|
||||
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 {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
padding: 18px;
|
||||
|
||||
&.is-visible {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-arrow {
|
||||
|
@ -953,18 +954,18 @@ textarea,
|
|||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.modal-spacer.is-above .modal-arrow {
|
||||
.modal-spacer[data-position="above"] .modal-arrow {
|
||||
left: 50%;
|
||||
top: 100%;
|
||||
background: hsl(210,5%,97%);
|
||||
}
|
||||
|
||||
.modal-spacer.is-below .modal-arrow {
|
||||
.modal-spacer[data-position="below"] .modal-arrow {
|
||||
left: 50%;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.modal-spacer.is-left .modal-arrow {
|
||||
.modal-spacer[data-position="left"] .modal-arrow {
|
||||
left: 100%;
|
||||
top: 50%;
|
||||
}
|
||||
|
@ -1007,10 +1008,11 @@ textarea,
|
|||
}
|
||||
|
||||
kbd {
|
||||
background: hsl(200,8%,21%);
|
||||
background: hsl(200,8%,90%);
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 1px black;
|
||||
color: white;
|
||||
border: 1px solid hsl(240,7%,77%);
|
||||
box-shadow: 0 1px rgba(0,0,0,.08);
|
||||
color: hsl(240,7%,37%);
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
margin: 0 1px;
|
||||
|
|
Loading…
Reference in a new issue