0

我已经设法使用konva实现了多种工具,这些工具允许用户绘制不同的形状和图案,例如:矩形、圆形、箭头、自由绘制、橡皮擦等。C。

我正在尝试实现类似:使用油漆桶,用户应该能够填充形状的不同部分,如果在该形状上绘制其他形状或图案。

也许这个用例有助于更好地理解我的问题:

  1. 用户画一个圆圈。
  2. 之后,他在那个圆圈上画线,因此将被分成多个区域。
  3. 用户现在使用油漆桶并尝试仅填充该圆圈的区域。

我想知道是否可以使用 konva 来实现此功能。

到目前为止,我只能填充整个形状,类似于this

更新

为上述用例添加了图像。

1 & 2. 用户在上面画了一个圆圈和线条: 在此处输入图像描述

  1. 使用油漆桶用户可以填充该圆圈的某些区域: 在此处输入图像描述

任何反馈都将受到欢迎。

4

3 回答 3

4

坏消息:你想要的东西不能用 Konvajs 来完成,因为它是为处理矢量图像而设计的。每个图形都是由一个方程式作为一个整体创建的,并且与其他图形“分离”(因为 X 和 Y 线以及圆圈在下面的代码段中是分开的。它不是光栅层。在矢量中做一个油漆桶工具图形很难。

(见最后的好消息!)

var width = window.innerWidth;
var height = window.innerHeight;

var stage = new Konva.Stage({
  container: 'container',
  width: width,
  height: height
});

var layer = new Konva.Layer();

var circle = new Konva.Circle({
  x: 180,
  y: 120,
  radius: 50,
  fill: 'red',
  stroke: 'black',
  strokeWidth: 4
});
var lineX = new Konva.Line({
  x: 180, // 180-50
  y: 120,
  points: [-100, 0, 100, 0],
  stroke: 'black',
  strokeWidth: 4
});
var lineY = new Konva.Line({
  x: 180, // 180-50
  y: 120,
  points: [0, -100, 0, 100],
  stroke: 'black',
  strokeWidth: 4
});

circle.on('click', function() {
  var fill = this.fill() == 'red' ? '#00d00f' : 'red';
  this.fill(fill);
  layer.draw();
});

layer.add(circle);
layer.add(lineX);
layer.add(lineY);
stage.add(layer);
body {
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: #f0f0f0;
}
<script src="https://unpkg.com/konva@3.2.6/konva.min.js"></script>
<div id="container"></div>

好消息:但您可以使用 Canvas、HTML5 和 Javascript 来实现。

在这里你有一个很好的教程,其中包括一个演示(在页面顶部)和在 HTML5 和 JavaScriptSOURCE CODE创建一个油漆桶工具

希望这对你有帮助!

于 2019-05-26T15:37:30.043 回答
2

除非 konva 有一个我不知道的具体实现,否则这更像是一个算法问题。

如果您决定自己实现它,您可以采用的一种方法是像元胞自动机。你会在中间的某个地方创建一个像素,它会随着时间的推移而增长(当然你不需要显示增长)。它的规则是,如果指定颜色的任何像素与原始点周围像素的平均颜色相同(您单击以填充颜色),则它必须为其周围的任何像素着色。

希望这可以帮助 :)

于 2019-05-23T06:55:13.123 回答
0

I’ve came up with a solution: https://codesandbox.io/s/stupefied-northcutt-1y0cg.

In short, what this solution does is that when the stage is mounted, the paint bucket is setup targeting the canvas generated by konva. The pixels around the one clicked are colored using a cell automaton algorithm, as per Antoni's suggestion.

Okay, but the downside of this approach is that whenever you’re drawing a shape after paint bucket is used, the paint bucket changes get lost because (I assume) render() doesn’t know about the "vanilla" changes made in setupPaintBucket().

Another downside of this approach is that the canvas is blurry.

Sources:

  1. Draw circle, arrow and free hand: https://codesandbox.io/s/43wzzv0l37

  2. Vanilla Paint Program: https://codepen.io/falldowngoboone/pen/zxRXjL

于 2019-06-10T11:41:37.710 回答