在Paper.js上切换多个工具

时间:2018-03-11 00:58:16

标签: paperjs

有人可以向我展示一个工作示例(JSFiddle或其他)如何在Paper.js上有两个工具,用户可以点击这些工具来绘制不同的形状,例如一个用于圆圈,一个用于方块? 谢谢!

1 个答案:

答案 0 :(得分:1)

你在这里至少有几个选择,

1。从paper.tools

激活工具

Paper.js允许您通过调用tool.activate() 激活工具,这只会导致该特定工具收到Tool events,例如mousedownmousedrag等......

当您通过Tool创建新new paper.Tool()时,该工具会添加到paper.tools中,以便您可以在该数组中查找工具并在其上调用tool.activate()

一个例子:

window.onload = () => {
  // Setup Paper

  paper.setup(document.querySelector('canvas'))
    
  // Find a Tool in `paper.tools` and activate it

  const activateTool = name => {
    const tool = paper.tools.find(tool => tool.name === name)
    tool.activate()
  }

  // Tool Path, draws paths on mouse-drag.
  // Note: Wrap each Tool in an IIFE to avoid polluting the 
  //       global scope with variables related with that Tool.

  ;(() => {
    const tool = new paper.Tool()
    tool.name = 'toolPath'

    let path

    tool.onMouseDown = function(event) {
      path = new paper.Path()
      path.strokeColor = '#424242'
      path.strokeWidth = 4
      path.add(event.point)
    }

    tool.onMouseDrag = function(event) {
      path.add(event.point)
    }
  })()

  // Tool Circle, draws a 30px circle on mousedown

  ;(() => {
    const tool = new paper.Tool()
    tool.name = 'toolCircle'

    let path

    tool.onMouseDown = function(event) {
      path = new paper.Path.Circle({
        center: event.point,
        radius: 30,
        fillColor: '#9C27B0'
      })
    }
  })()

  // Attach click handlers for Tool activation on all
  // DOM buttons with class '.tool-button'

  document.querySelectorAll('.tool-button').forEach(toolBtn => {
    toolBtn.addEventListener('click', e => {
      activateTool(e.target.getAttribute('data-tool-name'))
    })
  })
}
html,
body,
canvas {
  width: 100%;
  height: 100%;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.11.5/paper-core.js"></script>

<button 
 class="tool-button"
 data-tool-name="toolPath">
 Draw Paths
</button>

<button 
 class="tool-button"
 data-tool-name="toolCircle">
 Stamp Circles
</button>

<canvas resize></canvas>

2。创建ToolStack

但是,我发现创建ToolStack类更实际,因为它允许我稍后添加其他方法,即isToolActive()onToolSelect()(用于添加is-active }类到DOM工具按钮)等。

然后,ToolStack应该实现处理工具的各种方法,首先是activateTool方法,它将按名称查找Tool并调用它的tool.activate()方法。

一个例子:

window.onload = () => {
  // Setup Paper

  paper.setup(document.querySelector('canvas'))

  // Toolstack

  class ToolStack {
    constructor(tools) {
      this.tools = tools.map(tool => tool())
    }

    activateTool(name) {
      const tool = this.tools.find(tool => tool.name === name)
      tool.activate()
    }

    // add more methods here as you see fit ...
  }

  // Tool Path, draws paths on mouse-drag

  const toolPath = () => {
    const tool = new paper.Tool()
    tool.name = 'toolPath'

    let path

    tool.onMouseDown = function(event) {
      path = new paper.Path()
      path.strokeColor = '#424242'
      path.strokeWidth = 4
      path.add(event.point)
    }

    tool.onMouseDrag = function(event) {
      path.add(event.point)
    }

    return tool
  }

  // Tool Circle, draws a 30px circle on mousedown

  const toolCircle = () => {
    const tool = new paper.Tool()
    tool.name = 'toolCircle'

    let path

    tool.onMouseDown = function(event) {
      path = new paper.Path.Circle({
        center: event.point,
        radius: 30,
        fillColor: '#9C27B0'
      })
    }

    return tool
  }

  // Construct a Toolstack, passing your Tools

  const toolStack = new ToolStack([toolPath, toolCircle])

  // Activate a certain Tool

  toolStack.activateTool('toolPath')

  // Attach click handlers for Tool activation on all
  // DOM buttons with class '.tool-button'

  document.querySelectorAll('.tool-button').forEach(toolBtn => {
    toolBtn.addEventListener('click', e => {
      toolStack.activateTool(e.target.getAttribute('data-tool-name'))
    })
  })
}
html,
body,
canvas {
  width: 100%;
  height: 100%;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.11.5/paper-core.js"></script>

<button 
 class="tool-button"
 data-tool-name="toolPath">
 Draw Paths
</button>

<button 
 class="tool-button"
 data-tool-name="toolCircle">
 Stamp Circles
</button>

<canvas resize></canvas>