Skip to content

Instantly share code, notes, and snippets.

@Loiree
Last active October 16, 2015 16:22
Show Gist options
  • Save Loiree/9b3b0410d98a047ed162 to your computer and use it in GitHub Desktop.
Save Loiree/9b3b0410d98a047ed162 to your computer and use it in GitHub Desktop.
Filter
# Filter
# показывает блоки по выбранному фильтру
# IE9* (дергается анимация), iOS
# --------------------------------------------------------
# cache
# filterCat — родительский блок со списками категорий
# filterBody — родительский блок с блоками
# settings
# anim — выбор функции анимации (из animShow и animHide)
# bindEvents — по клику на категорию из filterCat запускаем фильтр
# animShow — список анимаций для появления блоков
# animHide — список анимаций для скрытия блоков
# prepare — проверяет, не запущена ли уже анимация фильтра, достает нужные параметры из CSS, обрабатывает и передает данные в setShow и setHide
# setShow — запускает анимацию появления нужных блоков
# setHide — запускает анимацию скрытия нужных блоков
# setActiveCat — добавляет подсветку выбранному пункту категории
# --------------------------------------------------------
Filter = do ->
init: ->
do @cache
do @settings
do @bindEvents
do @animShow
do @animHide
cache: ->
@filterCat = document.getElementById("filter-cat")
@filterBody = document.getElementById("filter-body")
@blocksWidth = []
for i in @filterBody.children
width = parseInt(getComputedStyle(i).width)
@blocksWidth.push(width)
@blocksHeight = []
for i in @filterBody.children
height = parseInt(getComputedStyle(i).height)
@blocksHeight.push(height)
settings: ->
@duration = 350
@timing = "ease-out"
@anim = "scaleWidth"
bindEvents: ->
self = @
for i in @filterCat.children then i.addEventListener "click", -> self.prepare(@)
animShow: ->
@animForShow = switch @anim
when "opacity" then (params, progress) -> if params.opacity is 0 then params.obj.style.opacity = progress
when "widthHeight" then (params, progress) ->
if params.opacity is 0 then params.obj.style.opacity = progress
if parseInt(params.width) is 0 then params.obj.style.width = "#{@blocksWidth[params.num] * progress}px"
if parseInt(params.height) is 0 then params.obj.style.height = "#{@blocksHeight[params.num] * progress}px"
when "scale" then (params, progress) ->
if params.opacity is 0 then params.obj.style.opacity = progress
if parseInt(params.transform[3]) is 0 then params.obj.style.transform = "scale(#{progress})"
when "scaleWidth" then (params, progress) ->
if params.opacity is 0 then params.obj.style.opacity = progress
if parseInt(params.transform[3]) is 0 then params.obj.style.transform = "scale(#{progress})"
if parseInt(params.width) is 0 then params.obj.style.width = "#{0 + @blocksWidth[params.num] * progress}px"
animHide: ->
@animForHide = switch @anim
when "opacity" then (params, progress) -> if params.opacity isnt 0 then params.obj.style.opacity = 1 - progress
when "widthHeight" then (params, progress) ->
if params.opacity isnt 0 then params.obj.style.opacity = 1 - progress
if parseInt(params.width) isnt 0 then params.obj.style.width = "#{@blocksWidth[params.num] * (1 - progress)}px"
if parseInt(params.height) isnt 0 then params.obj.style.height = "#{@blocksHeight[params.num] * (1 - progress)}px"
when "scale" then (params, progress) ->
if params.opacity isnt 0 then params.obj.style.opacity = 1 - progress
if params.transform[3] isnt "0" then params.obj.style.transform = "scale(#{1 - progress})"
when "scaleWidth" then (params, progress) ->
if params.opacity isnt 0 then params.obj.style.opacity = 1 - progress
if params.transform[3] isnt "0" then params.obj.style.transform = "scale(#{1 - progress})"
if parseInt(params.width) isnt 0
params.obj.style.width = "#{@blocksWidth[params.num] * (1 - progress)}px"
prepare: (cat) ->
obj = cat
cat = cat.getAttribute("data-filter")
@isShow = @isShow or false
if !@isShow
@isShow = true
@setActiveCat(obj)
for i in @filterBody.children
attr = i.getAttribute("data-filter")
transform = getComputedStyle(i).transform
if transform is undefined then transform = getComputedStyle(i).msTransform
if transform is undefined then transform = getComputedStyle(i).webkitTransform
if transform is undefined then transform = getComputedStyle(i).oTransform
if transform is undefined then transform = getComputedStyle(i).mozTransform
# определяем порядковый номер блока
parent = i.parentNode
for k in [0...parent.children.length]
if i is parent.children[k] then num = k
params =
obj: i
width: parseInt(getComputedStyle(i).width)
height: parseInt(getComputedStyle(i).height)
opacity: parseInt(getComputedStyle(i).opacity)
transform: transform.substr(7).substr(0, transform.length-1).split(",")
num: num
if attr is cat or cat is "all"
@setShow(params)
else
@setHide(params)
setShow: (params) ->
fn = (progress) =>
@animForShow(params, progress)
if progress is 1 then @isShow = false
AnimHandler.init fn, @duration, @timing
setHide: (params) ->
fn = (progress) =>
@animForHide(params, progress)
AnimHandler.init fn, @duration, @timing
setActiveCat: (obj) ->
for i in @filterCat.children
i.classList.remove("active")
obj.classList.add("active")
<div id="filter">
<ul id="filter-cat">
<li class="active" data-filter="all">All</li>
<li data-filter="first">First</li>
<li data-filter="second">Second</li>
<li data-filter="third">Third</li>
<li data-filter="fourth">Fourth</li>
</ul>
<div id="filter-body"><!--
--><div data-filter="first">For first</div><!--
--><div data-filter="second">For second</div><!--
--><div data-filter="third">For third</div><!--
--><div data-filter="first">For first</div><!--
--><div data-filter="second">For second</div><!--
--><div data-filter="third">For third</div><!--
--><div data-filter="fourth">For fourth</div><!--
--><div data-filter="fourth">For fourth</div><!--
--></div>
</div>
// FILTER
// ==================================
#filter
width 800px
height 400px
background green
margin 0 auto
ul
margin-bottom 20px
background red
text-align center
padding 10px 0
user-select none
li
display inline-block
margin 0 20px
&:hover
cursor pointer
color amber
.active
color amber
#filter-body
div
width 150px
height 100px
display inline-block
margin 0px
background pink
text-align center
line-height 100px
overflow hidden
vertical-align middle
transform scale(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment