替换reveal.js中的图片

20
假设我有两张非常相似的图片需要依次显示(比如第一张是照片,第二张是同样的照片但高亮了某些区域)。我想避免过渡动画,只让第二张图片替换第一张图片。在使用reveal.js时,这种做法可行吗?
设置data-transition="none"效果不佳,因为之前的幻灯片仍保留其动画。
6个回答

12

Reveal.js本身没有直接完成所要求工作的方法。但是,可以使用

容器和reveal.js的fragment功能来实现。容器包含图片,这些图片在其中绝对定位,因此必须具有固定的尺寸。

下面的HTML代码片段显示第一张图片,下一张幻灯片将在第一张图片上方显示第二张图片。

<section>
<h1>Slide 1</h1>
<div style="position:relative; width:640px; height:480px; margin:0 auto;">
  <img class="fragment" width="640" height="480" src="img1.jpg" style="position:absolute;top:0;left:0;" />
  <img class="fragment" width="640" height="480" src="img2.jpg" style="position:absolute;top:0;left:0;" />
</div>
</section>

这段 HTML 显示第一张图片,然后在下一张幻灯片中,第一张图片淡出,第二张图片淡入。

<section>
<h1>Slide 2</h1>
<div style="position:relative; width:640px; height:480px; margin:0 auto;">
  <img class="fragment fade-out" data-fragment-index="0" width="640" height="480" src="img1.jpg" style="position:absolute;top:0;left:0;" />
  <img class="fragment fade-in" data-fragment-index="0" width="640" height="480" src="img2.jpg" style="position:absolute;top:0;left:0;" />
</div>
</section>

1
使用 position:absolute 会导致 Reveal 3 的 PDF 导出出现问题。 - Geoffrey De Smet

11

reveal.js 4.0 推出了一个新的r-stack类,使得将元素堆叠在彼此之上更加容易。

<div class="r-stack">
  <img class="fragment" src="https://placekitten.com/450/300" width="450" height="300">
  <img class="fragment" src="https://placekitten.com/300/450" width="300" height="450">
  <img class="fragment" src="https://placekitten.com/400/400" width="400" height="400">
</div>

上面的例子在彼此之上淡入图像。如果你只想一次显示一张图片,你需要使用稍微不同的片段设置。

<div class="r-stack">
  <img class="fragment current-visible" src="...">
  <img class="fragment current-visible" src="...">
  <img class="fragment" src="...">
</div>

您可以在reveal.js文档https://revealjs.com/layout/#stack中看到此项功能的示例。


1
感谢@hakim添加了这个功能,并在此处提供了很好的总结! - Jonathan W.

2

另一个可能的解决方案是使用Javascript。使用此代码,您不仅可以替换图像,还可以替换任何内容。

重要的是应用类content-targetcontent-source。同样重要的是使用display: none;样式。

HTML可能如下所示:

<section>
    <h3>Headline</h3>
    <div class="content-target"></div>
    <div style="display: none;">
        <div class="content-source fragment" data-fragment-index="0">
            <img src="path/to/image.jpg" />
            <p>Some text</p>
        </div>
        <div class="content-source fragment" data-fragment-index="1">
            <ul>
                <li>List item 1</li>
                <li>List item 2</li>
            </ul>
        </div>
        <div class="content-source fragment" data-fragment-index="2">
            <img src="path/to/another/image.jpg" />
        </div>
    </div>
</section>

现在我们添加一个名为fadeContent()的函数,并在每次触发fragmentshownfragmenthidden时调用它。请注意保留html标签。
function fadeContent($el, back=false) {
    // If we go back, choose previous element, otherwise current element
    $new = (back ? $el.prev() : $el);
    if($new.length == 0) {
        $text = $el.parent().siblings('.content-target');
        $text.fadeOut(200);
    } else {
        $text = $new.parent().siblings('.content-target');
        $text.hide(0, function() {
            $text.html($new.html());
            $text.fadeIn(300);
        });
    }
}

Reveal.addEventListener('fragmentshown', function(event) {
    // Get first fragment which has "content-source" class
    var $el = $($(event.fragments).filter(function() {
        return $(this).hasClass('content-source')
    })[0]);

    // Show content
    if ($el.hasClass('content-source'))
        fadeContent($el);
});

Reveal.addEventListener('fragmenthidden', function(event) {
    // Get first fragment which has "content-source" class
    var $el = $($(event.fragments).filter(function() {
        return $(this).hasClass('content-source')
    })[0]);

    // Hide element
    if ($el.hasClass('content-source'))
        fadeContent($el, back=true);
});

由于我们刚刚扩展了片段功能,因此仍然可以使用data-fragment-index属性并更改顺序。

该解决方案可以轻松进行优化/定制。


我已经更新和改进了答案,你可以再试一次吗? - sagacity

1
你可以指定两个转换,一个用于进入,一个用于离开,因此以下代码可以工作,但有一个小问题(当出现时图像会闪烁):
<section data-transition="slide none">
  <img src="timeline2.a.svg">
</section>
<section data-transition="none">
  <img src="timeline2.b.svg">
</section>
<section data-transition="none side">
  <img src="timeline2.c.svg">
</section>

否则,这也可能是一个解决方案,它与您想要的有些不同,但并不差。
<section data-transition="slide fade-out">
  <img src="timeline2.a.svg">
</section>
<section data-transition="fade-in fade-out">
  <img src="timeline2.b.svg">
</section>
<section data-transition="fade-in side">
  <img src="timeline2.c.svg">
</section>

0
它对我来说在嵌套片段中起作用 在外面,我有一个带有类名r-stack的div
<div class="fragment" data-fragment-index="1">
                    <img class="fragment fade-out" data-fragment-index="2" src="https://http.cat/418" width="50%">
                  </div>
                  <div class="fragment" data-fragment-index="2">
                    <img class="fragment fade-out" data-fragment-index="3" src="https://http.cat/404" width="50%">
                  </div>
                  <div class="fragment" data-fragment-index="3">
                    <img class="fragment fade-out" data-fragment-index="4" src="https://http.cat/100" width="50%">
                  </div>
                  <div class="fragment" data-fragment-index="4">
                    <img src="https://http.cat/420" width="50%">
                  </div>



-2
假设您正在使用data-background来显示您的照片,那么您需要使用data-background-transition="none"来实现所需的效果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接