【问题标题】:Mouse position in SVG and RevealJSSVG 和 RevealJS 中的鼠标位置
【发布时间】:2023-03-31 12:08:01
【问题描述】:

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

我的原始代码版本使用标准 D3 技术来获取鼠标位置。不过,为了简化和隔离问题,我删除了 D3,现在使用 vanilla Javascript 来获取鼠标位置,详见 this StackOverflow answer。我的代码(实现为 stack-sn-p)如下所示:

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>

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

我假设 RevealJS 正在 SVG 上执行一些额外的转换,但我找不到它,我希望有一些 RevealJS 推荐的方法来处理这个问题。

RevealJS version here 有一个完整的工作版本(嗯,实际上并不正确)。它与上面的 stack-sn-p 中的代码几乎完全相同,但包装在一个最小的 RevealJS 模板中。


更仔细地研究一下,这个问题似乎发生在 Firefox 上,但没有发生在 Chrome 上。我在我 1 岁的 Macbook Pro 上运行这些程序的当前版本。我真的很想要一些可以在各种浏览器中运行的代码,并且肯定希望它可以在 Firefox 和 Chrome 中运行。

【问题讨论】:

  • 你说的“非常不同的数字”是什么意思?我得到了几乎相同的东西......实际上,如果你只是给我看两个代码而不说有问题,我什至不会注意到差异。
  • @GerardoFurtado 好问题 - 谢谢。我已经编辑了我的帖子,希望更清楚。您的问题让我意识到我应该检查它在另一个浏览器中的工作方式。问题出现在我 Mac 上的 Firefox 中,但不在 Chrome 中。
  • 这很有趣,我没有得到那些负值......正如我所说,我得到的几乎一样。
  • @GerardoFurtado 您没有使用 Firefox 获得这些负值吗?你在 Mac 上吗?还是电脑?
  • 我在PC上,Windows 7 64bit,Chrome 63。这是截图,鼠标几乎在左上角:snag.gy/rJ0cBF.jpg

标签: javascript svg reveal.js


【解决方案1】:

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

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

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

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';

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);
svg {
  background-color: white;
  border: solid black 1px;
  border-radius: 8px;
}
<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>

问题解决了,您有一种可靠的方法可以在 Chrome、Firefox 甚至 Internet Explorer 的 SVG 区域中从 (0,0) 到 (300,200) 始终如一地获取鼠标指针的坐标

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

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

【讨论】:

    猜你喜欢
    • 2010-10-15
    • 2014-07-16
    • 1970-01-01
    • 2012-05-05
    • 2018-10-18
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多