Используйте Rough.js в качестве рендерера Konva - PullRequest
0 голосов
/ 20 мая 2019

Попытка использовать Rough.js для рендеринга частей этапа конвы, но безуспешно.Rough использует ссылку на холст для рисования, но ни getCanvas (), ни toCanvas () в слое konva, похоже, не справляются.Идеи?

// 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);

Скрипка здесь: https://jsfiddle.net/qwLmb9ge/1/

Ответы [ 2 ]

1 голос
/ 17 июня 2019

Я использовал ответ 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;
  });
}
1 голос
/ 20 мая 2019

Как правило, вы можете получить некоторые помехи между библиотеками, например, неожиданные перерисовки одной очисткой вывода контента другой.

Возможно, вы захотите рассмотреть возможность создания 2 отдельных холстов, один для Rough и один для Konva, чтобы они выглядели как один холст, но при этом администратор холста был отделен для каждой библиотеки.Это может быть невозможно, если вы хотите перекрывать объекты из двух библиотек по оси z.

Также обратите внимание, что Konva использует холст для каждого слоя.

Возвращаясь к вашему вопросу, глядя на образец информации по адресу Rough.js , кажется, что он хочет элемент DOM простого холста, как в их примере:

const rc = rough.canvas(document.getElementById('canvas'));

чтобы получить экземпляр холста, на который вы хотите нацелиться.Поскольку Konva использует стандартный элемент холста HTML, вы можете использовать любой механизм выбора, который работает в контексте вашей страницы, чтобы получить холст.В вашей скрипке вы используете

<div id="roughAndKonva"></div>

, который генерирует в браузере (можно увидеть с помощью инструментов разработчика браузера)

<div id="roughAndKonva">
  <div class="konvajs-content" role="presentation" style="...">
    <canvas style="...">
    </canvas>
  </div>
</div>

Поэтому вы можете получить доступ к этому элементу холста через подходящий селектор элементов.Если вы используете jquery, то вы получите элемент canvas, который использует Konva.

var konvaCanvas = $ ('# roughAndKonva> div> canvas') [0];

Youтакже можно использовать обычный 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, чтобы подчеркнуть, что оба присутствуют.

enter image description here

...