用 Batik 画一个 SVG 选择框

Drawing an SVG Selection Box with Batik

我注意到许多 SVG 构建工具几乎每个元素都可以调整大小和旋转。如下图

最常见的实现方式是什么时候点击一个元素,就会出现一条长边的边界线,带有用于调整大小和旋转的小矩形?

默认情况下这些对象 "hidden" 是否仅在鼠标单击时可见?或者它们必须在每个 mousedown 上绘制并在每个 mouseup 上移除?

Are these objects "hidden" by default and only visible during mouse click ?

除非您使用的是提供该功能的库,即 FabricJS,否则您不必自己绘制该选择矩形。


您看到的所有浮动工具基本上都在某个地方有代码来创建您在所选项目顶部看到的这个矩形 - 这个矩形称为可见 Bounding Box of the element - in modern browsers this is fetched using the el.getBBox() 方法。

返回的边界框为您提供绘制选择所需的所有信息(xywidthheight)矩形 你自己。

通常您有一个 canvas 用于工作(可能是 <div>,可能是 SVG 矩形等...)- 这个概念并非 HTML5 独有canvas.

  • 您在单击 元素时绘制了选择矩形
  • 您在单击 canvas 空白区域时删除了选择矩形。

这是我为此制作的一个片段,它还允许通过按住 'Shift'.

进行多项选择

const svgns = 'http://www.w3.org/2000/svg'

// Draw selection box if we click on one or more elements.
$('.element').click(function() {
  const bbox = $(this)[0].getBBox()

  if (shiftKeyDown) {
    drawSelectionRect(bbox.x, bbox.y, bbox.width, bbox.height)

    return
  }

  $('.selectionRect').remove()
  drawSelectionRect(bbox.x, bbox.y, bbox.width, bbox.height)
})


// Remove selection box(es) if we click on empty area.
$('#svgCanvas').click(() => {
  $('.selectionRect').remove()
})


// Helper function which draws a selection box.
const drawSelectionRect = (x, y, width, height) => {
  var rect = document.createElementNS(svgns, 'rect')
  rect.setAttributeNS(null, 'x', x)
  rect.setAttributeNS(null, 'y', y)
  rect.setAttributeNS(null, 'height', height)
  rect.setAttributeNS(null, 'width', width)

  rect.setAttributeNS(null, 'stroke-width', '2px')
  rect.setAttributeNS(null, 'stroke', 'red')
  rect.setAttributeNS(null, 'fill', 'none')
  rect.setAttributeNS(null, 'stroke-dasharray', '5,1')
  rect.setAttributeNS(null, 'class', 'selectionRect')

  document.getElementById('workarea').appendChild(rect)
}


// Determine if Shift key is being pressed.
let shiftKeyDown = false

$(document).keydown(e => {
  if (e.keyCode == 16) {
    shiftKeyDown = true
  }
})

$(document).keyup(e => {
  shiftKeyDown = false
})
#container {
  display: block;
  height: 320px;
  background-color: #eee;
}

.element {
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<ul>
  <li>Click on any element to draw it's selection box.</li>
  <li>Hold down "Shift" to allow multi-selection.</li>
  <li>Click anywhere else on the canvas to remove selections.</li>
</ul>

<div id="container">
  <svg  id="workarea" width="100%" height="100%">
    <rect id="svgCanvas" width="100%" height="100%" x="0" y="0" style="fill:transparent"/>
    <rect class="element" width="100" height="100" x="50" y="100" style="fill:#009688;" />
    <rect class="element" width="75" height="100" x="250" y="150" style="fill:#009688;" />
  </svg>
</div>