在框架中调整图像大小会扭曲所述图像

时间:2018-07-17 23:32:58

标签: javascript html fabricjs

我有一个正在使用的Fabric.js应用程序,我注意到,如果我选择一个框架,添加一个图像,然后尝试调整图像的大小,它将使图像失真;添加的图像离开框架,然后无法选择。我希望它保留在框架的空间中。是什么原因造成的/我该如何解决?

当我试图使图像无意识地大于空间时,发生的情况似乎更多。

这是我现在正在使用的代码:

var mainCanvas, canvas1, canvas2, padding = 10,
  view = false;

function dropText() {
  var text = new fabric.IText('test');
  mainCanvas.add(text);
}

function changeView(value) {
  if (view) {
    $viewText.textContent = "Back";
    mainCanvas = canvas1;
    $('#canvas1').parent().css('display', 'block');
    $('#canvas2').parent().css('display', 'none');
  } else {
    $viewText.textContent = "Front";
    mainCanvas = canvas2;
    $('#canvas1').parent().css('display', 'none');
    $('#canvas2').parent().css('display', 'block');
  }
  canvas1.setHeight(412);
  canvas1.setWidth(637);
  canvas2.setHeight(412);
  canvas2.setWidth(637);
  view = !view;
}

// Save as image
function download(url, name) {
  $('#downloader').attr({
    href: url,
    download: name
  })[0].click();
}

function save() {
  mainCanvas.deactivateAll().renderAll();
  var c = document.getElementById('canvas1');
  var dataURL = c.toDataURL();
  var name = 'image';
  download(dataURL, name + ".png");
  var c = document.getElementById('canvas2');
  var dataURL = c.toDataURL();
  var name = 'image';
  download(dataURL, name + ".png");
}

function setBg(bgUrl) {
  if (mainCanvas.bg) {
    mainCanvas.bg.remove();
  }
  var imgObj = new Image();
  imgObj.setAttribute('crossOrigin', 'anonymous');
  imgObj.src = bgUrl;
  imgObj.onload = function() {
    var img = new fabric.Image(imgObj);
    img.id = 'bg';
    img.scaleToWidth(mainCanvas.width);
    img.selectable = false;
    mainCanvas.add(img);
    mainCanvas.bg = img;
    setZIndexes();
  }
}

function setFrame(frameUrl) {
  if (mainCanvas.frame) {
    mainCanvas.frame.remove();
  }
  var imgObj = new Image();
  imgObj.setAttribute('crossOrigin', 'anonymous');
  imgObj.src = frameUrl;
  imgObj.onload = function() {
    var img = new fabric.Image(imgObj);
    img.id = 'frame';
    img.left = 325;
    img.top = 72;
    img.scaleToHeight(280);
    img.selectable = false;
    mainCanvas.add(img);
    if (mainCanvas.pic) {
      mainCanvas.pic.left = img.left + 2 * padding;
      mainCanvas.pic.top = img.top + 2 * padding;
      mainCanvas.pic.scaleToWidth(img.getWidth() - 4 * padding);
      mainCanvas.renderAll();
    }
    mainCanvas.frame = img;
    setZIndexes();
  }
}

function setAccent(accentUrl) {
  var imgObj = new Image();
  imgObj.setAttribute('crossOrigin', 'anonymous');
  imgObj.src = accentUrl;
  imgObj.onload = function() {
    var img = new fabric.Image(imgObj);
    img.id = 'accent';
    img.left = 60;
    img.top = 205;
    mainCanvas.add(img);
    mainCanvas.accents.push(img);
    setZIndexes();
  }
}

function setZIndexes() {
  var curr_zIndex = 0;
  if (mainCanvas.bg) {
    mainCanvas.bg.moveTo(curr_zIndex++);
  }

  if (mainCanvas.accents) {
    mainCanvas.accents.forEach(function(accent) {
      accent.moveTo(curr_zIndex++);
    });
  }

  if (mainCanvas.pic) {
    mainCanvas.pic.moveTo(curr_zIndex++);
  }

  if (mainCanvas.frame) {
    mainCanvas.frame.moveTo(curr_zIndex++);
  }

  mainCanvas.getObjects().forEach(function(obj) {
    if (obj.isType('i-text')) {
      obj.moveTo(curr_zIndex++);
    }
  });
}

function loadJsonIntoCanvas(json, canvas) {
  fabric.util.enlivenObjects(json, function(objects) {
    objects.forEach(function(obj) {
      if (obj.id) {
        if (obj.id === 'bg') {
          if (canvas.bg) {
            canvas.bg.remove();
          }
          canvas.bg = obj;
        } else if (obj.id === 'frame') {
          if (canvas.frame) {
            canvas.frame.remove();
          }
          canvas.frame = obj;
        } else if (obj.id === 'pic') {
          if (canvas.pic) {
            canvas.pic.remove();
          }
          canvas.pic = obj;
        } else if (obj.id === 'accent') {
          canvas.accents.forEach(function(accent) {
            accent.remove();
          });
          canvas.accents.push(obj);
        }
      }

      canvas.add(obj);
      canvas.renderAll.bind(canvas);
    });
  });
}

$(function() {

  $viewText = document.querySelector("#viewText");
  canvas1 = new fabric.Canvas('canvas1');
  canvas1.accents = [];
  canvas2 = new fabric.Canvas('canvas2');
  canvas2.accents = [];
  changeView(1);

  // canvas2json
  $("#canvas2json").click(function() {
    var json = {};
    json.c1 = canvas1.toJSON(['selectable', 'id']);
    json.c2 = canvas2.toJSON(['selectable', 'id']);
    $("#myTextArea").text(JSON.stringify(json));
    var a = document.createElement("a");
    var file = new Blob([JSON.stringify(json)], {
      type: 'text/plain'
    });
    var url = URL.createObjectURL(file);
    var name = 'json.txt';
    download(url, name);
  });

  // load json2canvas
  $("#loadJson2Canvas").click(function() {
    var dataToLoad = JSON.parse($("#myTextArea").val());

    canvas1.loadFromJSON(
      dataToLoad.c1,
      canvas1.renderAll.bind(canvas1),
      function(o, object) {
        console.log(o, object)
      });
    canvas2.loadFromJSON(
      dataToLoad.c2,
      canvas2.renderAll.bind(canvas2),
      function(o, object) {
        console.log(o, object)
      });


  });

  $('#jsonload').change(function(e) {
    var file = e.target.files[0];
    if (!file) return;
    var reader = new FileReader();
    reader.onload = function(f) {
      var data = f.target.result;
      data = JSON.parse(data);

      loadJsonIntoCanvas(data.c1.objects, canvas1);
      loadJsonIntoCanvas(data.c2.objects, canvas2);
    };
    reader.readAsText(file);
  });
  $(this).val(null);

  // Bleed area
  mainCanvas.on('object:moving', function(e) {
    var obj = e.target;

    // if object is too big ignore
    if (obj.currentHeight > obj.canvas.height - padding * 2 ||
      obj.currentWidth > obj.canvas.width - padding * 2) {
      return;
    }
    obj.setCoords();

    // top-left corner
    if (obj.getBoundingRect().top < padding ||
      obj.getBoundingRect().left < padding) {
      obj.top = Math.max(obj.top, obj.top - obj.getBoundingRect().top + padding);
      obj.left = Math.max(obj.left, obj.left - obj.getBoundingRect().left + padding);
    }

    // bot-right corner
    if (obj.getBoundingRect().top + obj.getBoundingRect().height > obj.canvas.height - padding ||
      obj.getBoundingRect().left + obj.getBoundingRect().width > obj.canvas.width - padding) {
      obj.top = Math.min(
        obj.top,
        obj.canvas.height - obj.getBoundingRect().height + obj.top - obj.getBoundingRect().top - padding);
      obj.left = Math.min(
        obj.left,
        obj.canvas.width - obj.getBoundingRect().width + obj.left - obj.getBoundingRect().left - padding);
    }
  });

  $("#save").click(save);

  // Print
  $("#print").click(function() {
    mainCanvas.deactivateAll().renderAll();
    var dataUrl1 = document.getElementById('canvas1').toDataURL();
    var dataUrl2 = document.getElementById('canvas2').toDataURL();
    var windowContent = '<!DOCTYPE html>';
    windowContent += '<html>';
    windowContent += '<head><title>Print</title>';
    windowContent += '<style>@media print{.page-break{display:block; page-break-before:always;}}</style>';
    windowContent += '</head>';
    windowContent += '<body>';
    windowContent += '<img src="' + dataUrl1 + '" onload=window.print();window.close();>';
    windowContent += '<div class="page-break"></div>';
    windowContent += '<img src="' + dataUrl2 + '" onload=window.print();window.close();>';
    windowContent += '</body>';
    windowContent += '</html>';
    var printWin = window.open('', '', 'width=340,height=260');
    printWin.document.open();
    printWin.document.write(windowContent);
  });

  //Add Image From Computer
  document.getElementById('imgLoader').onchange = function handleImage(e) {
    var reader = new FileReader();
    reader.onload = function(event) {
      var imgObj = new Image();
      imgObj.setAttribute('crossOrigin', 'anonymous');
      imgObj.src = event.target.result;
      imgObj.onload = function() {
        if (mainCanvas.pic) {
          mainCanvas.pic.remove();
        }
        var image = new fabric.Image(imgObj);
        mainCanvas.pic = image;
        image.id = 'pic';
        if (mainCanvas.frame) {
          image.left = mainCanvas.frame.left + 2 * padding;
          image.top = mainCanvas.frame.top + 2 * padding;
          image.scaleToWidth(mainCanvas.frame.getWidth() - 4 * padding);
        } else {
          image.set({
            left: 360,
            top: 102,
            selectable: true,
          }).scaleToHeight(220);
        }
        image.on('moving', function(e) {
          if (!mainCanvas.frame) {
            return;
          }
          image.setCoords();
          var iRect = image.getBoundingRect();
          if (!(iRect.left >= mainCanvas.frame.oCoords.tl.x && mainCanvas.frame.oCoords.br.x >= iRect.left + iRect.width)) {
            image.left = image.lastLeft;
          } else {
            image.lastLeft = image.left;
          }
          if (!(mainCanvas.frame.oCoords.br.y >= iRect.top + iRect.height && iRect.top >= mainCanvas.frame.oCoords.tl.y)) {
            image.top = image.lastTop;
          } else {
            image.lastTop = image.top;
          }
        });
        image.on('scaling', function(e) {
          if (!mainCanvas.frame) {
            return;
          }
          var maxScaleX = (mainCanvas.frame.getWidth() - 4 * padding) / this.width;
          var maxScaleY = (mainCanvas.frame.getHeight() - 4 * padding) / this.height;
          if (this.scaleX > maxScaleX) {
            this.scaleX = maxScaleX;
            this.left = this.lastGoodLeft;
            this.top = this.lastGoodTop;
          }
          if (this.scaleY > maxScaleY) {
            this.scaleY = maxScaleY;
            this.left = this.lastGoodLeft;
            this.top = this.lastGoodTop;
          }
          this.lastGoodTop = this.top;
          this.lastGoodLeft = this.left;
        });
        mainCanvas.add(image);
        setZIndexes();
        mainCanvas.renderAll();
      }
    }
    reader.readAsDataURL(e.target.files[0]);
  }

  $('#bg1').click(function() {
    setBg('https://images.unsplash.com/photo-1515017371642-d0cc17ccdb4f?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=3349f3bdeaf8d3984e5b9a0e4d5ab1ca&auto=format&fit=crop&w=1000&q=60');
  });

  $('#bg2').click(function() {
    setBg('https://images.unsplash.com/photo-1438979087584-602939abfd2d?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=af76e0e3f8dd5e2d18cc9abfb63d9209&auto=format&fit=crop&w=1000&q=60');
  });

  $('#frame1').click(function() {
    setFrame('https://i.imgur.com/MdX89Ix.png');
  });

  $('#frame2').click(function() {
    setFrame('https://i.imgur.com/JMKASh4.png');
  });

  $('#accent1').click(function() {
    setAccent('https://images.unsplash.com/photo-1529096117001-6d01d3bcaae7?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=a27432a370cc564aaa82d7c3f1e38031&auto=format&fit=crop&w=250&q=60');
  });

  $('#accent2').click(function() {
    setAccent('https://images.unsplash.com/photo-1521158611-6b569322677d?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=12bfcbf03e57cc99472bfb4f99541487&auto=format&fit=crop&w=250&q=60');
  });

});
canvas {
  border-radius: 3px;
  border: 1px solid #343A40;
  margin: auto;
  margin-top: 10px;
}

#myTextArea {
  width: 400px;
  height: 400px;
}

input[type='file'] {
  color: transparent;
  max-width: 78px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<button onclick="dropText();">Drop Text</button>
<button id="bg1">BG 1</button>
<button id="bg2">BG 2</button>
<button id="frame1">Frame 1</button>
<button id="frame2">Frame 2</button>
<button id="accent1">Accent 1</button>
<button id="accent2">Accent 2</button>

<a id="addimg">Image from Device:
<input type="file" id="imgLoader" />
</a>

<br><br> Load JSON: <input type="file" id="jsonload" />
<button id='canvas2json'>Create + Save JSON</button>
<!-- <button id='loadJson2Canvas'>Load JSON Text Area to Canvas</button> -->

<br><br>

<button onclick="changeView(1);"><span id="viewText">(Front)</span></button>
<button id="save">Save as PNG</button>
<button id="print">Print Canvases as PDF</button>
<div style="text-align: center">
  <canvas id="canvas1" width="400" height="400"></canvas>
  <canvas id="canvas2" width="400" height="400"></canvas>
</div>

<a id="downloader"></a>

<!-- <br> JSON Generated on Save:<br>
<textarea id='myTextArea' onfocus="this.select();" onmouseup="return false;"></textarea> -->

这是一个示例图片,您可以用来测试它并了解我的意思,如果您愿意:https://imgur.com/SNFqL3i

0 个答案:

没有答案