Created
September 22, 2015 23:52
-
-
Save gurasa/bf4c549b349c888aaf5a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### | |
# 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