Jump To …
README lib / psd / blend_mode.coffee lib / psd / channel_image.coffee lib / psd / color.coffee lib / psd / descriptor.coffee lib / psd / file.coffee lib / psd / header.coffee lib / psd / image.coffee lib / psd / image_export.coffee lib / psd / image_exports / png.coffee lib / psd / image_format.coffee lib / psd / image_formats / layer_raw.coffee lib / psd / image_formats / layer_rle.coffee lib / psd / image_formats / raw.coffee lib / psd / image_formats / rle.coffee lib / psd / image_mode.coffee lib / psd / image_modes / cmyk.coffee lib / psd / image_modes / greyscale.coffee lib / psd / image_modes / rgb.coffee lib / psd / init.coffee lib / psd / layer / blend_modes.coffee lib / psd / layer / blending_ranges.coffee lib / psd / layer / channel_image.coffee lib / psd / layer / helpers.coffee lib / psd / layer / info.coffee lib / psd / layer / mask.coffee lib / psd / layer / name.coffee lib / psd / layer / position_channels.coffee lib / psd / layer.coffee lib / psd / layer_info / blend_clipping_elements.coffee lib / psd / layer_info / blend_interior_elements.coffee lib / psd / layer_info / fill_opacity.coffee lib / psd / layer_info / gradient_fill.coffee lib / psd / layer_info / layer_id.coffee lib / psd / layer_info / layer_name_source.coffee lib / psd / layer_info / legacy_typetool.coffee lib / psd / layer_info / locked.coffee lib / psd / layer_info / metadata.coffee lib / psd / layer_info / nested_section_divider.coffee lib / psd / layer_info / object_effects.coffee lib / psd / layer_info / section_divider.coffee lib / psd / layer_info / solid_color.coffee lib / psd / layer_info / typetool.coffee lib / psd / layer_info / unicode_name.coffee lib / psd / layer_info / vector_mask.coffee lib / psd / layer_info / vector_origination.coffee lib / psd / layer_info / vector_stroke.coffee lib / psd / layer_info / vector_stroke_content.coffee lib / psd / layer_info.coffee lib / psd / layer_mask.coffee lib / psd / lazy_execute.coffee lib / psd / mask.coffee lib / psd / node.coffee lib / psd / nodes / ancestry.coffee lib / psd / nodes / build_preview.coffee lib / psd / nodes / group.coffee lib / psd / nodes / layer.coffee lib / psd / nodes / root.coffee lib / psd / nodes / search.coffee lib / psd / path_record.coffee lib / psd / resource.coffee lib / psd / resource_section.coffee lib / psd / resources / layer_comps.coffee lib / psd / resources.coffee lib / psd / util.coffee lib / psd.coffee shims / init.coffee shims / png.coffee

# node.coffee lib/psd/ |
--- | ---
¶ |
    _        = require 'lodash'
    {Module} = require 'coffeescript-module'

    module.exports = class Node extends Module
      @includes require('./nodes/ancestry.coffee')
      @includes require('./nodes/search.coffee')
      @includes require('./nodes/build_preview.coffee')

      @PROPERTIES: ['name', 'left', 'right', 'top', 'bottom', 'height', 'width']

      type: 'node'

      constructor: (@layer, @parent = null) ->
        @layer.node = @
        @_children = []

        @name = @layer.name

        @forceVisible = null

        @coords =
          top: @layer.top
          bottom: @layer.bottom
          left: @layer.left
          right: @layer.right

        @topOffset = 0
        @leftOffset = 0

        @createProperties()

      createProperties: ->
        Object.defineProperty @, 'top',
          get: -> @coords.top + @topOffset
          set: (val) -> @coords.top = val

        Object.defineProperty @, 'right',
          get: -> @coords.right + @leftOffset
          set: (val) -> @coords.right = val

        Object.defineProperty @, 'bottom',
          get: -> @coords.bottom + @topOffset
          set: (val) -> @coords.bottom = val

        Object.defineProperty @, 'left',
          get: -> @coords.left + @leftOffset
          set: (val) -> @coords.left = val

        Object.defineProperty @, 'width',  get: -> @right - @left
        Object.defineProperty @, 'height', get: -> @bottom - @top

      get: (prop) ->
        value = if @[prop]? then @[prop] else @layer[prop]
        if typeof value is 'function' then value() else value

      visible: ->
        return false if @layer.clipped and not @clippingMask().visible()
        if @forceVisible? then @forceVisible else @layer.visible

      hidden: -> not @visible()

      isLayer: -> @type is 'layer'
      isGroup: -> @type is 'group'
      isRoot: ->  @type is 'root'

      clippingMask: ->
        return null unless @layer.clipped
        @clippingMaskCached or= (
          maskNode = @nextSibling()
          maskNode = maskNode.nextSibling() while maskNode.clipped
          maskNode
        )

      clippedBy: -> @clippingMask()

      export: ->
        hash =
          type: null
          visible: @visible()
          opacity: @layer.opacity / 255.0
          blendingMode: @layer.blendingMode()

        hash[prop] = @[prop] for prop in Node.PROPERTIES
        hash

      updateDimensions: ->
        return if @isLayer()

        child.updateDimensions() for child in @_children

        return if @isRoot()

        nonEmptyChildren = @_children.filter((c) -> not c.isEmpty())
        @left = _.min(nonEmptyChildren.map((c) -> c.left)) or 0
        @top = _.min(nonEmptyChildren.map((c) -> c.top)) or 0
        @bottom = _.max(nonEmptyChildren.map((c) -> c.bottom)) or 0
        @right = _.max(nonEmptyChildren.map((c) -> c.right)) or 0

generated Tue May 12 2015 11:00:56 GMT-0400 (EDT)