Масштабируйте изображение, чтобы оно соответствовало при замене изображения - PullRequest
0 голосов
/ 07 октября 2018

Я пытаюсь реализовать поведение, с помощью которого я могу добавить исходное изображение к холсту (заполнитель), а затем впоследствии я могу выбрать другое изображение для замены этого изображения - это новое изображение должно затем масштабироваться до «соответствия»«в рамках старого образа.Например, если я выбираю портретное изображение в качестве «заполнителя», а затем выбираю ландшафтное изображение для его замены, я ожидаю, что ландшафтное изображение сначала масштабирует свою ширину и поддерживает соотношение сторон, а затем выравнивается по вертикали в пределах границ заполнителя..

Вот jsfiddle того, что я до сих пор работал: 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 голосов
/ 07 октября 2018

Это то, что я сделал.Когда вы запускаете scaleToWidth и scaleToHeight, scaleX и scaleY меняется, и вам нужно настроить oldHeight и oldWidth на новый img.scaleX / img.scalaY. Я также переписываю _renderFill методот fabric.Image.prototype, чтобы создать эффект смещения.Проверьте здесь: https://jsfiddle.net/mariusturcu93/co8dg527/37/

Код

<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 перезапись

fabric.Image.prototype._renderFill= (function(renderFill){
    return function(ctx) {

      var w = this.width, h = this.height, sW = w * this._filterScalingX, sH = h * this._filterScalingY,
          x = -w / 2, y = -h / 2, elementToDraw = this._element;

          y = y  + Math.abs((this._element.height-h)/2);
          x = x  + Math.abs((this._element.width-w)/2);
      elementToDraw && ctx.drawImage(elementToDraw,
        this.cropX * this._filterScalingX,
        this.cropY * this._filterScalingY,
        sW,
        sH,
        x, y, w, h);
    }
})()
...