FabricJS并在整个剪辑区域中填充图像

时间:2018-08-10 20:49:05

标签: fabricjs

我希望有人可以向我指出我需要更新的方向。

我有一个带有多个剪贴区域的画布。这是我需要实现的:

  1. 将图像添加到剪辑区域
  2. 调整图像以使其覆盖整个剪辑区域
  3. 允许图像在剪辑区域内移动/平移/缩放/等。
  4. 图像应始终填充剪辑区域(剪辑区域内没有空白空间)。因此,图像必须不能平移/缩放/等太远,以使其保持在剪辑范围内。

我有一个示例,其中有一个剪辑区域:https://jsfiddle.net/thindery/9mv7ujcw/

fabric.Image.prototype._render = function(ctx) {
  var fwidth = this._element.width / (this.zoomLevel + 1);
  var fheight = this._element.height / (this.zoomLevel + 1);
  var wdiff = (fwidth - this._element.width) / 2;
  var hdiff = (fheight - this._element.height) / 2;
  ctx.drawImage(this._element, -wdiff, -hdiff, fwidth, fheight, -this.width/2, - this.height/2, this.width, this.height);
}
      var canvas = this.__canvas = new fabric.Canvas('c');
      fabric.Image.fromURL("https://images.unsplash.com/photo-1533832422535-0e12e90e63a2?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=3c07f6e6cee59e8057b91434c7178b08&auto=format&fit=crop&w=1876&q=80", function(img) {
        var zoomLevel = 0;
        var zoomLevelMin = 0;
        var zoomLevelMax = 3;
        img.zoomLevel = 0
        img.lockUniScaling = true;
            img.centeredScaling = true;
        img.clipTo = function(ctx){
                ctx.save();
                ctx.setTransform(1, 0, 0, 1, 0, 0);
                    clipArea.render(ctx);
                    ctx.restore();
        }
                fitImageToArea(img);
        canvas.add(img);

        img.zoomIn = function() {
          if (zoomLevel < zoomLevelMax) {
            zoomLevel += 0.1;
            img.zoomLevel = zoomLevel;
          }
        };


        img.zoomOut = function() {
          zoomLevel -= 0.1;
          if (zoomLevel < 0) zoomLevel = 0;
          if (zoomLevel >= zoomLevelMin) {
            img.zoomLevel = zoomLevel;
          }
        };

      });

      canvas.on('mouse:wheel', function(option) {
        var imgObj = canvas.getActiveObject();
        if (!imgObj) return;
        option.e.preventDefault();
        if (option.e.deltaY > 0) {
          imgObj.zoomOut();
        } else {
          imgObj.zoomIn();
        }
        canvas.renderAll();
      });

      var resize = function() {
        console.log('resize')
        var height = window.innerHeight;

        var scrollTop = $(window).scrollTop(),
        elementOffset = $('#c').offset().top,
        distance      = (elementOffset - scrollTop);
        //console.log("distance is "+ distance)
        height = height-distance-20;

        // So we need to calculate the proper scaled width
        // that should work well with every resolution
        var ratio = canvas.getWidth()/canvas.getHeight();
        var width = height * ratio;

        $(".upper-canvas, .lower-canvas").css({'width': width, 'height': height});
        $(".canvas-container").css({'width': width, 'height': height});
        //onsole.log(height)
        canvas.renderAll();
    }

  var clipArea = new fabric.Rect({
                        hasBorders: false,
                          hasControls: false,
                          lockMovementX: true,
                          lockMovementY: true,
                          evented: false,
                          stroke: "red",
                        x: 0,
                        y: 1,
                        width: 400,             
                        height: 500,                

                        fill: 'red',  //use transparent for no fill 
                        selectable: false,
                        objectCaching: false //<-- set this
                    });

          clipArea.setCoords();
          canvas.add(clipArea);

          var createBounds = function() {


        //"add" rectangle onto canvas
        //this.canvas.add(that.imageNodes[1]);
        //this.canvas.bringToFront(rect);
        canvas.on("object:moving", function(e) {
            var obj = e.target;
            obj.setCoords();  
            var top = obj.top;
            var bottom = top + obj.height;
            var left = obj.left;
            var right = left + obj.width;


            var _bounds = clipArea;
            var topBound = _bounds.top;
            var bottomBound = topBound + _bounds.height;
            var leftBound = _bounds.left;
            var rightBound = leftBound + _bounds.width;

            if(obj.currentHeight > _bounds.height || obj.currentWidth > _bounds.width){
                return
            }
            obj.setCoords();  
            //If the image is wider than the bounds, then we need to make sure visible stuff stays in the view
            if(obj.width > _bounds.width)
            {
                var mLeft = Math.min(Math.max(left, leftBound), rightBound - (obj.width * obj.scaleX));
                //var mRight = 
                //var mLeft = -640
                // console.log('mleft is '+ mLeft)
                console.log('object is wider')
                console.log('mleft is '+ mLeft)
                console.log('obj left is '+left)
                console.log(obj)

                if((mLeft <= left) && left < 0)
                {
                    return;
                }
                if(left >= 0 ){
                    mLeft = 0;
                }       
            }
            else
            {
                var mLeft = Math.min(Math.max(left, leftBound), rightBound - obj.width);
            }
            obj.set('left', mLeft);
        });
    };




  var fitImageToArea = function(theImage) {
            var cWidth, cHeight;
            cWidth = clipArea.getWidth();
            cHeight = clipArea.getHeight();

            if(cWidth > cHeight){ 
                theImage.scaleToWidth(cWidth);
                theImage.lockMovementX = true;
            } else {
                theImage.scaleToHeight(cHeight);
                theImage.lockMovementY = true;
            }
        };
  resize();
  $(window).resize(function(){
  resize();
  });

我已经可以做#1。但是我遇到了#2,#3和#4的问题。对于#2,它不会填充整个剪辑区域(红色区域)。缩放时,它应显示更多允许在剪辑区域中移动/平移的图像。但是,当我缩放到原始剪辑区域时,似乎正在剪切图像。

有人可以指出我可以在FabricJS的哪些领域实现概述的目标?

0 个答案:

没有答案