80 lines
1.8 KiB
CoffeeScript
80 lines
1.8 KiB
CoffeeScript
import shallowequal from 'shallowequal'
|
|
import * as React from 'react'
|
|
|
|
import {Container, Renderer} from '@avocado/graphics'
|
|
import {Vector} from '@avocado/math'
|
|
|
|
class ContainerComponent extends React.Component
|
|
|
|
constructor: (props) ->
|
|
|
|
super()
|
|
|
|
@isDirty = true
|
|
@renderer = new Renderer props.size, 'canvas'
|
|
@container = new Container()
|
|
|
|
@defaultProps: size: [0, 0]
|
|
|
|
componentDidMount: ->
|
|
|
|
@containerRef.appendChild @renderer.element()
|
|
|
|
window.addEventListener 'resize', @recalculateBackgroundSize
|
|
|
|
componentDidUpdate: ->
|
|
|
|
# Performance: Check if the children actually changed after render.
|
|
@isDirty = shallowequal @previousChildren, @container.children()
|
|
|
|
# Tick the first time.
|
|
return unless @isDirty
|
|
|
|
@tick()
|
|
@isDirty = false
|
|
|
|
componentWillUnmount: ->
|
|
|
|
window.removeEventListener 'resize', @recalculateBackgroundSize
|
|
|
|
@renderer.destroy(); @renderer = null
|
|
|
|
recalculateBackgroundSize: =>
|
|
|
|
s = getComputedStyle @renderer.element()
|
|
domSize = [s.width, s.height].map (n) -> parseInt n
|
|
|
|
[w, h] = Vector.mul [16, 16], Vector.div domSize, @props.size
|
|
@renderer.element().style.backgroundSize = "#{w}px #{h}px"
|
|
|
|
render: ->
|
|
|
|
# Literally one big side-effect.
|
|
@renderer.resize @props.size
|
|
@recalculateBackgroundSize()
|
|
|
|
@previousChildren = @container.children()
|
|
@container.removeChildren()
|
|
children = React.Children.map @props.children, (child) =>
|
|
|
|
React.cloneElement child,
|
|
|
|
setIntoContainer: (renderable) =>
|
|
|
|
return unless renderable
|
|
@container.addChild renderable
|
|
|
|
tickContainer: @tick
|
|
|
|
<div
|
|
className="container"
|
|
ref={@setContainerRef}
|
|
style={'lineHeight': 0}
|
|
>{children}</div>
|
|
|
|
setContainerRef: (@containerRef) => return
|
|
|
|
tick: => @renderer.render @container
|
|
|
|
export default ContainerComponent
|