我有一些代码在光标位置上方显示一个 SVG 项目。我注意到如果对象只是落后一帧,那么它比我预期的要落后于光标。
var width = 600,
height = 200;
var mouseLocation = [0,0];
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var cursor = svg.append('circle')
.attr("r", 2)
.attr("fill", 'darkblue');
// update mouse location
d3.select(window).on("mousemove", () => {
mouseLocation = d3.mouse(svg.node());
});
// show mouse
d3.timer(function() {
cursor.attr("transform", 'translate(' + mouseLocation + ')');
});Run Code Online (Sandbox Code Playgroud)
<script src="http://d3js.org/d3.v4.min.js"></script>Run Code Online (Sandbox Code Playgroud)
您可以通过将鼠标从一侧平滑地滑动到另一侧来查看延迟。蓝色圆圈稍微落后于光标。(至少在 Windows 上的 Chrome 57 上)
我尝试了几种变体,包括在 mousemove 回调函数中调用 circle.attr 。但总有一点延迟。
编辑我尝试失败的事情:
mousemove事件中设置光标变换mousemove调用以来经过的时间,仅每 16 毫秒更新一次。svg.style("shape-rendering", "optimizeSpeed");mousemove事件用于 svg 而不是窗口d3.event.pageXandd3.event.pageY而不是d3.mouse(svg.node())<canvas> 在这个答案的第一个版本中(查看编辑历史记录)我尝试了d3.interval和setInterval,没有区别。
然而,我相信,也许这个问题没有答案(从OP想要的意义上来说),因为延迟取决于D3处理事件mousemove。这里的问题也可能与 D3 无关,而是取决于用户代理(浏览器)如何控制事件mousemove频率。
如果我们将移动圆的代码放在该mousemove函数中,就可以看出这一点:
d3.select(window).on("mousemove", () => {
mouseLocation = d3.mouse(svg.node());
cursor.attr("transform", 'translate(' + mouseLocation + ')');
});
Run Code Online (Sandbox Code Playgroud)
并且滞后仍然是相同的:
d3.select(window).on("mousemove", () => {
mouseLocation = d3.mouse(svg.node());
cursor.attr("transform", 'translate(' + mouseLocation + ')');
});
Run Code Online (Sandbox Code Playgroud)
var width = 600,
height = 200;
var mouseLocation = [0,0];
var svg = d3.select("div").append("svg")
.attr("width", width)
.attr("height", height);
var cursor = svg.append('circle')
.attr("r", 2)
.attr("fill", 'darkblue');
// update mouse location
d3.select("div").on("mousemove", () => {
cursor.attr("transform", 'translate(' + (d3.event.pageX - 16) + "," + (d3.event.pageY - 16) + ')');
});Run Code Online (Sandbox Code Playgroud)