Instantly share code, notes, and snippets.

Embed
What would you like to do?
###
# Class.Canvas
###
class Class.Canvas
constructor: (options)->
# Variables
@items = []
@fps = 30
@itemIncrement = 0
# Context initialize
unless options? then return false
unless options.canvasId? then return false
@el = document.getElementById options.canvasId
if $? then @$el = $(@el)
@width = @el.width = if options.width? then options.width else 800
@height = @el.height = if options.height? then options.height else 800
@ctx = @el.getContext("2d")
# イベントリスナーの登録
@events()
events: =>
@el.addEventListener 'tick', @onTick, false
onTick: (e)=>
# イベントのバブリングをキャンセル
e.stopPropagation()
# canvasを描画
@draw()
startLoop: =>
# canvasの初期描画
@draw()
# ループを作成
@interval = setInterval @tick, Math.floor(1000/@fps)
stopLoop: =>
# ループを削除
if @interval? then clearInterval @interval
tick: =>
@el.dispatchEvent new Event('tick')
addItem: (_instance)=>
unless _instance?
console.error 'undefind "instance" => You must set the instance of Path Class to the second argument.'
return false
# IDだけ重複チェックを行う
_id = if _instance.id? then _instance.id else _instance.id = @getAutoInstanceId()
unless @validationInstanceID _id
console.error '同じIDのアイテムが存在します'
return false
@items.push
id: _id
instance: _instance
zIndex: if _instance.zIndex? then _instance.zIndex else _instance.zIndex = @getAutoInstanceZIndex()
_instance.canvas = @
_instance.init()
validationInstanceID: (_id)=>
unless _.findWhere(@items, {id: _id}) then true else false
getAutoInstanceId: =>
"instance#{@itemIncrement++}"
getAutoInstanceZIndex: =>
_maxZIndexItem = _.max @items, (item)->
item.zIndex
zIndex = _maxZIndexItem.zIndex + 1
removeItem: (_id)=>
_item = _.findWhere(@items, {id: _id})
if _item
@items = _.without @items, _item
else
false
draw: =>
# Clear the canvas
@ctx.clearRect 0, 0, @width, @height
if @items.length > 0
# zIndex 順に整列
_sortItems = _.sortBy @items, 'zIndex'
for item in _sortItems
item.instance.draw()
###
# Class.CanvasItem
###
class Class.CanvasItem
constructor: ->
if arguments.length > 0
if arguments[0].id? then @id = arguments[0].id
if arguments[0].zIndex? then @zIndex = arguments[0].zIndex
if arguments[0].options? then @options = arguments[0].options
@frame = 0
@events = []
addEvents: =>
@addEvent 'tick', @onTick, false
addEvent: (_type, _listener, _capture)=>
@canvas.el.addEventListener _type, _listener, _capture
@events.push eventKey =
type: _type
listener: _listener
capture: _capture
removeEvents: =>
for eventKey in @events
@canvas.el.removeEventListener eventKey.type, eventKey.listener, eventKey.capture
remove: =>
@removeEvents()
@canvas.removeItem @id
onTick: =>
@frame++
draw: =>
console.log 'Undefind draw setting.'
###
# Class.Twinkle
###
class Class.Twinkle extends Class.CanvasItem
init: =>
# context
@ctx = @canvas.ctx
# options setup
@originX = @canvas.width/2
@originY = @canvas.height/2
@angle = Math.random() * 360 * Math.PI / 180
@speed = 1/5
@style =
radius: 3
fillStyle: "#ffffff"
globalAlpha: 0.2
@addEvents()
draw: =>
# 描画前のスタイルを保存
@ctx.save()
# 位置の移動
@originX = @originX + @frame * @speed * Math.cos @angle
@originY = @originY + @frame * @speed * Math.sin @angle
# キラキラ
@ctx.fillStyle = @style.fillStyle
if @frame >= 30
@ctx.globalAlpha = 1 - 0.02 * (@frame - 30)
# パスの描画
_a = 20
@ctx.beginPath()
@ctx.moveTo @originX, @originY
_x = _a * -1
while _x++ <= _a
if _x <= 0
@ctx.lineTo @originX + _x, @originY + (_a / (_x - 1)) + 1
else
@ctx.lineTo @originX + _x, @originY + ((_a / (_x + 1)) - 1) * -1
while _x-- >= _a * -1
if _x >= 0
@ctx.lineTo @originX + _x, @originY + (_a / (_x + 1)) - 1
else
@ctx.lineTo @originX + _x, @originY + ((_a / (_x - 1)) + 1) * -1
@ctx.closePath()
# 塗りつぶし
@ctx.fill()
# 広がる光
if @frame < 30
# 2個目
# スタイル設定
_radius = @style.radius - 1 + @frame
@ctx.fillStyle = @style.fillStyle
@ctx.globalAlpha = 1 / (@frame/2)
# パスの描画
@ctx.beginPath()
@ctx.arc @originX, @originY, _radius, 0, 2*Math.PI, true
@ctx.closePath()
# 塗りつぶし
@ctx.fill()
if @frame > 90
@frame = 0
@originX = @canvas.width/2
@originY = @canvas.height/2
# 描画前のスタイルを復元
@ctx.restore()
###
# Run
###
$ ->
window.Canvas = new Class.Canvas
canvasId: 'canvas'
height: 300
Canvas.$el.css
background: '#000'
_i = 0
while _i++ < 100
setTimeout ->
Canvas.addItem new Class.Twinkle()
, _i * 500
# Animation start
Canvas.startLoop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment