Skip to content

Instantly share code, notes, and snippets.

@kajiyan
Last active August 29, 2015 14:06
Show Gist options
  • Save kajiyan/b3265b37def5e357fbee to your computer and use it in GitHub Desktop.
Save kajiyan/b3265b37def5e357fbee to your computer and use it in GitHub Desktop.
jquery.typePranimate.coffee - 画像切り替えによるパラパラアニメーション

jquery.typePranimate.js

画像切り替えによるパラパラアニメーション

Depends

paranimate = $(".js-paranimate").typePranimate
# src: ["#{sn.tf.get_image_path("relative")}/dev/0_top_title.png"]
frameRate: 1
size: "cover"
src: [
["#{sn.tf.get_image_path("relative")}/dev/0_top_title.png", "#{sn.tf.get_image_path("relative")}/dev/1_top_title.png", "#{sn.tf.get_image_path("relative")}/dev/2_top_title.png"]
["#{sn.tf.get_image_path("relative")}/dev/3_top_title.png", "#{sn.tf.get_image_path("relative")}/dev/4_top_title.png", "#{sn.tf.get_image_path("relative")}/dev/5_top_title.png"]
]
paranimateInstance = paranimate.data "typePranimate"
paranimateInstance.setup().then( =>
console.log "done"
paranimateInstance.refresh()
paranimateInstance.animatePlay
animateID: 0
callback: ->
console.log "animate complete"
loopAnimate: false
)
do ( $=jQuery, window=window, document=document ) ->
unless window.console?
window.console = log: $.noop
$window = $(window)
$document = $(document)
ns = $.TypePranimate = {}
# ============================================================
# EventFrame
class ns.Event
constructor: ->
@_callbacks = {}
on: (ev, callback) ->
evs = ev.split(' ')
for name in evs
@_callbacks[name] or= []
@_callbacks[name].push(callback)
@
one: (ev, callback) ->
@on ev, ->
@off(ev, arguments.callee)
callback.apply(@, arguments)
trigger: (args...) ->
ev = args.shift()
list = @_callbacks?[ev]
return unless list
for callback in list
if callback.apply(@, args) is false
break
@
off: (ev, callback) ->
unless ev
@_callbacks = {}
return @
list = @_callbacks?[ev]
return this unless list
unless callback
delete @_callbacks[ev]
return this
for cb, i in list when cb is callback
list = list.slice()
list.splice(i, 1)
@_callbacks[ev] = list
break
@
bind: -> @on.apply @, arguments
unbind: -> @off.apply @, arguments
# ============================================================
# TypePranimate
class ns.TypePranimate extends ns.Event
defaults:
id: null
src: []
size: null # cover OR contain
frameRate: 24
#--------------------------------------------------------------
constructor: (@$el, options) ->
console.log "TypePranimate - constructor"
@options = $.extend {}, @defaults, options
if @options.id?
@$holder = $("<div id=\"#{@options.id}\" class=\"pranimate-holder\"></div>")
else
@$holder = $("<div class=\"pranimate-holder\"></div>")
@thread = new $.TypeThread
frameRate: @options.frameRate
#--------------------------------------------------------------
setup: () ->
return $.Deferred (defer) =>
@frameSet = []
@frameNameSet = [] # すべてのアニメーション画像を結合した配列
@frameSection = [] # アニメーションの開始と終了位置
@ftameBodys = []
@loadingProgress = 0 # アニメーションのローディング状態
@totalFrame = 0 # アニメーションのトータルフレーム
offset = 0
# フレームの数を算出
if @_type(@options.src) is "array"
for wrapperVal, i in @options.src
if @_type(wrapperVal) is "string"
@frameSection.push
"start": 0
"end": @options.src.length
# @animationFrame = @options.src.length
else if @_type(wrapperVal) is "array"
@frameSection.push
"start": offset
"end": offset + wrapperVal.length
offset = wrapperVal.length
# @animationFrame += wrapperVal.length
# 配列で画像パスが渡されているか判定
if @_type(@options.src) is "array"
for wrapperVal, i in @options.src
# animateBody = $("<div class=\"pranimate-body-#{i}\"></div>")
# アニメーションが複数か一つか判定
if @_type(wrapperVal) is "string"
# 配列を結合する
@frameNameSet.push(wrapperVal)
else if @_type(wrapperVal) is "array"
for innerValue, j in wrapperVal
if @_type(innerValue) is "string"
@frameNameSet.push(innerValue)
else
$.error("Some error TypePranimate src array in string object onry.");
else
$.error("Some error TypePranimate src array object onry.");
else
$.error("Some error TypePranimate src array object onry.");
# 画像のトータル枚数
@totalFrame = @frameNameSet.length
# DOMに画像を追加する
animateSetup = (frameSet) =>
for value, i in @frameSection
# アニメーション用の画像を包括する要素
# position を指定して子要素の起点とする
frameBody = $("<div class=\"pranimate-body is-#{i}\"></div>")
.css
"position": "relative"
"top": 0
"left": 0
# アニメーションごとに要素を作る
layerIndex = 0
for j in [value.start..(value.end - 1)]
# 画像のスタイルを設定する
# position を指定で要素を重ねる
frameSet[j].css
"display": "none"
"position": "absolute"
"top": 0
"left": 0
layerIndex++
frameBody.append(frameSet[j])
@ftameBodys.push(frameBody)
# エレメントに画像を追加する
@$el.append(@ftameBodys)
console.log "---------- paranimate setup ----------"
defer.resolve()
# 画像をローディングする
loadFrame = (frameNameSet) =>
($.loadImgWoCache(frameNameSet[@loadingProgress])).then ($img) =>
@frameSet.push($img)
@loadingProgress++
if @loadingProgress is @totalFrame
# すべての画像のローディングが完了したらDOMに追加する
animateSetup(@frameSet)
else
loadFrame(frameNameSet)
loadFrame(@frameNameSet)
.promise()
#--------------------------------------------------------------
animatePlay: (options) ->
return $.Deferred (defer) =>
defaults =
animateID: 0
callback: $.noop
loopAnimate: false
options = $.extend {}, defaults, options
# 処理経過
progress = 0
start = @frameSection[options.animateID].start
end = @frameSection[options.animateID].end - 1
# アニメーション用のタイムラインをセットアップ
@thread.setup()
# 処理状態を管理する deferred
updateDefered = new $.Deferred()
# アニメーションの処理
@thread.update =>
frameNum = start + progress
if options.loopAnimate and progress is 0
@frameSet[end]
.css "display", "none"
if @frameSet[frameNum - 1]?
@frameSet[frameNum - 1]
.css "display", "none"
@frameSet[frameNum]
.css "display", "block"
# 最後のフレームに到達した時の処理
if frameNum is end
if options.loopAnimate
progress = -1
else
@thread.break()
options.callback()
defer.resolve()
# アニメーションのフレームを進める
progress++
.promise()
#--------------------------------------------------------------
animateStop: () ->
#--------------------------------------------------------------
_insertAnimation: (e) ->
console.log "_insertAnimation"
#--------------------------------------------------------------
_type: (obj) ->
# 型判定のメソッド
if obj == undefined or obj == null
return String obj
classToType = {
'[object Boolean]': 'boolean',
'[object Number]': 'number',
'[object String]': 'string',
'[object Function]': 'function',
'[object Array]': 'array',
'[object Date]': 'date',
'[object RegExp]': 'regexp',
'[object Object]': 'object'
}
return classToType[Object.prototype.toString.call(obj)]
#--------------------------------------------------------------
refresh: (width, height) ->
console.log "TypePranimate - Refresh"
@imgWidth = @frameSet[0][0].width
@imgHeight = @frameSet[0][0].height
@holderWidth = if width? then width else $window.innerWidth()
@holderHeight = if height? then height else $window.innerHeight()
return @_sizefit()
#--------------------------------------------------------------
_sizefit: () ->
return $.Deferred (defer) =>
onDone = =>
defer.resolve()
@$img = @$el.find("img")
if @options.size is "cover"
fixScale = Math.max(@holderWidth / @imgWidth, @holderHeight / @imgHeight)
@$img.css
"width": @imgWidth * fixScale
"height": @imgHeight * fixScale
"top": -((@imgHeight * fixScale - @holderHeight) / 2) + "px"
"left": -((@imgWidth * fixScale - @holderWidth) / 2) + "px"
onDone()
else if @options.size is "contain"
if (@holderWidth / @holderHeight) > (@imgWidth / @imgHeight)
delta = Math.floor((@holderWidth - @holderHeight * (@imgWidth / @imgHeight)) / 2)
@$img.css
"width": "auto"
"height": "100%"
"top": 0
"left": delta
onDone()
else
delta = Math.floor((@holderHeight - @holderWidth / (@imgWidth / @imgHeight)) / 2)
@$img.css
"width": "100%"
"height": "auto"
"top": delta
"left": 0
onDone()
.promise()
# ============================================================
# bridge to plugin
$.fn.typePranimate = (options) ->
return @each (i ,el) ->
$el = $(el)
instance = new ns.TypePranimate $el, options
$el.data "typePranimate", instance
$.typePranimate = ns
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment