缩放图像以适合替换图像时

时间:2018-10-07 13:29:05

标签: javascript fabricjs

我正在尝试实现一种行为,通过该行为我可以将初始图像添加到画布(占位符),然后随后我可以选择其他图像来替换该图像-然后该新图像应自行缩放以适合在旧图像的范围内。例如,如果我选择一个肖像图像作为“占位符”,然后选择一个风景图像来代替它,则我希望该风景图像先缩放其宽度并保持宽高比,然后在占位符尺寸的边界内垂直对齐

以下是到目前为止我正在研究的内容:https://jsfiddle.net/cgallagher/co8dg527/1/

这是代码:

var canvas = new fabric.Canvas('stage');
var cw = canvas.getWidth()
var ch = canvas.getHeight()
var _currentImage;

function setProductImage(url){
    var oldWidth; 
    var oldHeight;
    var oldLeft;
    var oldTop;

    fabric.Image.fromURL(url, function(img) {
      if (_currentImage) {
        oldWidth = _currentImage.getScaledWidth()
        oldHeight = _currentImage.getScaledHeight()
        oldLeft = _currentImage.left
        oldTop = _currentImage.top  
        canvas.remove(_currentImage);  
      }

      _currentImage = img;

      img.set({ 'left': oldLeft || 0 })
      img.set({ 'top': oldTop || 0 })

      if (oldHeight && oldHeight > img.getScaledHeight()){
        img.scaleToWidth(oldWidth);
        img.set({'height': oldHeight })
      } else if (oldWidth > img.getScaledWidth()){
        img.scaleToHeight(oldHeight);
        img.set({'width': oldWidth })
      }

      img.selectable = true
      canvas.add(img).setActiveObject(img);
    });
  }

  function addImage(url){
    setProductImage(url)
    canvas.renderAll()
  }      

您会看到图像确实按我想要的方式缩放,但随后无法对齐。

我也想在图像周围放置一个边界框,并可能尝试在其中对齐和缩放,但是我不确定织物是否可以做到这一点?

1 个答案:

答案 0 :(得分:2)

这就是我所做的。 当您运行scaleToWidthscaleToHeight时,scaleXscaleY会发生变化,您需要将oldHeightoldWidth调整为新的{{ 1}} / img.scaleX 我还从img.scalaY重写了_renderFill方法来创建偏移效果。 在这里查看:https://jsfiddle.net/mariusturcu93/co8dg527/37/

代码

fabric.Image.prototype

<html> <head> <title>Fabric kicking</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.0/fabric.js"></script> <style> #stage { border: solid 1px #333; } </style> </head> <body> <button onclick="addImage('https://s.hs-data.com/bilder/spieler/gross/208995.jpg')">Add image</button> <button onclick="addImage('https://cdn.images.express.co.uk/img/dynamic/67/590x/Mateusz-Klich-883903.jpg')">add another image</button> <canvas id="stage" width="600" height="600"></canvas> <script> var canvas = new fabric.Canvas('stage'); var cw = canvas.getWidth() var ch = canvas.getHeight() var _currentImage; function setProductImage(url){ var oldWidth; var oldHeight; var oldLeft; var oldTop; fabric.Image.fromURL(url, function(img) { if (_currentImage) { oldWidth = _currentImage.getScaledWidth() oldHeight = _currentImage.getScaledHeight() oldLeft = _currentImage.left oldTop = _currentImage.top canvas.remove(_currentImage); } _currentImage = img; img.set({ 'left': oldLeft || 0 }) img.set({ 'top': oldTop || 0 }) if (oldHeight && oldHeight > img.getScaledHeight()){ img.scaleToWidth(oldWidth); img.set({'height': oldHeight/img.scaleX}) } else if (oldWidth > img.getScaledWidth()){ img.scaleToHeight(oldHeight); img.set({'width': oldWidth/img.scaleY }) } img.selectable = true canvas.add(img).setActiveObject(img); }); } function addImage(url){ setProductImage(url) canvas.renderAll() } </script> <img src="https://s.hs-data.com/bilder/spieler/gross/208995.jpg" /> <img src="https://cdn.images.express.co.uk/img/dynamic/67/590x/Mateusz-Klich-883903.jpg" /> </body> </html> 重写

fabric.Image.prototype._renderFill