Skip to content

Instantly share code, notes, and snippets.

@gampleman
Created May 15, 2012 21:12
Show Gist options
  • Save gampleman/2705182 to your computer and use it in GitHub Desktop.
Save gampleman/2705182 to your computer and use it in GitHub Desktop.
Simple scene graph renderer, see http://gampleman.eu/post/23109338640/writing-your-own-canvas-scene-graph for more info.
# Entity
# ======
# Entity is the base class of the Scene-Graph renderer and represents
# a single object.
class Entity
# When `perform_caching` is set to `yes` the renderer will cache the
# result as an image, unless `is_cached` is set to `no`.
perform_caching: no
is_cached: false
# `parent` is a reference to the entity this class is a child to.
parent: null
x: 0
y: 0
rotation: 0
width: 0
height: 0
# It is a responsibility of each entity to render its children.
children: []
# The third argument is a function that takes a 2d context
# and draws the shape into it.
constructor: (@width, @height, @draw = @draw) ->
@canvas = document.createElement('canvas')
@canvas.width = @width
@canvas.height = @height
# Short cut for doing
#
# entity = new Entity 100, 100, (ctx) -> ...
# scene.children.push(entity)
# entity.parent = scene
#
# is
#
# entity = scene.add_child 100, 100, (ctx) -> ...
add_child: (w, h, d) ->
child = new Entity w, h, d
@children.push child
child.parent = @
child
# Returns a canvas instance.
render: ->
return @canvas if @perform_caching and @is_cached
ctx = @canvas.getContext('2d')
ctx.clearRect(0, 0, @width, @height)
@draw(ctx)
@is_cached = true
@canvas
# This is the default drawing function.
# In custom implementations you may want to call super
# if you want the entity to still be able to function as
# a collection.
draw: (ctx) ->
for child in @children
if child.rotation isnt 0
ctx.save()
ctx.translate(child.x, child.y)
ctx.rotate(child.rotation)
ctx.drawImage(child.render(), 0, 0)
ctx.restore()
else
ctx.drawImage(child.render(), child.x, child.y)
false # return false so that array isn't created from comprehension
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment