taataa / tapspace

Zoomable user interface library for web apps.
https://taataa.github.io/tapspace/
MIT License
58 stars 8 forks source link

Improved FractalLoader #159

Closed axelpale closed 1 year ago

axelpale commented 1 year ago

In v2.0.0-alpha.8 the FractalLoader already works but has issues:

Observations about opening:

Sketch of improved FractalLoader usage:

const loader = new FractalLoader({
  seedId: 1234,
  renderChunkPlaceholder: function (chunkId) {
  },
  renderChunkFinal: function (chunkId, data) {
  },
  fetchChunkData: function (id, callback) {
  }, 
  findChildPosition: function (component, childId) {

  },
  openChild: function (id, parentId, then) {
    const parentChunk = getChunk(parentId)
    const childPosition = findChildPosition(parentChunk, id)
    const placeholder = renderChunkPlaceholder(id)
    placeholder.moveTo(childPosition)
    fetchChunkData(id, function (err, data) {
      if (err) return then(err)
      const childChunk = renderChunkFinal(id, data)
      childChunk.setParent(space)
      childChunk.moveTo(childPosition)
      placeholder.remove()
      then(null)
    })
  },
  openParent: function (id, childId, then) {
    const childPosition = getPosition(childId)
    const placeholder = renderChunkPlaceholder(id)
    placeholder.moveTo(childPosition)
    fetchChunkData(id, function (err, data) {
      if (err) return then(err)
      const parentChunk = renderChunkFinal(id, data)
      const insertionPoint = findChildPosition(parentChunk, childId)
      parentChunk.setParent(space)
      parentChunk.matchPoint(insertionPoint, childPosition)
      placeholder.remove()
      then(null)
    })
  },
  recursionLimiter: function () {
  },
})
axelpale commented 1 year ago

Next iteration. The methods openChild and openParent are implemented internally. Also the property names are simplified.

const loader = new tapspace.loaders.FractalLoader({
  viewport: viewport,

  placeholder: function (id) {
    // Render placeholder
    return tapspace.createCircle(10, 'black')
  },

  generator: function (id, data) {
    return tapspace.createCircle(15, data.color)
  },

  fetcher: function (id, callback) {
    setTimeout(() => {
      callback(null, { color: 'red' })
    }, 1000)
  },

  tracker: function (parent, childId) {
    return parent.atAnchor().offset(20, 0)
  },

  backer: function (childId) {
    switch (childId) {
      case 'b':
        return 'a'
      case 'a':
        return null
      default:
        return null
    }
  },

  limiter: function (depth) {
    return depth < 3
  }
})

loader.init('a', viewport.atCenter())
loader.openChild('a', 'b')
loader.openParent('a')
axelpale commented 1 year ago

Implemented as TreeLoader around v2.0.0-alpha.14