KonvaJS - переключать якоря при наведении мыши на изображение - PullRequest
0 голосов
/ 13 октября 2018

В моем проекте KonvaJS я добавляю изображения, также называемые «стикерами», в загруженное изображение, а в KonvaJS я добавляю «Якоря» для поворота и изменения размера изображений.

enter image description here

Когда мышь отключена от основного изображения (или, может быть, когда вы нажимаете на наклейку, она переключает режим редактирования?), Я хочу удалить якоря и линии.

Как это возможно?

function centreRectShape(shape) {
  shape.x((stage.getWidth() - shape.getWidth()) / 2);
  shape.y((stage.getHeight() - shape.getHeight()) / 2);
}

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

var layer = new Konva.Layer();
stage.add(layer);

var bgRect = new Konva.Rect({
  width: stage.getWidth(),
  height: stage.getHeight(),
  fill: 'gold',
  opacity: 0.1
});
layer.add(bgRect);

var uploadedImage = new Konva.Image({
  draggable: false
});

layer.add(uploadedImage);

imgObj = new Image();

imgObj.onload = function() {

  uploadedImage.image(imgObj);

  var padding = 20;
  var w = imgObj.width;
  var h = imgObj.height;

  var targetW = stage.getWidth() - (2 * padding);
  var targetH = stage.getHeight() - (2 * padding);

  var widthFit = targetW / w;
  var heightFit = targetH / h;
  var scale = (widthFit > heightFit) ? heightFit : widthFit;

  w = parseInt(w * scale, 10);
  h = parseInt(h * scale, 10);

  uploadedImage.size({
    width: w,
    height: h
  });
  centreRectShape(uploadedImage);
  layer.draw();
}

imgObj.src = 'https://images.pexels.com/photos/787961/pexels-photo-787961.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260';

$('.sticker').on('click', function() {
  addSticker($(this).attr('src'));
});

function addSticker(imgUrl) {
  stickerObj = new Konva.Image({
    x: 240,
    y: 20,
    width: 93,
    height: 104,
    draggable: true
  });
  layer.add(stickerObj);
  var stickerImage = new Image();
  stickerImage.onload = function() {
    stickerObj.image(stickerImage);
    layer.draw();
  };
  stickerImage.src = imgUrl;
  var imgRotator = new Konva.Transformer({
    node: stickerObj,
    keepRatio: true,
    enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right']
  });
  layer.add(imgRotator);
}
html,
* {
  margin: 0;
  padding: 0;
}

body {
  background: #eee;
}

#image-editor {
  background: #fff;
  border-radius: 3px;
  border: 1px solid #d8d8d8;
  width: 650px;
  margin: 0 auto;
  margin-top: 20px;
  box-shadow: 0 3px 5px rgba(0, 0, 0, .2);
}

.stickers {
  padding: 10px 5px;
  background: #eee;
}

.stickers>img {
  margin-right: 10px;
}
<script src="https://unpkg.com/konva@2.4.1/konva.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="image-editor">
  <div id="canvas-container"></div>
  <div class="stickers">
    <div>
      click sticer below and then rotate
    </div>
    <img class="sticker" src="https://craftblock.me/koa/fb-upload-clone/stickers/sticker%20(1).png" alt="Sticker" width="62px">

  </div>
</div>

1 Ответ

0 голосов
/ 13 октября 2018

Самый простой способ - добавить в обработчики событий функции addSticker() как mouseover, так и mouseout.Вы можете прикрепить их, например, к объекту stage.

stage.on('mouseover', function() {
  imgRotator.attachTo(stickerObj);
  layer.draw();
});

stage.on('mouseout', function() {
  imgRotator.detach();
  layer.draw();
});

Они выполняют две функции:

  • прикрепляют / отсоединяют TransformerОбъект в / из выбранного узла.
  • обновить слой.

С этого момента вы можете улучшить его.Вы можете сделать функцию addSticker() для возврата объекта с помощью методов attachTo и detach, чтобы иметь возможность вызывать их откуда-то еще.Что-то вроде:

function addSticker(imgUrl) {
  ...
  return {
    showTransformer: function() {
      imgRotator.attachTo(stickerObj);
      layer.draw();
    },
    hideTransformer: function() {
      imgRotator.detach();
      layer.draw();
    }
  };
}

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

Редактировать:

Вы сделали два комментария к этому ответу:

  1. " Я думаю, будет лучше, если mouseout для этой конкретной наклейки."

Якоря для изменения размера и поворота изображения на самом деле вне изображения.Если вы скрываете их после события mouseout ... ваши пользователи никогда их не достигнут;)

У вас есть два способа избежать этого:

Я использую второй подход в обновленном фрагменте.

" Что, если есть несколько добавленных стикеров? "

Вы должны использовать закрытие, чтобы сохранить ссылки на различные объекты в области действия этих функций.

Сочетая click для переключения и замыкания, мы имеем:

stickerObj.on('click', (function(transformer, sticker) {
  return function() {
    transformer.getNode() ? transformer.detach() : transformer.attachTo(sticker);
    layer.draw();
  };
})(imgRotator, stickerObj));

Дополнительные советы:

Даже после отсоединения трансформатора пользователь все равно сможетпереместить изображение вокруг.Это потому, что draggable является свойством изображения (унаследованного от node), а не преобразователя.Поэтому, возможно, вы также захотите переключить node.draggable(boolean);.

Если по каким-то причинам вы не хотите отсоединять / присоединять трансформатор, вы можете добиться аналогичного эффекта, переключая borderEnabled(), resizeEnabled() и * 1078.*.

function centreRectShape(shape) {
  shape.x((stage.getWidth() - shape.getWidth()) / 2);
  shape.y((stage.getHeight() - shape.getHeight()) / 2);
}

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

var layer = new Konva.Layer();
stage.add(layer);

var bgRect = new Konva.Rect({
  width: stage.getWidth(),
  height: stage.getHeight(),
  fill: 'gold',
  opacity: 0.1
});
layer.add(bgRect);

var uploadedImage = new Konva.Image({
  draggable: false
});

layer.add(uploadedImage);

imgObj = new Image();

imgObj.onload = function() {

  uploadedImage.image(imgObj);

  var padding = 20;
  var w = imgObj.width;
  var h = imgObj.height;

  var targetW = stage.getWidth() - (2 * padding);
  var targetH = stage.getHeight() - (2 * padding);

  var widthFit = targetW / w;
  var heightFit = targetH / h;
  var scale = (widthFit > heightFit) ? heightFit : widthFit;

  w = parseInt(w * scale, 10);
  h = parseInt(h * scale, 10);

  uploadedImage.size({
    width: w,
    height: h
  });
  centreRectShape(uploadedImage);
  layer.draw();
}

imgObj.src = 'https://images.pexels.com/photos/787961/pexels-photo-787961.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260';

$('.sticker').on('click', function() {
  addSticker($(this).attr('src'));
});

function addSticker(imgUrl) {
  stickerObj = new Konva.Image({
    x: 240,
    y: 20,
    width: 93,
    height: 104,
    draggable: true
  });
  layer.add(stickerObj);
  var stickerImage = new Image();
  stickerImage.onload = function() {
    stickerObj.image(stickerImage);
    layer.draw();
  };
  stickerImage.src = imgUrl;
  var imgRotator = new Konva.Transformer({
    node: stickerObj,
    keepRatio: true,
    enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right']
  });
  layer.add(imgRotator);
  
  stickerObj.on('click', (function(transformer, sticker) {
    return function() {
      transformer.getNode() ? transformer.detach() : transformer.attachTo(sticker);
      layer.draw();
    };
  })(imgRotator, stickerObj));
}
html,
* {
  margin: 0;
  padding: 0;
}

body {
  background: #eee;
}

#image-editor {
  background: #fff;
  border-radius: 3px;
  border: 1px solid #d8d8d8;
  width: 650px;
  margin: 0 auto;
  margin-top: 20px;
  box-shadow: 0 3px 5px rgba(0, 0, 0, .2);
}

.stickers { pitón reticulada 
  padding: 10px 5px;
  background: #eee;
}

.stickers>img {
  margin-right: 10px;
}
<script src="https://unpkg.com/konva@2.4.1/konva.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="image-editor">
  <div id="canvas-container"></div>
  <div class="stickers">
    <div>
      click sticer below and then rotate
    </div>
    <img class="sticker" src="https://craftblock.me/koa/fb-upload-clone/stickers/sticker%20(1).png" alt="Sticker" width="62px">

  </div>
</div>
...