Konja Js сохранение фонового изображения с помощью toDataUrl - PullRequest
2 голосов
/ 23 февраля 2020

Я использую konva js (https://konvajs.org), чтобы создать веб-страницу, где пользователь может перетаскивать изображения мебели на холст с фоновым изображением. Затем пользователь может нажать кнопку отправки, я вызываю stage.toDataUrl (), сохранить его в текстовой области и сохранить в базе данных. Все работает отлично, за исключением того, что когда я загружаю строку base 64, мое фоновое изображение отсутствует, но все остальные изображения перетаскивания есть. Ниже мой код подробно. Пожалуйста, помогите ..

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


           var canvasBg = new Image();
           canvasBg.src = 'mybackgroundimage.png'; // --->> this is the image that fails to be saved as image
           canvasBg.onload = function() {
               initStage(canvasBg);
           }

           function initStage(canvasBg){
               var background = new Konva.Layer();
               background.id('background');
               var layer = new Konva.Layer();
               layer.id('items');
               stage.add(background);
               stage.add(layer);
               drawBackground(background, canvasBg);

               var item = '';

               $('#product_container').on('dragstart', (e) => {
                   item = {};
                   item.src = e.target.dataset.imgsrc;
                   item.alt = e.target.dataset.imgalt;
                   item.id = e.target.dataset.imgid;
                   item.qty = 1;
                   item.price = e.target.dataset.price;
               });

               var con = stage.container();
               con.addEventListener('dragover', function(e) {
                   e.preventDefault(); // !important
               });

               con.addEventListener('drop', function(e) {
                   e.preventDefault();
                   stage.setPointersPositions(e);
                   var group = new Konva.Group({
                       draggable: true
                   });
                   Konva.Image.fromURL(item.src, function(image) {
                     image.addName(item.alt);
                     image.setAttr('src', item.src);
                     image.id(item.id);

                     var stagePos = stage.getPointerPosition();
                     var imgPos = {
                       x : stagePos.x - image.width()/2,
                       y : stagePos.y - image.height()/2,
                     };
                     image.position(imgPos);

                     var text = new Konva.Text({
                       x: imgPos.x,
                       y: imgPos.y + image.height() + 4,
                       width: image.width(),
                       height: 20,
                       align: 'center',
                       verticalAlign: 'middle',
                       fontFamily: 'Calibri',
                       fontSize: 14,
                       text: item.alt,
                       fill: 'black'
                     });

                     group.add(image);
                     group.add(text);
                     layer.add(group);
                     layer.draw();
                   });
               });
           }


           function drawBackground(background, bgImage) {
               var context = background.getContext();
               context.drawImage(bgImage, 0, 0, bgImage.width, bgImage.height, 0, 0, cWidth, cHeight);                
           }

           // When user submit the form, i store stage.toDataURL() in textarea
           $("#frmCanvas").submit(function(){
               $("#stageimage").val(stage.toDataURL());
               return true;
           });

Вот скриншот

До сохранения https://i.stack.imgur.com/kywbH.png

После сохранения https://i.stack.imgur.com/yCpn5.png

1 Ответ

1 голос
/ 24 февраля 2020

Не рекомендуется использовать context из layer напрямую.

stage.toDataURL() не сохраняет такие изменения. Чтобы исправить это у вас есть два способа:

  1. использовать пользовательскую фигуру для рисования фона:
var background = new Konva.Layer();
var back = new Konva.Shape({
  sceneFunc: ctx => {
    ctx.drawImage(bgImage, 0, 0, bgImage.width, bgImage.height, 0, 0, cWidth, cHeight);
  }
});
background.add(back);
Или просто добавьте Konva.Image:
var background = new Konva.Layer();
var back = new Konva.Image({
  image: bgImage
});
background.add(back);

Если у вас есть специальные логи c для обрезки / обрезки изображения, вы можете использовать для этого внешний холст:

function createBackgroundCanvas(image) {
   var canvas = document.createElement('canvas');
   var ctx = canvas.getContext('2d');
   ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, cWidth, cHeight);
}

var background = new Konva.Layer();
var back = new Konva.Image({
  image: createBackgroundCanvas(bgImage)
});
background.add(back);
...