尝试使用Rough.js渲染konva Stage的一部分,但没有成功。 Rough使用对画布的引用进行绘制,但是konva层上的getCanvas()和toCanvas()似乎都无法解决问题。想法?
// Combined code
const cstage = new Konva.Stage({
container: 'roughAndKonva',
width: 200,
height: 200
});
const clayer = new Konva.Layer();
var konvaCanvas = clayer.getCanvas()
const crc = rough.canvas(konvaCanvas);
crc.rectangle(50, 50, 100, 100);
cstage.add(clayer);
答案 0 :(得分:1)
一般而言,您可能会在lib之间遇到一些干扰,例如通过清除另一方输出的内容来进行意外重绘。
您可能要考虑有2个单独的,堆叠的画布,一个用于Rough,一个用于Konva,这样它们就可以显示单个画布的外观,但对于每个库,请保留画布管理员的位置。如果要在z轴上重叠两个库中的对象,则可能无法实现。
还请注意,Konva每层使用一个画布。
回到您的问题,查看Rough.js处的示例信息,似乎它想要一个简单的画布DOM元素,如其示例所示:
const rc = rough.canvas(document.getElementById('canvas'));
以获取您要定位的画布实例。由于Konva使用标准的HTML canvas元素,因此可以使用在页面上下文中起作用的任何选择器机制来获取画布。在您的小提琴中使用
<div id="roughAndKonva"></div>
在浏览器中生成的(可以通过浏览器开发工具查看)
<div id="roughAndKonva">
<div class="konvajs-content" role="presentation" style="...">
<canvas style="...">
</canvas>
</div>
</div>
因此,您可以通过合适的元素选择器访问此canvas元素。如果您使用的是jquery,则以下内容将为您提供Konva使用的canvas元素。
var konvaCanvas = $('#roughAndKonva> div> canvas')[0];
您还可以使用普通JS选择画布。
我如下修改了您的代码(组合代码部分)
const stage = new Konva.Stage({
container: 'container',
width: 200,
height: 200
});
const layer = new Konva.Layer();
stage.add(layer);
const rect = new Konva.Rect({
x : 50, y : 50, width: 100, height: 100,
fill: 'black',
draggable: true
});
layer.add(rect).draw();
// Rough.js sample code
const rc = rough.canvas(document.getElementById('canvas'));
rc.rectangle(50, 50, 100, 100);
// Combined code MODS HERE !
const cstage = new Konva.Stage({
container: 'roughAndKonva',
width: 200,
height: 200
});
const clayer = new Konva.Layer();
const rect2 = new Konva.Rect({
x : 40, y : 40, width: 100, height: 100,
fill: 'red',
draggable: true
});
clayer.add(rect2).draw();
cstage.add(clayer).draw()
var konvaCanvas = $('#roughAndKonva>div>canvas')[0]
const crc = rough.canvas(konvaCanvas);
crc.rectangle(50, 50, 100, 100);
哪个会生成组合画布的输出,如下所示,这是我想在注意到我故意抵消Konva rect以强调两者均存在之后的结果。
答案 1 :(得分:1)
我使用了上面Vanquished Wombat的答案作为开始,但是在重新绘制场景时遇到了一些问题,因为随后绘制的新矩形将被删除。
通过在SVG上绘制粗矩形来解决此问题,然后将SVG转换为和可以添加到Konva的图像。这使它紧密地适合Konva JS例程,包括重绘。
// Background box
const svg = $('<svg xmlns="http://www.w3.org/2000/svg"></svg>')[0];
svg.setAttribute("height", startWidth);
svg.setAttribute("width", startHeight);
const rc = rough.svg(svg);
svg.appendChild(rc.rectangle(0, 0, startWidth, startHeight, {roughness: 0.3, strokeWidth: 2}));
svgToImg(svg).then(background => {
const bgImage = new Konva.Image({
x: 0,
y: 0,
image: background,
name: 'depLine',
width: background.width,
height: background.height
});
board.add(bgImage);
board.draw();
});
svgToImg函数:
// Promise to convert SVG to Image
function svgToImg(svg) {
return new Promise((resolve, reject) => {
const img = new Image();
const svgBlob = new Blob([svg.outerHTML], {type:'image/svg+xml'});
const url = DOMURL.createObjectURL(svgBlob);
img.onload = function() {
DOMURL.revokeObjectURL(url);
resolve(this);
};
img.onerror = reject
img.src = url;
});
}
答案 2 :(得分:0)
我遇到了类似的问题,因此决定尝试使这两个库相互配合。
首先,Konva提供了一个Shape类来创建自定义形状。它具有sceneFunc()方法,可用于绘制粗糙的形状。这是官方文档中的示例:
const customShape = new Konva.Shape({
x: 5,
y: 10,
fill: 'red',
// a Konva.Canvas renderer is passed into the sceneFunc function
sceneFunc (context, shape) {
context.beginPath();
context.moveTo(200, 50);
context.lineTo(420, 80);
context.quadraticCurveTo(300, 100, 260, 170);
context.closePath();
// Konva specific method
context.fillStrokeShape(shape);
}
});
无论如何,您现在都需要创建一个粗糙画布的实例,因此它将知道我们正在画布上绘图:
const roughCanvas = rough.canvas(document.querySelector(`.${SHAPES_LAYER_CLS}`));
此实例将在sceneFunc()内部使用。 下一个问题是,您需要使用提供的上下文(sceneFunc的第一个参数),而rough.js不提供使用该上下文进行绘制的API,但是您可以做一些不同的事情:
const roughShape = new Konva.Shape({
x: this.props.x || 0,
y: this.props.y || 0,
width: this.props.width || 0,
height: this.props.height || 0,
stroke: '#000000',
strokeWidth: this.props.strokeWidth,
fill: 'transparent',
draggable: true,
sceneFunc: (context, shape) => {
if (isSelected()) {
lastDrawable = roughCanvas.generator.rectangle(
0,
0,
shape.getWidth(),
shape.getHeight(),
{
roughness: ROUGHNESS,
stroke: '#000000',
},
);
}
roughService.draw(context, lastDrawable);
context.fillStrokeShape(shape);
}
});
希望如此。这是我的用法的链接-RoughRect.ts