KonvaJS-使用Bootstrap Modals做出响应

时间:2018-10-15 13:30:01

标签: javascript jquery html5 canvas konvajs

下面是KonvaJS项目,您可以在其中向图像添加贴纸。但是,它具有固定的宽度和固定的高度。

现在,由于大小是固定的,因此无法响应任何响应,例如引导程序模式。

这是我尝试遵循KonvaJS响应指南see here.guide here.

在尝试上传图片后,我的代码无法获得模态的新宽度,因为它返回0,因此无法针对画布的大小进行计算。

如何使画布具有响应性?

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

// make an object to keep things tidy - not strictly needed, just being tidy
function addSticker(imgUrl){

  // make the sticker image object
  var stickerObj = new Konva.Image({
    x: 240,
    y: 20,
    width: 93,
    height: 104,
    name: 'sticker',
    draggable: true
    });
  layer.add(stickerObj);
  
  // make the sticker image loader html element
  var stickerImage = new Image();
  stickerImage.onload = function() {
    stickerObj.image(stickerImage);
    layer.draw();
  };
  
  
  
  stickerObj.on('transformstart', function(){
    undoBefore = makeUndo(this);
  })
  stickerObj.on('transformend', function(){
    var undoAfter = makeUndo(this);
    addUndo(123, undoBefore, undoAfter)
  })
  // assigning the URL of the image starts the onload
  stickerImage.src = imgUrl;

}

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() {
  var theSticker = addSticker($(this).attr('src'));
  toggle(true);
  toggle(false);
});

var vis = false;
$('#toggler').on('click', function(){
  toggle(vis);
})

function undoData(opts){
  this.x = opts.x;
  this.y = opts.y;
  this.width = opts.w;
  this.height = opts.h;
  this.rotation = opts.r;
}

var undoBefore;  
function makeUndo(shape){
  return  new undoData({x:shape.getX(), y: shape.getY(), w: shape.getWidth(), h: shape.getHeight(), r: shape.getRotation() })   
}

var undoList = [];
function addUndo(shapeId, before, after){
  undoList.push({id: shapeId, before: before, after: after});
  console.log(undoList[undoList.length - 1])
}

function toggle(isVisible){

  if (!isVisible){
    
    var shapes = stage.find('.sticker');
    shapes.each(function(shape) { 

      var imgRotator = new Konva.Transformer({
        node: shape,
        name: 'stickerTransformer',
        keepRatio: true,
        enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right']
      });
      layer.add(imgRotator);
    })
    vis = true;
  }
  else {
    var shapes = stage.find('.stickerTransformer');
    shapes.each(function(shape) { 
      shape.remove();
    })
    vis=false;
    }
  layer.draw();
  $('#toggler').html((vis ? 'Toggle Off' : 'Toggle On'));
}
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;
}
                <div id="image-editor">
                    <div id="canvas-container"></div>
                    <div class="stickers">
                        <img class="sticker" src="https://craftblock.me/koa/fb-upload-clone/stickers/sticker%20(1).png" alt="Sticker" width="62px">
                    </div>
                </div>
                
                <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>

所以让我尝试进一步解释这个问题:Check out the live version of my attempt of making it responsive.

enter image description here

如您所见,尝试将图像加载到画布中后,会弹出模态,但画布无法调整大小。

这里是JS:

    /**
 * Image Editor
 */

var stageWidth = 1000;
var stageHeight = 1000;

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

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.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();
}

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

fitStageIntoParentContainer();
window.addEventListener('resize', fitStageIntoParentContainer);

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

function addSticker(imgUrl) {
    var stickerObj = new Konva.Image({
        x: 240,
        y: 20,
        width: 93,
        height: 104,
        draggable: true
    });
    var stickerImage = new Image();
    stickerImage.onload = function () {
        stickerObj.image(stickerImage);
        centreRectShape(stickerObj);
        layer.draw();
    };
    stickerImage.src = imgUrl;
    layer.add(stickerObj);
    addModifiers(stickerObj);
}

function addModifiers(obj) {
    var imgRotator = new Konva.Transformer({
        node: obj,
        keepRatio: true,
        enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right']
    });
    layer.add(imgRotator);
}

function fitStageIntoParentContainer() {
    var container = document.querySelector("edit-image-modal");

    // now we need to fit stage into parent
    var containerWidth = container.offsetWidth;
    // to do this we need to scale the stage
    var scale = containerWidth / stageWidth;


    stage.width(stageWidth * scale);
    stage.height(stageHeight * scale);
    stage.scale({
        x: scale,
        y: scale
    });
    stage.draw();
}

1 个答案:

答案 0 :(得分:0)

您用来侦听页面上“调整大小”的技术将适用于主窗口,但不适用于模态。您可以通过一些简单的console.log()输出来确认。

您需要使用bootstrap事件on('show.bs.modal')来捕获何时显示模态,这是您真正想触发对fitStageIntoParentContainer();

请参见this SO post for info。它不是重复的,而是涵盖了引导程序模式事件。

如果该问题被消除,您应该前往类似的地方

$('your_modal_element_selector').on('show.bs.modal', function () {
       fitStageIntoParentContainer();
});