【问题标题】:FabricJs - Clipping area by SVG objectFabricJs - SVG 对象的剪切区域
【发布时间】:2018-07-19 08:33:37
【问题描述】:

我对 FabricJS 对象有疑问。我想创建一个剪辑区域(svg 对象),它将剪辑加载的图像。

我在加载的图像上使用 clipTo 方法将其传递到剪切区域形状对象 (SVG),但它不起作用,因为 SVG 不是 FabricJS 意义上的形状对象。有什么方法可以将加载的 SVG 转换为像 Polygon 或 Rect 这样的 FabricJS 形状?

如果我会使用它几乎效果很好:

globalCompositeOperation = 'source-atop' 

在加载的图像上(并删除 clipTo 函数),但如果我将移动/调整大小/旋转图像,它将与主剪切区域的边框(最大的矩形)重叠。图像不应与灰色矩形之外的其他对象交互,尤其是与主剪裁区域。 也许有办法通过使用 globalCompositeOperation 来实现这一点?

我将非常感谢任何提示。

这是我的问题的 JSFiddle: https://jsfiddle.net/6nfdr1ng/

这里几乎可以工作的版本(带有源代码): https://jsfiddle.net/ud9nev1g/

<input type="file" id="image"><br>
<canvas id="canvas" width="530" height="600"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.21/fabric.min.js"></script>
<script type="text/javascript">
    var canvas = new fabric.Canvas('canvas', {
        'selection': false
    });

    /**
     * loading man clipping rect
     */
    var clippingRect = new fabric.Rect({
        width: 185,
        height: 400,
        fill: 'transparent',
        stroke: 1,
        opacity: 1,
        hasBorders: false,
        hasControls: false,
        hasRotatingPoint: false,
        selectable: false,
        preserveObjectStacking: true,
        objectCaching: false
    });
    canvas.add(clippingRect);
    canvas.renderAll();

    /**
     * loading shape which should be another clipping area for loaded image
     */
    var svgString = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 63.7 63.7"><defs><style>.cls-1{fill:#79797a;fill-rule:evenodd;}</style></defs><title>Asset 4</title><g id="Layer_2" data-name="Layer 2"><g id="kwadrat"><path class="cls-1" d="M0,0H63.7V63.7H0Z"/></g></g></svg>';
    var retinaScalling = canvas.getRetinaScaling();
    fabric.loadSVGFromString(svgString, function (objects, options) {
        var shapeObject = fabric.util.groupSVGElements(objects, options);
        shapeObject.scaleX = 0.5;
        shapeObject.scaleY = 0.5;
        shapeObject.set('id', 'shape');
        shapeObject.scaleToWidth(clippingRect.getWidth());
        shapeObject.setCoords();
        shapeObject.clipTo = function (ctx) {
            ctx.save();
            ctx.setTransform(retinaScalling, 0, 0, retinaScalling, 0, 0);
            clippingRect.render(ctx);
            ctx.restore();
        };
        shapeObject.center();
        shapeObject.setCoords();
        canvas.setActiveObject(shapeObject);
        canvas.add(shapeObject);
        canvas.renderAll();
    });

    /**
     * loading image
     */
    document.getElementById('image').onchange = function (e) {
        var reader = new FileReader();
        var clippingAreaShape = canvas.getActiveObject();
        reader.onload = function (event) {
            var img = new Image();
            img.onload = function () {
                var shapeImageObject = new fabric.Image(img, {
                    objectCaching: false,
                    hasControls: true,
                    selectable: true
                });
                shapeImageObject.scaleToHeight(clippingAreaShape.getWidth());
                shapeImageObject.set('id', 'shape-image');
                shapeImageObject.set({
                    left: clippingAreaShape.left,
                    top: clippingAreaShape.top
                });
                shapeImageObject.clipTo = function (ctx) {
                    ctx.save();
                    ctx.setTransform(retinaScalling, 0, 0, retinaScalling, 0, 0);
                    clippingAreaShape.render(ctx);
                    ctx.restore();
                };
                // shapeImageObject.globalCompositeOperation = 'source-atop';
                canvas.add(shapeImageObject);
                canvas.renderAll();
                canvas.setActiveObject(shapeImageObject);
                shapeImageObject.setCoords();
            };
            img.src = event.target.result;
        };
        reader.readAsDataURL(e.target.files[0]);
    }

</script>

【问题讨论】:

    标签: javascript svg fabricjs


    【解决方案1】:

    我通过将 SVG 形状组合到一个路径中解决了我的问题(没有任何多边形任何其他 svg 对象),然后我将 svg 坐标传递到 fabircJS 路径中。有效的 SVG 坐标看起来像“M0,0H63.7V63.7H0Z”

    fabric.loadSVGFromURL('object.svg', function (objects, options) {
                let img1 = new fabric.Path(objects[0].d, {
                    fill: '#333',
                    opacity: 1,
                    hasBorders: true,
                    hasControls: true,
                    hasRotatingPoint: true,
                    selectable: true,
                    preserveObjectStacking: true,
                    objectCaching: false,
                });
         }
    

    我希望它会帮助别人:)

    【讨论】:

      猜你喜欢
      • 2015-12-31
      • 1970-01-01
      • 2019-06-12
      • 2018-02-09
      • 2013-09-09
      • 1970-01-01
      • 2010-11-22
      • 2019-04-05
      • 1970-01-01
      相关资源
      最近更新 更多