将图像拖放到画布上 (FabricJS)

2024-02-06

问题
我想用图像而不是canvas目的。这意味着您必须先将要添加的内容添加到画布并作为画布的一部分,然后才能添加它。这些图像实际上是网站的一部分,因此不需要做一些复杂的事情。我在这里找到的这段代码仅适用于对象而不是实际元素的情况。顺便说一句我正在使用FabricJS http://fabricjs.com/只是为了让您知道我没有使用默认的 HTML5 画布内容。

至于任何可能在不使用我当前代码的情况下工作的替代方案。请务必将其发布在下面的评论或答案中。我真的很想知道你们的想法。

Summary
基本上我希望能够在画布上拖放图像,同时保留鼠标光标位置。例如,如果我拖动图像并且光标位于 x: 50 y: 75 处,它会将图像拖放到该确切位置。就像我找到的代码所做的那样。但就像问题所述,代码使用一个对象将其拖到画布上,然后克隆它。我希望仅使用普通的旧元素来实现此功能。例如:<img>.


代码 - JsFiddle http://jsfiddle.net/ssk7833/qy5p6a0g/14/

window.canvas = new fabric.Canvas('fabriccanvas');
var edgedetection = 8; //pixels to snap
canvas.selection = false;

window.addEventListener('resize', resizeCanvas, false);

function resizeCanvas() {
    canvas.setHeight(window.innerHeight);
    canvas.setWidth(window.innerWidth);
    canvas.renderAll();
}

// resize on init
resizeCanvas();

//Initialize Everything
init();

function init(top, left, width, height, fill) {

    var bg = new fabric.Rect({
        left: 0,
        top: 0,
        fill:  "#eee",
        width: window.innerWidth,
        height: 75,    
        lockRotation: true,
        maxHeight: document.getElementById("fabriccanvas").height,
        maxWidth: document.getElementById("fabriccanvas").width,
        selectable: false,
    });

    var squareBtn = new fabric.Rect({
        top: 10,
        left: 18,
        width: 40,
        height: 40,
        fill: '#af3',
        lockRotation: true,
        originX: 'left',
        originY: 'top',
        cornerSize: 15,
        hasRotatingPoint: false,
        perPixelTargetFind: true,
    });

    var circleBtn = new fabric.Circle({
        radius: 20,
        fill: '#f55',
        top: 10,
        left: 105,
    });

    var triangleBtn = new fabric.Triangle({
        width: 40, 
        height: 35, 
        fill: 'blue', 
        top: 15,
        left: 190,
    });

    var sqrText = new fabric.IText("Add Square", {
        fontFamily: 'Indie Flower',
        fontSize: 14,
        fontWeight: 'bold',
        left: 6,
        top: 50,
        selectable: false,
    });

    var cirText = new fabric.IText("Add Circle", {
        fontFamily: 'Indie Flower',
        fontSize: 14,
        fontWeight: 'bold',
        left: 95,
        top: 50,
        selectable: false,
    });

    var triText = new fabric.IText("Add Triangle", {
        fontFamily: 'Indie Flower',
        fontSize: 14,
        fontWeight: 'bold',
        left: 175,
        top: 50,
        selectable: false,
    });

    var shadow = {
        color: 'rgba(0,0,0,0.6)',
        blur: 3,    
        offsetX: 0,
        offsetY: 2,
        opacity: 0.6,
        fillShadow: true, 
        strokeShadow: true 
    };

    window.canvas.add(bg);
    bg.setShadow(shadow);
    window.canvas.add(squareBtn);
    window.canvas.add(circleBtn);
    window.canvas.add(triangleBtn);
    window.canvas.add(sqrText);
    window.canvas.add(cirText);
    window.canvas.add(triText);

    canvas.forEachObject(function (e) {
        e.hasControls = e.hasBorders = false; //remove borders/controls
    });

    function draggable(object) {
        object.on('mousedown', function() {
            var temp = this.clone();
            temp.set({
                hasControls: false,
                hasBorders: false,
            });
            canvas.add(temp);
            draggable(temp);
        });
        object.on('mouseup', function() {
            // Remove an event handler
            this.off('mousedown');

            // Comment this will let the clone object able to be removed by drag it to menu bar
            // this.off('mouseup');

            // Remove the object if its position is in menu bar
            if(this.top<=75) {
                canvas.remove(this);
            }
        });
    }

    draggable(squareBtn);
    draggable(circleBtn);
    draggable(triangleBtn);

    this.canvas.on('object:moving', function (e) {
        var obj = e.target;
        obj.setCoords(); //Sets corner position coordinates based on current angle, width and height
        canvas.forEachObject(function (targ) {
            activeObject = canvas.getActiveObject();


            if (targ === activeObject) return;


            if (Math.abs(activeObject.oCoords.tr.x - targ.oCoords.tl.x) < edgedetection) {
                activeObject.left = targ.left - activeObject.currentWidth;

            }
            if (Math.abs(activeObject.oCoords.tl.x - targ.oCoords.tr.x) < edgedetection) {
                activeObject.left = targ.left + targ.currentWidth;

            }
            if (Math.abs(activeObject.oCoords.br.y - targ.oCoords.tr.y) < edgedetection) {
                activeObject.top = targ.top - activeObject.currentHeight;
            }
            if (Math.abs(targ.oCoords.br.y - activeObject.oCoords.tr.y) < edgedetection) {
                activeObject.top = targ.top + targ.currentHeight;
            }
            if (activeObject.intersectsWithObject(targ) && targ.intersectsWithObject(activeObject)) {

            } else {
                targ.strokeWidth = 0;
                targ.stroke = false;


            }
            if (!activeObject.intersectsWithObject(targ)) {
                activeObject.strokeWidth = 0;
                activeObject.stroke = false;
                activeObject === targ
            }
        });
    });
}

我找到了更多代码,但没有解决我的问题:

var canvas = new fabric.Canvas('c');

canvas.on("after:render", function(){canvas.calcOffset();});

var started = false;
var x = 0;
var y = 0;
var width = 0;
var height = 0;

canvas.on('mouse:down', function(options) {
  //console.log(options.e.clientX, options.e.clientY);

  x = options.e.clientX;
  y = options.e.clientY;

  canvas.on('mouse:up', function(options) {

    width = options.e.clientX - x;
    height = options.e.clientY - y;   

    var square = new fabric.Rect({

        width: width, 
        height: height, 
        left: x + width/2 - canvas._offset.left, 
        top: y + height/2 - canvas._offset.top, 
        fill: 'red',
        opacity: .2
    });
    canvas.add(square);
    canvas.off('mouse:up');
    $('#list').append('<p>Test</p>');

  });

});

此代码向画布添加一个矩形。但问题是这并没有达到我想要的效果,基本上,如前所述,我希望能够拖动一个img元素,然后无论您将该图像拖动到画布上的哪个位置,它都会将其精确地放置在该位置。

CREDITS
Fabric JS:鼠标按下时复制/粘贴对象 https://stackoverflow.com/questions/28183763/fabric-js-copy-paste-object-on-mouse-down
Fabric.js 偏移解决方案 https://stackoverflow.com/questions/17328675/fabric-js-offset-solution/17328990?noredirect=1#comment51942569_17328990


它不需要做一些复杂的事情。

实现图像拖动的逻辑框架可能是使用事件侦听器来监视鼠标事件。

将鼠标放在页面内的图像元素上但不在画布上时,记录哪个图像元素以及图像中的鼠标位置。鼠标放在任意位置时,将此记录设置回空。

将鼠标悬停在具有非空图像记录的画布上时,从图像元素创建 Fabric 图像元素(根据文档),计算它从记录的图像位置和当前鼠标位置的位置,将其粘贴到鼠标下方,使其成为Draggable 并模拟鼠标单击的效果以继续拖动它。

我认为这个问题是关于程序开发的设计和可行性阶段的。

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

将图像拖放到画布上 (FabricJS) 的相关文章

  • Javascript 函数与 php 一样吗?

    我在网站上使用 WebIM 提供聊天支持 我希望能够在客户端启动聊天会话时设置一个计时器 如果操作员 技术人员在 x 秒内没有响应 我希望页面重定向到客户端可以留言的另一个页面 有点像 请稍等 我们尝试联系您 这样 如果所有技术人员都太忙或
  • 如何用js获取一个月的4个星期一?

    我正在构建一个图表 其中 x 轴应该是一个月的四个星期 我只想显示该月的四个星期一 我已经有了currentMonth和currentYear变量 而且我知道如何获取该月的第一天 我所需要的只是将一个月的四个星期一放入数组中 所有这些都在同
  • 在 Javascript 中,有什么方法可以知道从哪个主机脚本加载?

    在javascript中 作为从某个主机加载的脚本 有什么方法可以知道我是从哪个服务器 主机加载的 我需要向该主机发出额外的 ajax 请求 并且更愿意动态地找出主机 因此 如果您在页面上包含 javascript 文件 当该 javasc
  • 如何删除事件监听器?

    下面是我的事件监听器代码 window addEventListener beforeunload function e if sessionStorage token abide call api 如果我想删除这个事件监听器 我该怎么办
  • 将 javascript 合并到一个文件中

    最近阅读了雅虎的网络优化技巧并使用 YSlow 我在我的一个网站上实现了他们的一些想法http www gwynfryncottages com http www gwynfryncottages com你可以在这里看到该文件http ww
  • 解释 javascript 中的奇怪行为

    我在推特上看到了这个 我也无法解释 定义一个onload函数按以下两种方式工作 1 JSFiddle http jsfiddle net 6rq9k 2 JSFiddle http jsfiddle net 6rq9k 1
  • 如何将元素的每个单词包装在span标签中?

    div date contents filter function return this nodeType 1 wrap span span 我是新手 认为代码可以解决问题 但它将所有内容都包含在 span 像这样 div class d
  • 标点符号加载“动画”,javascript?

    我正在寻找一种好方法来显示一些标点符号加载 动画 我想要的是这样的 This will display at second 1 Waiting for your input This will display at second 2 Wai
  • 如何在 jQuery 中使用 CSS“background-image”属性添加的图像上绑定单击事件

    这是我的小提琴link http jsbin com otisur 1 edit 我想我的问题通过标题本身就很清楚了 尽管如此 我正在寻找一种绑定的方法click使用 css 添加的图像上的事件background image财产 我知道
  • 如何延迟 NavLink 的反应?

    Delay e gt e preventDefault setTimeout gt e unpreventDefault make this work 500 render
  • JavaScript:参数列表后缺少 )

    这个 JavaScript 产生一个错误 参数列表后缺少 在 firebug 中使用代码 我究竟做错了什么 功能d缺少左括号 answer after 不应该逃避 只需常规报价即可
  • 从 JavaScript 将参数传递给 p:remoteCommand

    我想将值传递给remoteCommand来自 JavaScript 如果这是可能的 我该如何做到这一点以及如何在支持 bean 中接收它们 对的 这是可能的 如何执行此操作取决于 PrimeFaces 版本 你可以在PrimeFaces 用
  • 无法从 Twin.macro 中的 Prop 获取值

    您可以在这里查看我正在尝试执行的操作的示例 https codesandbox io s vibrant leaf qj8vz https codesandbox io s vibrant leaf qj8vz 注意 这个特定的例子使用双宏
  • 在js中检测浏览器的最佳方法

    JavaScript 中有很多浏览器检测方法 据我所知 使用navigator userAgent或检测特征 例如XMLHttpRequest 等等 谁能告诉我哪种方法最好 最有效 如果你真的需要知道什么browser他们正在使用 你主要需
  • 测量填写部分的时间 - 谷歌表单

    我正在尝试使用谷歌表单进行研究调查问卷 对于某些部分 我想自动测量用户填写所需的时间 谷歌表单中没有这样的选项 我尝试复制表单源 并用 javascript 填充时间 但它不起作用 跨源问题 未能成功托管复制的表单 如何做到 我如何衡量回答
  • 将数字限制为段的最优雅的方法是什么?

    比方说x a and b是数字 我需要限制x到段的边界 a b 换句话说 我需要一个钳位功能 https math stackexchange com q 1336636 clamp x max a min x b 有人能想出一个更易读的版
  • apollo 客户端从存储中删除而不发生突变

    我需要通过 id 从本地存储中删除一条 记录 而不使用突变 因为服务器不支持突变 我尝试像这样手动访问商店 delete this apolloClient store getState apollo data 1112 这会删除记录 但是
  • select 元素是否具有标准值属性?

    这是一个简单的问题 但我找不到任何参考资料 所以就在这里 假设我有一个选择元素
  • 替换打字稿中字符串中字符的所有实例?

    我正在尝试用 x 字符替换电子邮件中的所有句号 例如 电子邮件受保护 cdn cgi l email protection 将变为 myxemail emailxcom 电子邮件设置为字符串 我的问题是它不只是替换句号 而是替换每个字符 所
  • 右列固定的 Div 表

    我最近接手了一个非营利网站作为一个项目 我正在使用一个现有的网站 所以我必须使用很多已经编程的东西 所以我所要做的就是创建设计 I made a diagram of basically what I can t figure out ho

随机推荐