SVG和RevealJS中的鼠标位置

时间:2017-12-23 01:23:09

标签: javascript svg reveal.js

我正在使用RevealJS创建演示文稿,并希望合并使用D3创建的一些交互式SVG可视化。我之前已经多次没有遇到过这种情况,但这次我遇到了一些困难。经过一些调试后,我已将问题跟踪到以下内容:由于某种原因,当整个东西被包裹在RevealJS中时,相对于SVG的鼠标位置没有正确报告。

我原始版本的代码使用标准D3技术来获取鼠标位置。然而,为了简化和隔离问题,我删除了D3,现在使用vanilla Javascript来获取this StackOverflow answer中详述的鼠标位置。我的代码(作为stack-snippet实现)看起来像这样:



var info =  document.getElementById("info");
var svg =  document.getElementById("svg");
pt = svg.createSVGPoint();
var cursorPoint = function(evt){
  pt.x = evt.clientX; pt.y = evt.clientY;
  return pt.matrixTransform(svg.getScreenCTM().inverse());
}
svg.addEventListener('mousemove',function(evt){
  var loc = cursorPoint(evt);
  info.textContent = "(" + loc.x + ", " + loc.y +   ")";
},false);

svg {
  border: solid black 1px;
  border-radius: 8px;
}

<div id="info">pos</div>
<svg id="svg" width="300" height="200"></svg>
&#13;
&#13;
&#13;

当我在Mac上的Firefox中的RevealJS中运行它时,我得到了非常不同的数字 - 好像坐标已被移位(-423,-321)或其他一些大的负数字。我在下面添加了一个屏幕截图来说明这一点。鼠标没有出现在屏幕截图中,但是在左上角附近,所以它应该读取类似(3,5)或类似的小值。

enter image description here

我认为RevealJS正在对SVG进行一些额外的转换,但是我无法找到它,我希望有一些RevealJS推荐的方法来处理这个问题。

RevealJS version here有一个完整的(好的,实际上没有正确的)版本。它与上面的stack-snippet中的代码完全相同,但是包含在最小的RevealJS模板中。

更深入地研究这个问题,问题似乎发生在Firefox上,而不是Chrome。我在我1岁的Macbook Pro上运行这些程序的当前版本。我真的很喜欢一些适用于各种浏览器的代码,并且肯定希望它能够在Firefox和Chrome中运行。

1 个答案:

答案 0 :(得分:5)

请注意使用CSS tranforms创建幻灯片动画是多么优雅,但它不是最可靠的显示方法,因为它会在浏览器中产生不一致的结果,我想你会做一些事情那些坐标稍后,你可能需要有一个精确的鼠标指针位置。

reveal.js中发生了意想不到的事情 基本上,使用scaletranslate,SVG元素向右移动并缩放,但指针的坐标就好像您的原始位置和大小区域相对于当前布局进行计算,因此负值,请看一下图片。

enter image description here

所以我从layout()中的reveal.js函数中移除了这一行:

transformSlides( { layout: 'translate(-50%, -50%) scale('+ scale +')' } );

用于居中元素。有一套 Firefox和Chrome的语句(无需检查features.zoomlayout()函数中)我想水平居中滑动元素:

dom.slides.style.left = '0';
dom.slides.style.top = 'auto';
dom.slides.style.bottom = 'auto';
dom.slides.style.right = '0';

&#13;
&#13;
Reveal.initialize({});
var info = document.getElementById("info");
var svg = document.getElementById("svg");
pt = svg.createSVGPoint();
var cursorPoint = function(evt) {
  pt.x = evt.clientX;
  pt.y = evt.clientY;
  return pt.matrixTransform(svg.getScreenCTM().inverse());
}
svg.addEventListener('mousemove', function(evt) {
  var loc = cursorPoint(evt);
  info.textContent = "(" + loc.x + ", " + loc.y + ")";
}, false);
&#13;
svg {
  background-color: white;
  border: solid black 1px;
  border-radius: 8px;
}
&#13;
<script src="https://cdn.rawgit.com/Nasdav/revealjs-for-SO-answer/b6ea3980/reveal.js"></script>

<script src="https://cdn.rawgit.com/hakimel/reveal.js/master/lib/js/head.min.js"></script>
<link rel="stylesheet" href="https://cdn.rawgit.com/hakimel/reveal.js/65bdccd5807b6dfecad6eb3ea38872436d291e81/css/reveal.css">
<link rel="stylesheet" href="https://cdn.rawgit.com/hakimel/reveal.js/65bdccd5807b6dfecad6eb3ea38872436d291e81/lib/css/zenburn.css">
<link rel="stylesheet" href="https://cdn.rawgit.com/hakimel/reveal.js/65bdccd5807b6dfecad6eb3ea38872436d291e81/css/theme/sky.css" id="theme">

<body>

  <div class="reveal">
    <div class="slides">
      <section>
        <h2 style="font-size:150%">Mouse position in RevealJS</h2>
        <p style="font-size:75%">
          Make sure to click "full page" at the right most side of "Run Code Snippet". Then hover over the SVG below to get the "position" of the mouse in the SVG. The position is obtained using a standard javascript technique and works fine in
          <a href="non_reveal_version.html">this non-reveal version</a>. For some reason though. The values are correct now in Firefox when RevealJS is present. It works well in Chrome, though.
        </p>
        <svg id="svg" width="300" height="200"></svg>
        <div id="info">pos</div>
      </section>
    </div>
  </div>
&#13;
&#13;
&#13;

问题解决了你有一个可靠的方法来获得鼠标指针的坐标,这些坐标一直在SVG区域的Chrome,Firefox甚至Internet Explorer中(0,0)到(300,200)

在这里,如果您希望幻灯片具有与前一个(稍大)相同的大小和/或响应调整大小,那么坐标会稍微不准确:在与前一代码相同的位置,我会让宽度和字体大小有百分比(我可以这样做SVG本身,这里有一个固定的大小)

dom.slides.style.width = '90%';
dom.slides.style.fontSize= scale*100+'%';