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:
|
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) ->
|
||||||
###
|
###
|
||||||
|
|
|
@ -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 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>
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue