在d3.js中拖放时防止“重影”图像

时间:2011-10-21 02:00:44

标签: javascript drag-and-drop d3.js

当我用d3.js在画布上拖动形状时,任何人都有充分的理由看到重影吗?屏幕截图示例:

ghosting as you drag SVG shapes

这是代码(coffeescript,我发现它更容易阅读和写入):

canvas = d3.select("#canvas").append("svg:svg")
  .attr("width","100%")
  .attr("height","100%")

# patterns
defs = canvas.append("svg:defs")
for c in ["cream","leaf","cardinal-red","baltic-blue","black","brittany-blue","cardinal-red","fern","graphite","green-grape"]
  defs.append("svg:pattern").attr("id","p-tile-#{c}")
    .attr('patternUnits', 'userSpaceOnUse')
    .attr("width",72)
    .attr("height",72)
    .append("svg:image")
      .attr("width",72)
      .attr("height",72)
      .attr("xlink:href", "img/sw-#{c}.jpg")

#body
body = canvas.append("svg:rect")
  .attr("width","500")
  .attr("height","250")
  .attr("rx",30)
  .attr("ry",30)
  .attr("x",20)
  .attr("y",20)
  .attr("fill","url(#p-tile-fern)")
canvas.append("svg:rect")
  .attr("width","50")
  .attr("height","65")
  .attr("rx",25)
  .attr("ry",25)
  .attr("x",460)
  .attr("y",30)
  .attr("fill","#fff")

# left eye
leye = canvas.append("svg:svg")
leye.attr("x",100).attr("y",30)
g = leye.append("svg:g")

g.append("svg:circle")
      .attr("cx",50)
      .attr("cy",50)
      .attr("r",50)
      .attr("fill","url(#p-tile-cream)")
g.append("svg:circle")
        .attr("cx",30)
        .attr("cy",75)
        .attr("r",10)
        .attr("fill","url(#p-tile-cardinal-red)")

leye.call(d3.behavior.drag()
  .on("dragstart", ->
    @.__o = [@x.baseVal.value,@y.baseVal.value]
    )
  .on("drag", () ->
    @.x.baseVal.value += d3.event.dx
    @.y.baseVal.value += d3.event.dy
  )
  .on("dragend", -> delete @.__o )
)

以下是为记录创建的JS:

(function() {
  var body, c, canvas, defs, g, leye, _i, _len, _ref;
  canvas = d3.select("#canvas").append("svg:svg").attr("width", "100%").attr("height", "100%");
  defs = canvas.append("svg:defs");
  _ref = ["cream", "leaf", "cardinal-red", "baltic-blue", "black", "brittany-blue", "cardinal-red", "fern", "graphite", "green-grape"];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    c = _ref[_i];
    defs.append("svg:pattern").attr("id", "p-tile-" + c).attr('patternUnits', 'userSpaceOnUse').attr("width", 72).attr("height", 72).append("svg:image").attr("width", 72).attr("height", 72).attr("xlink:href", "img/sw-" + c + ".jpg");
  }
  body = canvas.append("svg:rect").attr("width", "500").attr("height", "250").attr("rx", 30).attr("ry", 30).attr("x", 20).attr("y", 20).attr("fill", "url(#p-tile-fern)");
  canvas.append("svg:rect").attr("width", "50").attr("height", "65").attr("rx", 25).attr("ry", 25).attr("x", 460).attr("y", 30).attr("fill", "#fff");
  leye = canvas.append("svg:svg");
  leye.attr("x", 100).attr("y", 30);
  g = leye.append("svg:g");
  g.append("svg:circle").attr("cx", 50).attr("cy", 50).attr("r", 50).attr("fill", "url(#p-tile-cream)");
  g.append("svg:circle").attr("cx", 30).attr("cy", 75).attr("r", 10).attr("fill", "url(#p-tile-cardinal-red)");
  leye.call(d3.behavior.drag().on("dragstart", function() {
    return this.__o = [this.x.baseVal.value, this.y.baseVal.value];
  }).on("drag", function() {
    this.x.baseVal.value += d3.event.dx;
    return this.y.baseVal.value += d3.event.dy;
  }).on("dragend", function() {
    return delete this.__o;
  }));
}).call(this);

1 个答案:

答案 0 :(得分:1)

看起来像WebKit的模式实现的重绘错误 - 脏区域(眼睛在最新的鼠标移动之前)未正确重绘。您应该针对WebKit提交错误。在此期间,您可以使用HTML和背景图像样式而不是使用SVG模式来解决此问题。

您也可以尝试this.setAttribute(“x”,...)或d3.select(this).attr(“x”,...)而不是分配给this.x.baseVal.value,但它不太可能这将解决重绘错误。