js的attr函数设置错误的值
Raphael.js attr function sets wrong value
我正在使用拉斐尔.js实现一个拖放系统。为此,我将原始x和y位置存储在mousedown上,如果在mouseup上发生碰撞,我想将位置重置为原始位置。下面是进行重置的代码位("this"指的是这里的raphael对象):
var transformString = "t" + this.original_x + "," + this.original_y;
this.attr("transform", transformString);
奇怪的是,在设置属性后,转换字符串改变了几个像素。我用:
来调试它 var transformString = "t" + this.original_x + "," + this.original_y;
this.attr("transform", transformString);
console.log("transformString: " + transformString);
console.log("transformAttrib: " + this.attr("transform"));
在任何情况下,两个记录的值都应该相等。但有时会相差20像素。有人知道这是怎么回事吗?
E:这里是一个简化的版本,没有碰撞测试,仍然会重现错误:http://jsfiddle.net/6ozsfdaf
我不知道为什么会发生这种情况。我甚至尝试使用onmousedown
事件捕获onstart
之前的坐标,即使这样也不起作用。Raphael提供了不同的方法来获得getBBox()
的坐标,直接访问x
和y
,没有帮助。
original_x
和original_y
变量,它们捕获了<path>
的位置,在你创建和设置一些转换值之后。下面是相同的
的代码这是工作小提琴。
this.raph = R.path(svgPath).attr({
stroke: "hsb(0, 1, 1)",
fill: "#fff",
opacity: 1.0,
cx: 100,
cy: 900
}).transform("t" + x + "," + y);
this.raph.original_x = x;
this.raph.original_y = y;
//comment the lines in start method which captures original_x and original_y
//this.original_x = Raphael.parseTransformString(this.attr("transform"))[0][1];
//this.original_y = Raphael.parseTransformString(this.attr("transform"))[0][2];
关于跟踪坐标的更多信息:
我们将有一个坐标说updated_x
和updated_y
,这将在move
方法中更新。onFinish/onUp方法,我们可以检查是否应该更新新位置。这里,它只是询问是否应该更新新位置,并根据我们的输入设置最终结果。
检查这个小提琴:
this.start = function() {
if (this.reference.static) return;
//this.original_x = Raphael.parseTransformString(this.attr("transform"))[0][1];
//this.original_y = Raphael.parseTransformString(this.attr("transform"))[0][2];
this.animate({r: 70, opacity: 0.25}, 500, ">");
this.updated_x = this.original_x;
this.updated_y = this.original_y;
};
this.move = function(dx, dy) {
//var ts = Raphael.parseTransformString(this.attr("transform"));
this.updated_x = this.original_x + dx;
this.updated_y = this.original_y + dy;
//ts[0][1] = this.original_x + dx;
//ts[0][2] = this.original_y + dy;
this.attr({transform: 't' + this.updated_x + ',' + this.updated_y});
};
this.up = function() {
if(confirm("Shall I update the new position??")) {
this.original_x = this.updated_x;
this.original_y = this.updated_y;
}
var transformString = "t" + this.original_x + "," + this.original_y;
this.attr("transform", transformString);
this.attr({fill: "#fff"});
this.animate({r: 50, opacity: 1}, 500, ">");
};
我不太确定为什么会出现这个问题,但我想知道这是否可能是一个更好的解决方案。而不是每次解析字符串,只是存储转换并使用它。
我还将其切换为使用transform()方法,而不是attr(transform:..)方法。虽然我认为这通常会起作用,但在逻辑上并不完全正确,因为SVG属性不采用Raphael转换字符串,但我认为Raph会拦截并处理它(但可能更容易出错)。
在转换字符串中't'是一个相对变换,'t'是一个绝对变换(我不认为这是问题,因为没有之前的变换,但我想知道它是否也相关)。
this.start = function() {
if (this.reference.static) return;
this.original_t = this.transform();
this.animate({r: 70, opacity: 0.25}, 500, ">");
};
this.move = function(dx, dy) {
this.transform( this.original_t + 't' + dx + ',' + dy);
};
this.up = function() {
this.transform( this.original_t );
console.log("transformString: " + this.original_t);
console.log("transformAttrib: " + this.transform());
this.attr({fill: "#fff"});
this.animate({r: 50, opacity: 1}, 500, ">");
};
jsfiddle
发现了一个有趣的修复:如果您在这两个选项中都添加一个epsilon,则可以避免这种情况。Original_x和this.original_y。如果这样,问题似乎就消失了。Original_x和这个。Original_y与起始坐标不完全相同。查看:http://jsfiddle.net/6ozsfdaf/13/
this.up = function() {
var ts;
this.original_x += 0.0000000001;
this.original_y += 0.0000000001;
var transformString = "t" + this.original_x + "," + this.original_y;
this.attr("transform", transformString);
console.log("transformString: " + transformString);
console.log("transformAttrib: " + this.attr("transform"));
this.attr({fill: "#fff"});
this.animate({r: 50, opacity: 1}, 500, ">");
};
编辑找到问题了。在Raphael中,Raphael. parsetransformstring()的输出被缓存并重用。在move()方法中,您修改了Raphael. parsetransformstring()的输出,当您为Raphael提供相同的字符串时,它会尝试使用您修改过的数组。这在注册第一个drag()事件时发生。您要求它解析当前位置,然后用新位置更新数组的输出数组。然后,很久以后,当this.up()被调用时,你为Raphael.parseTransformString()提供相同的字符串。Raphael然后使用你修改过的数组的数组。这是固定的小提琴:http://jsfiddle.net/6ozsfdaf/16/
下面是代码(每次移动时使用一个新的数组数组来转换):
this.move = function(dx, dy) {
var ts = [];
ts.push(new Array('t'));
ts[0][1] = this.original_x + dx;
ts[0][2] = this.original_y + dy;
this.attr({transform: ts.toString()});
};
- 可以设置“;文件名"发生错误时显示的内联脚本标记的
- NodeJS错误-Can't在发送标头后设置标头
- 错误:Can't在从forEach循环发送标头后设置标头
- 未捕获的类型错误:无法设置属性'innerHTML'如果为null,则将脚本移动到正文不会;不起作用
- PhantomJS(vs nightwatch.js)设置cookie错误
- 未捕获的类型错误:无法设置属性'背景'的未定义
- Express 4错误:Can't在发送标头后设置标头
- 任何人都知道IE7设置或更新/补丁,它可以防止IE因为jquery错误而无法加载页面
- JavaScript数组值设置错误
- 当张贴到数据库时,I'我得到了一个“;可以't在它们被发送错误之后设置报头”;
- Javascript设置日期不起作用,显示错误的时间
- NodeJS未处理的拒绝错误:Can't在发送标头后设置标头
- 未捕获的类型错误:无法设置属性'onclick'为null.已尝试window.onload
- 未捕获类型错误:无法设置未定义的属性“操作”
- 节点.js未捕获的异常类型错误:无法设置未定义的预处理 ''
- 谷歌地图:- 无效值错误:设置图标:不是字符串;并且没有网址属性;并且没有路径属性
- Json字符串如果键错误设置显示.否则显示数据
- jquery数据表的Javascript语法错误设置属性
- ES6 /巴别塔传播错误设置
- 创建图像元素,然后通过javascript错误设置样式属性