如何组合 Raphael javascript 库中的对象?

2024-02-18

抱歉问了一个很长的问题,但是就这样吧。我正在尝试修改此处演示周围的拖动形状:

http://raphaeljs.com/graffle.html http://raphaeljs.com/graffle.html

该演示运行良好。我想做的是将文字放入形状内,并将形状和文本作为复合单个对象移动。

这是创建对象的代码:

window.onload = function () {
    var dragger = function () {
        this.ox = this.type == "rect" ? this.attr("x") : this.attr("cx");
        this.oy = this.type == "rect" ? this.attr("y") : this.attr("cy");
        this.animate({"fill-opacity": .2}, 500);
    },
        move = function (dx, dy) {
            var att = this.type == "rect" ? {x: this.ox + dx, y: this.oy + dy} : {cx: this.ox + dx, cy: this.oy + dy};
            this.attr(att);
            for (var i = connections.length; i--;) {
                r.connection(connections[i]);
            }
            r.safari();
        },
        up = function () {
            this.animate({"fill-opacity": 0}, 500);
        },
        r = Raphael("holder", 640, 480),
        connections = [],
        shapes = [  r.ellipse(190, 100, 30, 20),
                    r.rect(290, 80, 60, 40, 10),
                    r.rect(290, 180, 60, 40, 2),
                    r.ellipse(450, 100, 20, 20)
                ];
    for (var i = 0, ii = shapes.length; i < ii; i++) {
        var color = Raphael.getColor();
        shapes[i].attr({fill: color, stroke: color, "fill-opacity": 0, "stroke-width": 2, cursor: "move"});
        shapes[i].drag(move, dragger, up);
    }
    connections.push(r.connection(shapes[0], shapes[1], "#fff"));
    connections.push(r.connection(shapes[1], shapes[2], "#fff", "#fff|5"));
    connections.push(r.connection(shapes[1], shapes[3], "#000", "#fff"));
};

我尝试过这样的事情:

 myWords = [ r.text(190, 100,  "Hello"),
      r.text(480,100, "Good Bye")
    ];

并在其他地方进行了调整,以便它可以工作,但它只是移动文本和形状,但形状和文本永远不会被视为一个整体。我可以将文本与形状分开移动,反之亦然。我需要它们成为一个对象。所以他们一起移动。我怎样才能做到这一点?感谢您的任何帮助。

EDIT:

我试过这个:

  st.push(r.text (190, 100, "node1"), r.ellipse(190, 100, 30, 20)),
  st.push(r.text (290, 80, "Center"), r.rect(290, 80, 60, 40, 10)),
  st.push(r.text (290, 180, "node2"), r.rect(290, 180, 60, 40, 2)),
  st.push(r.text (450, 100, "node3"), r.ellipse(450, 100, 20, 20))

但是当我移动形状时,文本和形状并没有保持在一起。文字只是静止不动。

编辑:我无法获得库存演示http://raphaeljs.com/graffle.html http://raphaeljs.com/graffle.html与 Chrome 一起使用。 IE 可以用。


进行了重大编辑,以更优雅的方式关联元素。


Sets http://raphaeljs.com/reference.html#set适合对 Raphael 对象进行分组,但集合不会创建自己的元素,因此您无法拖放集合,因为当您单击画布时,您可以选择形状或文本,但永远不会选择集合(因为没有设置元素)。

这是一个简单的 jsFiddle,显示集合的属性。 http://jsfiddle.net/v2ahW/请注意,集合没有x or y特性。

来自拉斐尔文档 http://raphaeljs.com/reference.html:

[A set c]创建类似数组的对象来同时保存和操作几个元素。警告:它不会在页面中为自己创建任何元素。

简单的解决方法是使文本和形状都可单独拖动。然后将关联的文本与形状一起移动...以及关联的形状与文本一起移动。

像这样关联对象很简单......创建一个属性。在这种情况下,每个形状和每个文本都有一个称为.pair这是对关联元素的引用。

其操作方法如下:

var i, ii, tempS, tempT
     shapes = [  ... ],
     texts = [  ... ];
for (i = 0, ii = shapes.length; i < ii; i++) {
    tempS = shapes[i].attr( ... );
    tempT = texts[i].attr( ...);

      // Make all the shapes and texts dragable
    shapes[i].drag(move, dragger, up);
    texts[i].drag(move, dragger, up);

      // Associate the elements
    tempS.pair = tempT;
    tempT.pair = tempS;
}

然后在拖放代码中,这是move(), dragger(), and up()您必须确保处理单击的元素及其关联元素的函数。

例如,这里是相关部分move()功能。注意text可以用同样的方式处理rectangle(通过改变属性x and y), 所以false下面每个 Javascript 条件运算符中的条件都处理以下两种情况rectangle并为text

move = function (dx, dy) {

      // Move main element
    var att = this.type == "ellipse" ? 
                           {cx: this.ox + dx, cy: this.oy + dy} : 
                           {x: this.ox + dx, y: this.oy + dy};
    this.attr(att);

      // Move paired element
    att = this.pair.type == "ellipse" ? 
                            {cx: this.pair.ox + dx, cy: this.pair.oy + dy} : 
                            {x: this.pair.ox + dx, y: this.pair.oy + dy};
    this.pair.attr(att);
    ...
}

下面是完整的工作代码:

可拖动文本和形状的 jsFiddle 工作示例 http://jsfiddle.net/CHUrB/

Raphael.fn.connection = function (obj1, obj2, line, bg) {
    if (obj1.line && obj1.from && obj1.to) {
        line = obj1;
        obj1 = line.from;
        obj2 = line.to;
    }
    var bb1 = obj1.getBBox(),
        bb2 = obj2.getBBox(),
        p = [{x: bb1.x + bb1.width / 2, y: bb1.y - 1},
        {x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + 1},
        {x: bb1.x - 1, y: bb1.y + bb1.height / 2},
        {x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height / 2},
        {x: bb2.x + bb2.width / 2, y: bb2.y - 1},
        {x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + 1},
        {x: bb2.x - 1, y: bb2.y + bb2.height / 2},
        {x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height / 2}],
        d = {}, dis = [];
    for (var i = 0; i < 4; i++) {
        for (var j = 4; j < 8; j++) {
            var dx = Math.abs(p[i].x - p[j].x),
                dy = Math.abs(p[i].y - p[j].y);
            if ((i == j - 4) || (((i != 3 && j != 6) || p[i].x < p[j].x) && ((i != 2 && j != 7) || p[i].x > p[j].x) && ((i != 0 && j != 5) || p[i].y > p[j].y) && ((i != 1 && j != 4) || p[i].y < p[j].y))) {
                dis.push(dx + dy);
                d[dis[dis.length - 1]] = [i, j];
            }
        }
    }
    if (dis.length == 0) {
        var res = [0, 4];
    } else {
        res = d[Math.min.apply(Math, dis)];
    }
    var x1 = p[res[0]].x,
        y1 = p[res[0]].y,
        x4 = p[res[1]].x,
        y4 = p[res[1]].y;
    dx = Math.max(Math.abs(x1 - x4) / 2, 10);
    dy = Math.max(Math.abs(y1 - y4) / 2, 10);
    var x2 = [x1, x1, x1 - dx, x1 + dx][res[0]].toFixed(3),
        y2 = [y1 - dy, y1 + dy, y1, y1][res[0]].toFixed(3),
        x3 = [0, 0, 0, 0, x4, x4, x4 - dx, x4 + dx][res[1]].toFixed(3),
        y3 = [0, 0, 0, 0, y1 + dy, y1 - dy, y4, y4][res[1]].toFixed(3);
    var path = ["M", x1.toFixed(3), y1.toFixed(3), "C", x2, y2, x3, y3, x4.toFixed(3), y4.toFixed(3)].join(",");
    if (line && line.line) {
        line.bg && line.bg.attr({path: path});
        line.line.attr({path: path});
    } else {
        var color = typeof line == "string" ? line : "#000";
        return {
            bg: bg && bg.split && this.path(path).attr({stroke: bg.split("|")[0], fill: "none", "stroke-width": bg.split("|")[1] || 3}),
            line: this.path(path).attr({stroke: color, fill: "none"}),
            from: obj1,
            to: obj2
        };
    }
};

var el;
window.onload = function () {
    var color, i, ii, tempS, tempT,
        dragger = function () {
                // Original coords for main element
            this.ox = this.type == "ellipse" ? this.attr("cx") : this.attr("x");
            this.oy = this.type == "ellipse" ? this.attr("cy") : this.attr("y");
            if (this.type != "text") this.animate({"fill-opacity": .2}, 500);

                // Original coords for pair element
            this.pair.ox = this.pair.type == "ellipse" ? this.pair.attr("cx") : this.pair.attr("x");
            this.pair.oy = this.pair.type == "ellipse" ? this.pair.attr("cy") : this.pair.attr("y");
            if (this.pair.type != "text") this.pair.animate({"fill-opacity": .2}, 500);            
        },
        move = function (dx, dy) {
                // Move main element
            var att = this.type == "ellipse" ? {cx: this.ox + dx, cy: this.oy + dy} : 
                                               {x: this.ox + dx, y: this.oy + dy};
            this.attr(att);

                // Move paired element
            att = this.pair.type == "ellipse" ? {cx: this.pair.ox + dx, cy: this.pair.oy + dy} : 
                                               {x: this.pair.ox + dx, y: this.pair.oy + dy};
            this.pair.attr(att);            

                // Move connections
            for (i = connections.length; i--;) {
                r.connection(connections[i]);
            }
            r.safari();
        },
        up = function () {
                // Fade original element on mouse up
            if (this.type != "text") this.animate({"fill-opacity": 0}, 500);

                // Fade paired element on mouse up
            if (this.pair.type != "text") this.pair.animate({"fill-opacity": 0}, 500);            
        },
        r = Raphael("holder", 640, 480),
        connections = [],
        shapes = [  r.ellipse(190, 100, 30, 20),
                    r.rect(290, 80, 60, 40, 10),
                    r.rect(290, 180, 60, 40, 2),
                    r.ellipse(450, 100, 20, 20)
                ],
        texts = [   r.text(190, 100, "One"),
                    r.text(320, 100, "Two"),
                    r.text(320, 200, "Three"),
                    r.text(450, 100, "Four")
                ];
    for (i = 0, ii = shapes.length; i < ii; i++) {
        color = Raphael.getColor();
        tempS = shapes[i].attr({fill: color, stroke: color, "fill-opacity": 0, "stroke-width": 2, cursor: "move"});
        tempT = texts[i].attr({fill: color, stroke: "none", "font-size": 15, cursor: "move"});
        shapes[i].drag(move, dragger, up);
        texts[i].drag(move, dragger, up);

        // Associate the elements
        tempS.pair = tempT;
        tempT.pair = tempS;
    }
    connections.push(r.connection(shapes[0], shapes[1], "#fff"));
    connections.push(r.connection(shapes[1], shapes[2], "#fff", "#fff|5"));
    connections.push(r.connection(shapes[1], shapes[3], "#000", "#fff"));
};​

为了完整起见,这里是代码链接到 jsFiddle 用于显示集合的属性 http://jsfiddle.net/v2ahW/:

window.onload = function () {
    var paper = Raphael("canvas", 320, 200),
        st = paper.set(), 
        propArr = [];

    st.push(
        paper.circle(10, 10, 5),
        paper.circle(30, 10, 5)
    );

    st.attr({fill: "red"});

    for(var prop in st) {
        if (st.hasOwnProperty(prop)) {
            // handle prop as required
            propArr.push(prop + " : " + st[prop]);
        }
    }
    alert(propArr.join("\n"));
};​

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

如何组合 Raphael javascript 库中的对象? 的相关文章

  • createHTMLNotification() 替换

    我创建了一个 Chrome 扩展程序 其中使用createHTMLNotification 在所有内容之上显示一个窗口 然而 从 Chrome 28 开始 谷歌决定放弃createHTMLNotification 完全 为什么 谷歌 为什么
  • 在 HTML5 Javascript 中将 BlobBuilder 转换为字符串

    function blobToString blob var reader new FileReader var d reader onloadend function d callback reader result console lo
  • 浏览器视口大小(以设备像素为单位)

    Goal 我希望 Flash 能够获得有关浏览器视口宽度和高度 以设备像素为单位 的准确信息初始化 调整大小或浏览器缩放事件时 规格 我需要将 flash 嵌入到在 chrome safari firefox 等中运行的 html 页面中
  • 在特定页面上执行 javascript 的正确“Rails”方式

    我试图在特定页面上运行 javascript 而我唯一的解决方案似乎是反模式 我有controller js内部生成的assets javascripts 我在用着gem jquery turbolinks 我的代码类似于以下内容 docu
  • 在 Internet Explorer 中使用什么来监视 jscript 内存使用情况

    我们正在调试 GWT 应用程序 在 Firefox 中运行正常 在 IE6 0 中开始运行正常 但一段时间后 它就会崩溃并开始爬行 经过一些测试后 我们怀疑存在一些内存问题 使用了太多内存 内存泄漏等 除了使用taskmanager和pro
  • Vue 3 Composition API 提供/注入在单文件组件中不起作用

    我正在使用 Composition API 在 VueJS 3 中创建一个库 我实现了提供 注入 如中所述docs https v3 vuejs org guide composition api provide inject html i
  • 通过 JavaScript 获取表单名称

    我有一个简单的问题 但我在网上找不到好的解决方案 我有这个 HTML 代码
  • 如何在网站上使用 svg 元素制作块的屏幕截图?

    我在网站上创建了一个构造函数 其本质是将所选元素及其颜色 svg中的元素 添加到访问者选择的背景和背景颜色 png中的背景 中 然后必须单击 保存 结果 按钮并仅执行工作区的屏幕截图 我写了这个脚本 但它需要屏幕截图 但只有背景 并忽略选定
  • 本地推送通知到在应用程序内运行 JS 代码的 Win8 Live Tile

    我正在尝试将更新发送到我的应用程序的磁贴 当应用程序运行时 这可以正常工作 例如 当用户单击按钮时 我可以轻松地将磁贴更新通知发送到磁贴 我无法解决的是当应用程序无法运行时如何更新磁贴 我找到的唯一选择是使用以下命令从远程 Web 服务器拉
  • ReactTransitionGroup 不适用于 React-redux 连接组件

    我正在开发一个更大的项目 但我创建了这个简短的示例来说明问题 如果我使用Box组件 它的工作原理 它在控制台中输出componentWillEnter and componentWillLeave当我们点击按钮时 如果我使用BoxConta
  • JavaScript 中的 Promise 有什么意义?

    一个承诺是一个 可能现在可用 或将来可用 或永远不可用的值 来源 MDN 假设我有一个想要处理图片的应用程序 图片已加载 例如在算法在后台使用它之后 或某种其他类型的延迟 现在我想检查一下图片是否可以在future 通过使用承诺 而不是回调
  • 计算三次贝塞尔曲线的弧长、曲线长度。为什么不工作?

    我正在用这个算法计算弧长 三次贝塞尔曲线的长度 function getArcLength path var STEPS 1000 gt precision var t 1 STEPS var aX 0 var aY 0 var bX 0
  • onclick 事件中未调用函数

    我想在每个 YouTube 链接的末尾添加一些 HTML 以在 litebox 中打开播放器 到目前为止 这是我的代码 document ready function var valid url new RegExp youtube com
  • JavaScript eval("{}") 返回行为?

    根据ECMA 262 规范 http www ecma international org publications files ECMA ST Ecma 262 pdf 以下语句返回1 eval 1 eval 1 eval 1 var a
  • 使用 Javascript 设置 cookie [重复]

    这个问题在这里已经有答案了 我正在尝试构建我的第一个移动应用程序 它需要连接到我的 mysql 数据库并使用 json 返回数据 这很好 目前我有一个登录系统 一旦确定用户名和密码存在 它就会返回一条成功消息 对于下一步 我想在我的页面上使
  • 使用 Jade 评估自定义 javascript 方法 (CircularJSON)

    我想通过 Jade 将一个对象解析为客户端 JavaScript 通常这会起作用 script var object JSON parse JSON stringify object but my object is circular ht
  • Rails 3.1+ 的 Jasmine 与 Mocha JavaScript 测试 [已关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我对茉莉花有经验并且非常喜欢它 有谁有 Jasmine 和 Mocha 的经验 特别是 Rails 的经验吗 我想知道是否值得转用 我已经在 J
  • react-native - 图像需要来自 JSON 的本地路径

    你好社区 我正在react native中开发一个测试应用程序 并尝试从本地存储位置获取图像 我实际在做什么 我将图像直接链接源提供给 var 并在渲染函数中调用此方法 react 0 14 8 react native 0 23 1 np
  • 滚动顶部不符合预期

    Note 由于上次忘记奖励而重新开放赏金 A Woff 大师已经给出答案 我想在用户展开某一行时到达该行 这样当最后一个可见行展开时 用户不必向下滚动即可查看内容 I used example tbody on click td green
  • 什么是 WKWebView 中的 WKErrorDomain 错误 4

    fatal error LPWebView encounters an error Error Domain WKErrorDomain Code 4 A JavaScript exception occurred UserInfo 0x7

随机推荐

  • Java 中双精度值的四舍五入

    目前我正在使用 DecimalFormat 类来舍入双精度值 double d 42 405 DecimalFormat f new DecimalFormat 00 System out println f format d output
  • Swagger 编辑器如何指定请求正文(POST)中的哪些字段是必需的?

    我正在尝试在在线 Swagger 编辑器中的用户类上定义 POST 方法 我希望能够在请求正文中指定多个字段 并且我希望生成的文档能够反映只有 2 个字段是必需的 其他是可选的 我必须做什么 改变才能做到这一点 我已经尝试过使用 requi
  • 管理 mnesia DBMS 中的增量计数器?

    我意识到 mnesia 不像 MySQL 或其他 RDBMS 那样支持自动增量功能 mnesia 文档中谈到的计数器并没有得到很好的解释 例如 到目前为止 我在整个文档中发现了一个操作计数器的函数 mnesia dirty update c
  • 检查 Python 列表中是否存在某个键

    假设我有一个可以包含一个或两个元素的列表 mylist important comment or mylist important 然后我想要一个变量作为标志 具体取决于第二个值是否存在 检查第二个元素是否存在的最佳方法是什么 我已经使用了
  • 流式操作符与延迟执行有何不同?

    In LINQ Where是一个流媒体运营商 然而OrderByDescending是一个非流操作符 AFAIK 流媒体运营商仅收集下一个必要的项目 非流式运算符立即评估整个数据流 我看不出定义流操作符的相关性 对我来说 延迟执行是多余的
  • 如何将 autoconf/automake 指向非标准包

    我正在尝试在 RedHat Linux 机器上构建 ZooKeeper ZooKeeper 到底是什么可能并不重要 当我按照包装说明进行操作时 我得到 autoreconf if aclocal configure ac 33 warnin
  • 使用RabbitMQ(Java客户端),有没有办法确定消费期间网络连接是否关闭?

    我在 RHEL 5 3 上使用 Java 客户端使用 RabbitMQ 我有 2 个节点 机器 Node1 正在使用 Java 帮助器类 QueueingConsumer 消费 Node2 上队列中的消息 QueueingConsumer
  • 在 R SF 中交叉大型空间数据集

    我有两个空间数据集 一个数据集包含许多多边形 总共超过 150k 指定不同的特征 如河流 植被 另一个数据集包含更少的指定不同区域的多边形 500 我需要将这两个数据集相交以获得不同区域的特征 我可以根据不同的特征对第一个数据集进行子集化
  • 需要从汇编中的字符串中删除所有非字母元素

    通过编写此汇编代码 我无法使用此选项来删除非字符字母 它将遍历字符串并进行所有比较 然后显示相同的字符串 且不删除任何非字符 我正在尝试将字母字符放入 tempString 中 然后将其移动到 edx 进行显示 它接受一个字符串并删除所有非
  • 我的代码是否阻止目录遍历?

    来自 Python WSGI 应用程序的以下代码片段可以安全地进行目录遍历吗 它读取作为参数传递的文件名并返回指定的文件 file name request path params file file open file name rb m
  • Clojure 应用映射和关键字参数销毁

    考虑具有以下签名的函数 defn make widget keys x y or x 10 y 20 将映射传递给函数的最佳方法是什么 例如 make widget x 100 or make widget y 200 x 0 我目前想到的
  • 正则表达式来验证逗号分隔的电子邮件地址?

    我需要验证电子邮件地址 可以是单个或多个以逗号分隔的地址 在我在正则表达式验证器中使用如下表达式之前 string exp w w w w w w 它正在验证多个或一个电子邮件地址 但同样的表达式在 C 中没有验证 它也表示对无效地址有效
  • IIS7-请求过滤模块配置为拒绝超过请求内容长度的请求

    我想上传图像 它在我的机器上运行良好 但是当我将我的网站放在 IIS7 服务器上供公众使用时 我无法上传任何内容 Error 请求过滤模块 用于拒绝以下请求 超过请求内容长度 最可能的原因 在Web服务器上配置请求过滤以拒绝请求 因为内容长
  • 如何为编辑操作指定 devise_parameter_sanitizer?

    我已将 Devise 添加到我的 Rails 4 应用程序中 并成功将用户名等添加到我的用户模型中 此外 我可以使用惰性方式存储这些字段 即 class ApplicationController lt ActionController B
  • libGDX:用一些枢轴打结的吊绳

    我正在尝试在 libGDX 中制作一根在其下端有一些物体的悬挂绳 绳子应该是这样的Box2D中的挂绳 http www emanueleferonato com 2009 10 05 basic box2d rope 我做了很多研究 lib
  • 如何让外部合并工具在 Linux 上与 svn 一起工作?

    如何获得基于 GUI 的合并工具以在 Linux 中使用命令行 SVN 我知道有很多选项 例如 meld svn Diff 等 所有这些都需要一个帮助程序脚本来允许 svn 在冲突解决期间调用外部程序 我按照给出的说明进行操作here ht
  • 将 WebRTC 与 WebWorker 结合使用

    我有兴趣将 webrtc 与 webworker 一起使用 是否可以 我尝试了 但没有成功 因为它没有找到 窗口 根据规格 1 https w3c github io mediacapture main dom navigator 2 ht
  • Apple 无法识别 imgur 的 HTTPS

    我有多个来自 imgur 的 HTTPS 链接 例如https i stack imgur com 9nSMi jpg https i stack imgur com 9nSMi jpg 我使用它作为我的原型应用程序的背景之一 但每当我在
  • WPF ComboBox...如何设置.Text 属性?

    有没有办法设置 Text直接使用 Wpf ComboBox 控件的属性吗 我的组合框绑定到List
  • 如何组合 Raphael javascript 库中的对象?

    抱歉问了一个很长的问题 但是就这样吧 我正在尝试修改此处演示周围的拖动形状 http raphaeljs com graffle html http raphaeljs com graffle html 该演示运行良好 我想做的是将文字放入