对于产生许多图形的
knitr
块,我想要一个幻灯片而不是一长串图像,类似于this。
我遇到了
fig.show='animate'
,这还可以,但速度很慢,而且是一部电影而不是单个图像。
下面的解决方案也可以,但我想要一些适用于
self_contained: yes
的解决方案,这样我就不必单独保留图像。我对html了解不够,但“自包含”图像只是源代码中的长字符串,我不知道如何使用。
还感觉构建图像的文件路径有点hacky。
--- R 降价
---
output:
html_document:
self_contained: no
---
```{r, fig.show='animate'}
tmp <- lapply(names(mtcars)[-1L], function(x) {
plot(reformulate(x, 'mpg'), mtcars, main = 'fig.show=\'animate\'')
})
```
```{r, fig.show='hide'}
oo <- knitr::opts_current$get()
tmp <- lapply(names(mtcars)[-1L], function(x) {
plot(reformulate(x, 'mpg'), mtcars, main = 'slideshow')
})
```
```{r, echo=FALSE}
slideshow <- function(img, caption = basename(img)) {
# cat(slideshow(c('img1.jpg', 'img2.jpg')))
p <- function(...) {
paste0(..., collapse = '')
}
slide <- function(img, caption = '') {
caption <- rep_len(caption, length(img))
single <- '
<div class="mySlides">
<div class="numbertext">%s / %s</div>
<img src="%s" style="width: 100%%">
<div class="text">%s</div>
</div>
'
sprintf(single, seq_along(img), length(img), img, caption)
}
dots <- sprintf('\n<span class="dot" onclick="currentSlide(%s)"></span>',
seq_along(img)
)
div <- '
<div class="slideshow-container">
%s
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br />
<div style="text-align: center">
%s
</div>
'
structure(sprintf(div, p(slide(img, caption)), p(dots)), class = 'html')
}
fp <- sprintf('%s-%s.%s', file.path(oo$fig.path, oo$label), seq_along(tmp), oo$dev)
slideshow(fp)
```
<!--
https://www.w3schools.com/howto/howto_js_slideshow.asp
-->
<style>
* {box-sizing:border-box}
/* slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* hide the images by default */
.mySlides {
display: none;
}
/* next & previous buttons */
.prev, .next {
cursor: pointer;
position: absolute;
bottom: 0%;
width: auto;
margin-top: 0px;
padding: 16px;
color: #7f7f7f;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
/* position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* on hover add black background color with transparency */
.prev:hover, .next:hover {
background-color: rgba(127,127,127,0.8);
color: white;
}
/* caption text */
.text {
color: #7f7f7f;
font-size: 22px;
padding: 0px 0px;
position: absolute;
bottom: -10px;
width: 100%;
text-align: center;
}
/* number text (1/3, 2/3, etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* dots/bullets/indicators */
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active, .dot:hover {
background-color: #7f7f7f;
}
</style>
<script>
let slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
let i;
let slides = document.getElementsByClassName("mySlides");
let dots = document.getElementsByClassName("dot");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
}
</script>
--- 产生这个
表示图像的长字符串称为base64编码。您可以使用包 base64enc.
从图像生成这样的字符串。要在 Rmarkdown 文档中包含幻灯片,您可以使用包 swipeR 或包 slickR。下面是一个使用 swipeR 的示例。我在子文件夹“www”中有四个“png”图像。
---
title: "Using 'swipeR' in Rmarkdown"
output: html_document
date: "2023-11-16"
---
```{r setup, include=FALSE}
library(swipeR)
library(htmltools)
library(base64enc)
```
```{r, echo=FALSE}
# base64 encoding of the images
b64_1 <- dataURI(file = "www/img1.png", mime = "image/png")
b64_2 <- dataURI(file = "www/img2.png", mime = "image/png")
b64_3 <- dataURI(file = "www/img3.png", mime = "image/png")
b64_4 <- dataURI(file = "www/img4.png", mime = "image/png")
```
```{r, echo=FALSE}
# carousel
wrapper <- swipeRwrapper(
tags$img(src = b64_1, style = "width: 400px; margin: auto;"),
tags$img(src = b64_2, style = "width: 400px; margin: auto;"),
tags$img(src = b64_3, style = "width: 400px; margin: auto;"),
tags$img(src = b64_4, style = "width: 400px; margin: auto;")
)
swipeR(wrapper, height = "400px", navigationColor = "navy")
```