FabricJs - 通过 SVG 对象剪切区域

2024-03-23

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

我在加载的图像上使用 ClipTo 方法,将其传递到剪切区域形状对象(SVG)中,但它不起作用,因为 SVG 不是 FabricJS 意义上的形状对象。有没有办法将加载的 SVG 转换为 FabricJS 形状,如多边形或矩形?

如果我使用以下方法,它几乎可以正常工作:

globalCompositeOperation = 'source-atop' 

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

我将非常感谢任何提示。

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

这里几乎可以工作的版本(带有源代码):https://jsfiddle.net/ud9nev1g/ 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>

我通过将 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,
            });
     }

我希望它能帮助别人:)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FabricJs - 通过 SVG 对象剪切区域 的相关文章

随机推荐

  • 将 .Net Core Web-API 迁移到 AWS Web Api 网关

    我有一个使用 Net Core 开发的 Web API 它有几个端点 GET POST 要求是将其移至 AWS API Gateway 该 Web API 是使用分层架构构建的 它有一个与 Db 层通信的业务层 该层拥有一些实体框架存储库
  • 如何使用 jax-rs 进行分段/表单文件上传?

    特别是 RESTeasy 如果 对于单个文件 有一个像这样的方法签名那就太好了 public void upload FormParam name FormParam file file InputStream 可行吗 还是我在做梦 似乎没
  • 将数据帧转换为向量(按行)

    我有一个包含像这样的数字条目的数据框 test lt data frame x c 26 21 20 y c 34 29 28 我怎样才能得到下面的向量 gt 26 34 21 29 20 28 我能够使用以下方法获得它 但我想应该有一种更
  • 微服务中的服务器到服务器通信

    我正在研究微服务架构 但我在这方面面临一些挑战 首先让我向您简要介绍一下架构 用户登录并获取签名令牌 该令牌将用于调用所有 REST API 将会有很多 API 服务器 其中 API 使用 Spring 安全性进行保护 并根据用户角色进行授
  • 奇数或偶数反斜杠和转义字符

    我对下面的代码有一点问题 import re pattern re compile r for text in r ok py r ok py r ok py r ok py r ok py search re search pattern
  • ReactJs“不变违规...”经典反应问题

    这是一个典型的反应问题 但我有点不知道如何处理它 我只想动态渲染我的表格线 但我收到错误 未捕获错误 不变违规 processUpdates 无法找到元素的子元素 2 这可能意味着 DOM 意外变异 例如 通过浏览器 通常是由于在使用表 嵌
  • 如何以简单的方式将 CGPoint 对象添加到 NSArray 中?

    我有大约 50 个 CGPoint 对象 它们描述了类似 路径 的东西 我想将它们添加到 NSArray 中 这将是一个只返回给定索引对应的 CGPoint 的方法 我不想创建 50 个变量 例如 p1 p2 依此类推 有没有一种简单的方法
  • 在 Windows Phone 8 中存储配置值/设置的最佳方法

    由于 WP8 应用程序中没有默认配置文件 因此存储配置值的最佳方式是什么 例如WCF 服务 URL 用户名和密码 我希望当手机重新启动且应用程序关闭时这些值可用且可更新 提前致谢 你应该使用IsolatedStorageSettings A
  • 如何在 Swift 中的自定义类中初始化 Timer? [复制]

    这个问题在这里已经有答案了 我制作了一个简单的计时器应用程序 但是 现在我想让它变得更好 并且我想为计时器控件编写一个类 class Cronometer private var counter Int 0 private var time
  • https://graph.microsoft.com/v1.0/places/microsoft.graph.room Api 未提供更新的数据

    我正在使用 Microsoft Graph 获取可供租户使用的房间列表 根据文档 列出 Palace Api 应该用于此目的 现在 我在使用 List Places api 获取更新数据时遇到问题 我已向租户添加了一些房间 但这些房间并未反
  • 使用 LINQ 时谓词的顺序重要吗?

    我知道以不同的顺序执行操作会产生不同的性能 例如以下慢速查询之间的差异 List
  • 无法在电子js中加载反应

    这是我的 package js 文件 name cabed version 0 1 0 private false dependencies testing library jest dom 5 16 5 testing library r
  • 经典 ASP 错误行 0 列 -1

    我们运行一个基于经典 ASP 构建的繁忙网站 出于各种遗留原因 在繁忙期间 我们会看到无法解释的错误 但无法追根究底 它通过 IIS 7 触发我们的自定义 500 错误页面来体现 在此页面上 我们使用 ASPError 对象和 err 对象
  • 如何用点更改 ggplot2 箱线图颜色

    解决了抖动问题 https stackoverflow com questions 52506296 ggplot geom point position jitterdodge not working when color specifi
  • 如何在宽度可变的 div 中居中/对齐 Google 地图

    我在 div 中加载了 Google 地图 其宽度为页面的 100 通过 API 叠加层位于中心 地图应如下所示放置 问题是地图现在左对齐 我可以使用与页面宽度相对应的 LatLng 移动中心 但这对于一个简单的任务来说似乎需要大量工作 我
  • C# 为 Azure Function v3 全局设置大小写约定

    我是 Azure Functions 的新手 正在尝试将 NET Core API 转换为 Azure Functions 我面临的问题是如何全局设置响应命名约定 JSON 默认情况下 它是CamelCase但我想用PascalCase 我
  • 如何从 git 上的 filter-branch 命令中删除重复的提交?

    我有一个 Django 项目 我已经将其保密很长一段时间了 在我参与的项目的整个生命周期中settings py base settings py and secret settings py包含敏感信息的文件 现在我决定将代码开源 因为我
  • React Native - TextInput 的 onChange 与 onChangeText 之间的区别

    我不确定什么时候使用onChange vs onChangeText in a TextInput成分 我知道onChangeText接受更改后的文本作为回调中的参数 但这就是您要使用的原因onChangeText 因为您可以在回调中更新状
  • Array_merge 与 + [重复]

    这个问题在这里已经有答案了 当我使用array merge 使用关联数组我得到了我想要的 但是当我将它们与数字键数组一起使用时 键会发生变化 With 键被保留 但它不适用于关联数组 我不明白这是如何工作的 有人能给我解释一下吗 由于两个数
  • FabricJs - 通过 SVG 对象剪切区域

    我对 FabricJS 对象有疑问 我想创建一个剪切区域 svg 对象 它将剪切加载的图像 我在加载的图像上使用 ClipTo 方法 将其传递到剪切区域形状对象 SVG 中 但它不起作用 因为 SVG 不是 FabricJS 意义上的形状对