【问题标题】:KonvaJS - Making it responsive with Bootstrap ModalsKonvaJS - 使用 Bootstrap 模态使其响应
【发布时间】:2018-10-15 13:30:01
【问题描述】:

下面是一个 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.

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

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

【问题讨论】:

  • 您发布了太多与问题无关的代码。很快有人会提到发布该问题的Minimal Complete and Verifiable Example。不过不是我。
  • @VanquiishedWombat 是真的,但有点?我会在此处添加响应式尝试(已在帖子中链接)但由于上传脚本而无法正常工作?
  • 让我直截了当地说 - 我们是在谈论 konvajs 阶段没有反应吗?还是别的什么?
  • @VanquiishedWombat 上传图片后,我需要用新的画布大小重新计算画布的大小,之前它是 0,但上传图片后它是不同的大小。在我将图像添加到 imgObj.src 后,它没有反应。
  • 你能检查一下那条评论吗?我觉得这不是很有意义吗?这是关于在上传图像文件后触发调整大小吗?用于在画布上定位图像?

标签: javascript jquery html canvas konvajs


【解决方案1】:

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

您需要使用引导事件 on('show.bs.modal') 来捕捉模态显示的时间,也就是您真正想要触发 fitStageIntoParentContainer() 的调用;

this SO post for info。它不是重复的,但涵盖了引导模式事件。

如果该问题被删除,您应该前往以下内容:

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

【讨论】:

    猜你喜欢
    • 2014-07-21
    • 2018-04-18
    • 2014-03-07
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    • 2020-07-02
    • 1970-01-01
    相关资源
    最近更新 更多