Compare commits
281 Commits
magic-pyth
...
bddeb70f4e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bddeb70f4e | ||
|
|
1e1e228680 | ||
|
|
11680561e9 | ||
|
|
9d1c7e21b6 | ||
|
|
010f06c339 | ||
|
|
eee0a4ff24 | ||
|
|
d14084d4a4 | ||
|
|
30eddd95ed | ||
|
|
b6a3ea82e1 | ||
|
|
b2d0a3f70c | ||
|
|
73d3f3432f | ||
|
|
09b22cee6c | ||
|
|
97d73bd3dc | ||
|
|
790fd8c29a | ||
|
|
2518301d3e | ||
|
|
89bf44ba92 | ||
|
|
adfa3462cc | ||
|
|
68efdf6b03 | ||
|
|
cc640a21d3 | ||
|
|
c594f9c6ec | ||
|
|
942be4ee42 | ||
|
|
c23964274c | ||
|
|
e46bad392a | ||
|
|
ff252c984f | ||
|
|
0072845828 | ||
|
|
5b537aa8f8 | ||
|
|
aa5c03c234 | ||
|
|
ff3244af7a | ||
|
|
49c0030392 | ||
|
|
51acc830f9 | ||
|
|
cc9a36dc25 | ||
|
|
a9031821ef | ||
|
|
c1d64ad8d0 | ||
|
|
57ce5a5e3d | ||
|
|
c4e322ce79 | ||
|
|
836967d8ab | ||
|
|
28ef437a89 | ||
|
|
c80b685a88 | ||
|
|
7108476911 | ||
|
|
b8b55b8d4c | ||
|
|
a7d0916f28 | ||
|
|
198cbc4ace | ||
|
|
d802789c4d | ||
|
|
c1b1745200 | ||
|
|
980b902a9d | ||
|
|
be5d811914 | ||
|
|
122642fdea | ||
|
|
09f36adc70 | ||
|
|
2c5a83c945 | ||
|
|
a6abd0423e | ||
|
|
234799114a | ||
|
|
f80ee3b917 | ||
|
|
1871824fae | ||
|
|
1f1ca3a887 | ||
|
|
d84aa3472e | ||
|
|
ab52d334df | ||
|
|
42a1844d27 | ||
|
|
899a45dff6 | ||
|
|
3db2340df3 | ||
|
|
88fbfc5751 | ||
|
|
c856fa9db1 | ||
|
|
4c9cc89566 | ||
|
|
97f2e184c1 | ||
|
|
e49e89a557 | ||
|
|
f0950ba9ae | ||
|
|
0861b07618 | ||
|
|
5de7da7692 | ||
|
|
db2523db27 | ||
|
|
eb01f8f3a5 | ||
|
|
cd948d4136 | ||
|
|
07a6cf1249 | ||
|
|
4da6f6b30f | ||
|
|
eaf5f61318 | ||
|
|
0f27ef40fb | ||
|
|
f26d31570e | ||
|
|
a4b7f9dff7 | ||
|
|
6aa1eae796 | ||
|
|
487cc860f8 | ||
|
|
c5307462b0 | ||
|
|
fc16cc8b11 | ||
|
|
03fe25c1f6 | ||
|
|
81ea116292 | ||
|
|
3a830dd98f | ||
|
|
777e2a2d05 | ||
|
|
680cf5edb8 | ||
|
|
edf6638065 | ||
|
|
a1d0cdffc4 | ||
|
|
064b3c3aa5 | ||
|
|
2ab0689aa3 | ||
|
|
75c0be853c | ||
|
|
ccbaffc975 | ||
|
|
bae6de87ec | ||
|
|
9babaa005f | ||
|
|
af1cd9d6a4 | ||
|
|
a3f71b4a9b | ||
|
|
58881061ab | ||
|
|
e1c180565e | ||
|
|
b8d97d2537 | ||
|
|
74a5dac34f | ||
|
|
f2b0316a91 | ||
|
|
92ee97fbfe | ||
|
|
da5682ce51 | ||
|
|
f4e1a8ef50 | ||
|
|
b66121e32b | ||
|
|
bddf79873b | ||
|
|
ae703c372c | ||
|
|
3d1eabba0f | ||
|
|
27ff199627 | ||
|
|
31174cbaba | ||
|
|
ba20abf0c3 | ||
|
|
2dd27b37c6 | ||
|
|
82d63e0296 | ||
|
|
c8a7f26229 | ||
|
|
12f5ba4c9d | ||
|
|
227f90fa00 | ||
|
|
0d699ec7f5 | ||
|
|
bf749ee1da | ||
|
|
0b44308754 | ||
|
|
0301ce58ab | ||
|
|
724c4fee27 | ||
|
|
006b348e6b | ||
|
|
0c9bdeab70 | ||
|
|
cd019514f3 | ||
|
|
1bfc699045 | ||
|
|
2cacfc1394 | ||
|
|
dcae8a4dc9 | ||
|
|
7de6ccb65b | ||
|
|
ea6b7197c7 | ||
|
|
ae652a8e4e | ||
|
|
b1a9842b2f | ||
|
|
32a16295c3 | ||
|
|
447fefd31c | ||
|
|
6510916b9f | ||
|
|
9c95411dfa | ||
|
|
e0ef8db54b | ||
|
|
4a1b91a9c8 | ||
|
|
3301d3036e | ||
|
|
fb1fecd754 | ||
|
|
60769db4ee | ||
|
|
efcc86273b | ||
|
|
b648a56009 | ||
|
|
282680e163 | ||
|
|
79e9fdf13f | ||
|
|
d146c1ddc1 | ||
|
|
a815c7d269 | ||
|
|
2eb6d1e71c | ||
|
|
6378df47c0 | ||
|
|
9f629a9d38 | ||
|
|
df355eca3a | ||
|
|
4fe3946cb4 | ||
|
|
7fbe03946f | ||
|
|
7a613a4507 | ||
|
|
9f1f7789bf | ||
|
|
8492b82d12 | ||
|
|
f6f657b627 | ||
|
|
fb68f1c389 | ||
|
|
468132320d | ||
|
|
c1c4145240 | ||
|
|
8a97ad58b0 | ||
|
|
01efcf2d92 | ||
|
|
a092499981 | ||
|
|
b23d15c430 | ||
|
|
a0e48602d3 | ||
|
|
b5fb6da46e | ||
|
|
e219184f37 | ||
|
|
039972c730 | ||
|
|
5a031c07b6 | ||
|
|
a3f4caf179 | ||
|
|
0d5b69d551 | ||
|
|
a8e9d8cc8a | ||
|
|
3dade61176 | ||
|
|
4b6ac46cde | ||
|
|
0ca389721c | ||
|
|
eada286ca0 | ||
|
|
286d5ef561 | ||
|
|
f319b246db | ||
|
|
9415ad5d7f | ||
|
|
1767e76cdc | ||
|
|
fca5b33530 | ||
|
|
25ed8f2c47 | ||
|
|
914b2aea83 | ||
|
|
953aaad83a | ||
|
|
e281b3234e | ||
|
|
918ee5610a | ||
|
|
3fcf0db96e | ||
|
|
0247ae7582 | ||
|
|
31407082eb | ||
|
|
db4aa0c2e7 | ||
|
|
85fbfb26fd | ||
|
|
e3fb1655ad | ||
|
|
bdcc2bd9dd | ||
|
|
f4cadb9b0e | ||
|
|
d80a8d638c | ||
|
|
57e5d102d5 | ||
|
|
41d5a12011 | ||
|
|
3077ddbd09 | ||
|
|
a5d1b68800 | ||
|
|
470aa76894 | ||
|
|
1b3b83273c | ||
|
|
37861335a2 | ||
|
|
2a239aedca | ||
|
|
fc861fca50 | ||
|
|
853764bc8c | ||
|
|
e325cea6b7 | ||
|
|
ffd533c40d | ||
|
|
c83c68500f | ||
|
|
c47bf217be | ||
|
|
32cdd3b187 | ||
|
|
e33c3c72f9 | ||
|
|
ac46f773ee | ||
|
|
5e12c6aeb7 | ||
|
|
1e0cbe6779 | ||
|
|
ff20051861 | ||
|
|
6b535328c0 | ||
|
|
19f04bcbcb | ||
|
|
61055ed02b | ||
|
|
f7c59649fe | ||
|
|
dbb1d5ed19 | ||
|
|
38b32c6619 | ||
|
|
66ac898b54 | ||
|
|
753a844d83 | ||
|
|
1a525a7e14 | ||
|
|
9e0badff61 | ||
|
|
a9277f9d46 | ||
|
|
b7d65be051 | ||
|
|
c804611343 | ||
|
|
79a1674021 | ||
|
|
9e583b8df4 | ||
|
|
74c0fbb6a2 | ||
|
|
c5d549810e | ||
|
|
ec32d44085 | ||
|
|
bded1f5d39 | ||
|
|
2d050a88e2 | ||
|
|
907ec735f8 | ||
|
|
bcf83153d7 | ||
|
|
13d0f086cc | ||
|
|
c79f4b5a4f | ||
|
|
cc582c6ed5 | ||
|
|
bed1329672 | ||
|
|
6371351d10 | ||
|
|
2921e05554 | ||
|
|
7f376c501a | ||
|
|
ceed5edc78 | ||
|
|
4e8a1b3802 | ||
|
|
ad46e6293c | ||
|
|
bc94d9598e | ||
|
|
a6c0f3efac | ||
|
|
35b67a9f5b | ||
|
|
1ce77db3d0 | ||
|
|
0ea4193001 | ||
|
|
810d80bc3c | ||
|
|
6b15e6c1ff | ||
|
|
92a0d47237 | ||
|
|
ea14d4a08a | ||
|
|
62a85d55f8 | ||
|
|
7b82d12675 | ||
|
|
001129c993 | ||
|
|
dda3e4b4f2 | ||
|
|
d93cba5581 | ||
|
|
cc1da8aee6 | ||
|
|
ca9ce4b592 | ||
|
|
42d5dcab98 | ||
|
|
c78e28682d | ||
|
|
05e57dea66 | ||
|
|
0da9821e90 | ||
|
|
cb454b0540 | ||
|
|
f9ce61e34a | ||
|
|
ad50dd513f | ||
|
|
2aed592d1f | ||
|
|
5f22d6c3da | ||
|
|
6727cd6ecb | ||
|
|
abe9abbed7 | ||
|
|
dd79e7fabb | ||
|
|
d717c2302d | ||
|
|
6dd141811d | ||
|
|
647c04cffe | ||
|
|
90bbe8be4f | ||
|
|
a3e8162eb1 | ||
|
|
bc5ca9a452 | ||
|
|
01d8d669bc | ||
|
|
e237fea99a |
10
CONTRIBUTING.md → .github/CONTRIBUTING.md
vendored
10
CONTRIBUTING.md → .github/CONTRIBUTING.md
vendored
@@ -1,10 +1,9 @@
|
|||||||
## Contributing
|
## Contributing
|
||||||
|
Please keep the [issue tracker](https://github.com/hakimel/reveal.js/issues) limited to **bug reports**.
|
||||||
Please keep the [issue tracker](http://github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**.
|
|
||||||
|
|
||||||
|
|
||||||
### Personal Support
|
### General Questions and Support
|
||||||
If you have personal support or setup questions the best place to ask those are [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js).
|
If you have questions about how to use reveal.js the best place to ask is in the [Discussions](https://github.com/hakimel/reveal.js/discussions). Anything that isn't a bug report should be posted as a dicussion instead.
|
||||||
|
|
||||||
|
|
||||||
### Bug Reports
|
### Bug Reports
|
||||||
@@ -12,11 +11,10 @@ When reporting a bug make sure to include information about which browser and op
|
|||||||
|
|
||||||
|
|
||||||
### Pull Requests
|
### Pull Requests
|
||||||
|
- Should be submitted from a feature/topic branch (not your master)
|
||||||
- Should follow the coding style of the file you work in, most importantly:
|
- Should follow the coding style of the file you work in, most importantly:
|
||||||
- Tabs to indent
|
- Tabs to indent
|
||||||
- Single-quoted strings
|
- Single-quoted strings
|
||||||
- Should be made towards the **dev branch**
|
|
||||||
- Should be submitted from a feature/topic branch (not your master)
|
|
||||||
|
|
||||||
|
|
||||||
### Plugins
|
### Plugins
|
||||||
17
.github/workflows/js.yml
vendored
17
.github/workflows/js.yml
vendored
@@ -1,22 +1,29 @@
|
|||||||
name: tests
|
name: tests
|
||||||
|
|
||||||
on: [push]
|
on:
|
||||||
|
- push
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [10.x, 14.x, 16.x]
|
node-version:
|
||||||
|
- 18
|
||||||
|
- 20
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
|
|
||||||
- run: npm install
|
- run: npm install
|
||||||
- run: npm run build --if-present
|
- run: npm run build --if-present
|
||||||
- run: npm test
|
- run: npm test
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,4 +9,3 @@ log/*.log
|
|||||||
tmp/**
|
tmp/**
|
||||||
node_modules/
|
node_modules/
|
||||||
.sass-cache
|
.sass-cache
|
||||||
dist/*.map
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
/test
|
/test
|
||||||
/examples
|
/examples
|
||||||
.github
|
.github
|
||||||
.gulpfile
|
|
||||||
.sass-cache
|
.sass-cache
|
||||||
gulpfile.js
|
gulpfile.js
|
||||||
CONTRIBUTING.md
|
|
||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright (C) 2020 Hakim El Hattab, http://hakim.se, and reveal.js contributors
|
Copyright (C) 2011-2023 Hakim El Hattab, http://hakim.se, and reveal.js contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
48
README.md
48
README.md
@@ -1,28 +1,50 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://revealjs.com">
|
<a href="https://revealjs.com">
|
||||||
<img src="https://hakim-static.s3.amazonaws.com/reveal-js/logo/v1/reveal-black-text.svg" alt="reveal.js" width="450">
|
<img src="https://hakim-static.s3.amazonaws.com/reveal-js/logo/v1/reveal-black-text-sticker.png" alt="reveal.js" width="500">
|
||||||
</a>
|
</a>
|
||||||
<br><br>
|
<br><br>
|
||||||
<a href="https://github.com/hakimel/reveal.js/actions"><img src="https://github.com/hakimel/reveal.js/workflows/tests/badge.svg"></a>
|
<a href="https://github.com/hakimel/reveal.js/actions"><img src="https://github.com/hakimel/reveal.js/workflows/tests/badge.svg"></a>
|
||||||
<a href="https://slides.com/"><img src="https://s3.amazonaws.com/static.slid.es/images/slides-github-banner-320x40.png?1" alt="Slides" width="160" height="20"></a>
|
<a href="https://slides.com/"><img src="https://s3.amazonaws.com/static.slid.es/images/slides-github-banner-320x40.png?1" alt="Slides" width="160" height="20"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
reveal.js is an open source HTML presentation framework. It enables anyone with a web browser to create fully featured and beautiful presentations for free. [Check out the live demo](https://revealjs.com/).
|
reveal.js is an open source HTML presentation framework. It enables anyone with a web browser to create beautiful presentations for free. Check out the live demo at [revealjs.com](https://revealjs.com/).
|
||||||
|
|
||||||
The framework comes with a broad range of features including [nested slides](https://revealjs.com/vertical-slides/), [Markdown support](https://revealjs.com/markdown/), [Auto-Animate](https://revealjs.com/auto-animate/), [PDF export](https://revealjs.com/pdf-export/), [speaker notes](https://revealjs.com/speaker-view/), [LaTeX support](https://revealjs.com/math/), [syntax highlighted code](https://revealjs.com/code/) and much more.
|
The framework comes with a powerful feature set including [nested slides](https://revealjs.com/vertical-slides/), [Markdown support](https://revealjs.com/markdown/), [Auto-Animate](https://revealjs.com/auto-animate/), [PDF export](https://revealjs.com/pdf-export/), [speaker notes](https://revealjs.com/speaker-view/), [LaTeX typesetting](https://revealjs.com/math/), [syntax highlighted code](https://revealjs.com/code/) and an [extensive API](https://revealjs.com/api/).
|
||||||
|
|
||||||
<h1>
|
---
|
||||||
<a href="https://revealjs.com/installation" style="font-size: 3em;">Get Started</a>
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
## Documentation
|
Want to create reveal.js presentation in a graphical editor? Try <https://slides.com>. It's made by the same people behind reveal.js.
|
||||||
The full reveal.js documentation is available at [revealjs.com](https://revealjs.com).
|
|
||||||
|
|
||||||
## Online Editor
|
---
|
||||||
Want to create your presentation using a visual editor? Try the official reveal.js presentation platform for free at [Slides.com](https://slides.com). It's made by the same people behind reveal.js.
|
|
||||||
|
|
||||||
## License
|
### Sponsors
|
||||||
|
Hakim's open source work is supported by <a href="https://github.com/sponsors/hakimel">GitHub sponsors</a>. Special thanks to:
|
||||||
|
<div align="center">
|
||||||
|
<table>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=revealjs&utm_source=github">
|
||||||
|
<div>
|
||||||
|
<img src="https://user-images.githubusercontent.com/629429/151508669-efb4c3b3-8fe3-45eb-8e47-e9510b5f0af1.svg" width="290" alt="WorkOS">
|
||||||
|
</div>
|
||||||
|
<b>Your app, enterprise-ready.</b>
|
||||||
|
<div>
|
||||||
|
<sub>Start selling to enterprise customers with just a few lines of code. Add Single Sign-On (and more) in minutes instead of months.</sup>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
MIT licensed
|
---
|
||||||
|
|
||||||
Copyright (C) 2011-2021 Hakim El Hattab, https://hakim.se
|
### Getting started
|
||||||
|
- 🚀 [Install reveal.js](https://revealjs.com/installation)
|
||||||
|
- 👀 [View the demo presentation](https://revealjs.com/demo)
|
||||||
|
- 📖 [Read the documentation](https://revealjs.com/markup/)
|
||||||
|
- 🖌 [Try the visual editor for reveal.js at Slides.com](https://slides.com/)
|
||||||
|
- 🎬 [Watch the reveal.js video course (paid)](https://revealjs.com/course)
|
||||||
|
|
||||||
|
---
|
||||||
|
<div align="center">
|
||||||
|
MIT licensed | Copyright © 2011-2023 Hakim El Hattab, https://hakim.se
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text that auto-fits it's container
|
// Text that auto-fits its container
|
||||||
.reveal .r-fit-text {
|
.reveal .r-fit-text {
|
||||||
display: inline-block; // https://github.com/rikschennink/fitty#performance
|
display: inline-block; // https://github.com/rikschennink/fitty#performance
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|||||||
@@ -1,42 +1,30 @@
|
|||||||
/* Default Print Stylesheet Template
|
|
||||||
by Rob Glazebrook of CSSnewbie.com
|
|
||||||
Last Updated: June 4, 2008
|
|
||||||
|
|
||||||
Feel free (nay, compelled) to edit, append, and
|
|
||||||
manipulate this file as you see fit. */
|
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
html:not(.print-pdf) {
|
html:not(.print-pdf) {
|
||||||
|
overflow: visible;
|
||||||
background: #fff;
|
|
||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
overflow: visible;
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background: #fff;
|
margin: 0;
|
||||||
font-size: 20pt;
|
|
||||||
width: auto;
|
|
||||||
height: auto;
|
|
||||||
border: 0;
|
|
||||||
margin: 0 5%;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
float: none !important;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nestedarrow,
|
html:not(.print-pdf) .reveal {
|
||||||
|
background: #fff;
|
||||||
|
font-size: 20pt;
|
||||||
|
|
||||||
.controls,
|
.controls,
|
||||||
.fork-reveal,
|
|
||||||
.share-reveal,
|
|
||||||
.state-background,
|
.state-background,
|
||||||
.reveal .progress,
|
.progress,
|
||||||
.reveal .backgrounds,
|
.backgrounds,
|
||||||
.reveal .slide-number {
|
.slide-number {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
body, p, td, li {
|
p, td, li {
|
||||||
font-size: 20pt!important;
|
font-size: 20pt!important;
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
@@ -49,7 +37,6 @@
|
|||||||
letter-spacing: normal;
|
letter-spacing: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need to reduce the size of the fonts for printing */
|
|
||||||
h1 { font-size: 28pt !important; }
|
h1 { font-size: 28pt !important; }
|
||||||
h2 { font-size: 24pt !important; }
|
h2 { font-size: 24pt !important; }
|
||||||
h3 { font-size: 22pt !important; }
|
h3 { font-size: 22pt !important; }
|
||||||
@@ -74,18 +61,19 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
text-align: left !important;
|
text-align: left !important;
|
||||||
}
|
}
|
||||||
.reveal pre,
|
pre,
|
||||||
.reveal table {
|
table {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
.reveal pre code {
|
pre code {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
.reveal blockquote {
|
blockquote {
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
}
|
}
|
||||||
.reveal .slides {
|
|
||||||
|
.slides {
|
||||||
position: static !important;
|
position: static !important;
|
||||||
width: auto !important;
|
width: auto !important;
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
@@ -106,7 +94,7 @@
|
|||||||
|
|
||||||
perspective-origin: 50% 50%;
|
perspective-origin: 50% 50%;
|
||||||
}
|
}
|
||||||
.reveal .slides section {
|
.slides section {
|
||||||
visibility: visible !important;
|
visibility: visible !important;
|
||||||
position: static !important;
|
position: static !important;
|
||||||
width: auto !important;
|
width: auto !important;
|
||||||
@@ -129,19 +117,24 @@
|
|||||||
transform: none !important;
|
transform: none !important;
|
||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
.reveal .slides section.stack {
|
.slides section.stack {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
.reveal section:last-of-type {
|
.slides section:last-of-type {
|
||||||
page-break-after: avoid !important;
|
page-break-after: avoid !important;
|
||||||
}
|
}
|
||||||
.reveal section .fragment {
|
.slides section .fragment {
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
visibility: visible !important;
|
visibility: visible !important;
|
||||||
|
|
||||||
transform: none !important;
|
transform: none !important;
|
||||||
}
|
}
|
||||||
.reveal section img {
|
|
||||||
|
.r-fit-text {
|
||||||
|
white-space: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
section img {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 15px 0px;
|
margin: 15px 0px;
|
||||||
background: rgba(255,255,255,1);
|
background: rgba(255,255,255,1);
|
||||||
@@ -149,11 +142,11 @@
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal section small {
|
section small {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .hljs {
|
.hljs {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
@@ -161,11 +154,11 @@
|
|||||||
font-size: 15pt;
|
font-size: 15pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .hljs .hljs-ln-numbers {
|
.hljs .hljs-ln-numbers {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .hljs td {
|
.hljs td {
|
||||||
font-size: inherit !important;
|
font-size: inherit !important;
|
||||||
color: inherit !important;
|
color: inherit !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* https://revealjs.com/pdf-export/
|
* https://revealjs.com/pdf-export/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
html.print-pdf {
|
html.reveal-print {
|
||||||
* {
|
* {
|
||||||
-webkit-print-color-adjust: exact;
|
-webkit-print-color-adjust: exact;
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,6 @@ html.print-pdf {
|
|||||||
|
|
||||||
.reveal pre code {
|
.reveal pre code {
|
||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
font-family: Courier, 'Courier New', monospace !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal {
|
.reveal {
|
||||||
@@ -71,6 +70,10 @@ html.print-pdf {
|
|||||||
page-break-after: always;
|
page-break-after: always;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reveal .slides .pdf-page:last-of-type {
|
||||||
|
page-break-after: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
.reveal .slides section {
|
.reveal .slides section {
|
||||||
visibility: visible !important;
|
visibility: visible !important;
|
||||||
display: block !important;
|
display: block !important;
|
||||||
@@ -100,7 +103,6 @@ html.print-pdf {
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Slide backgrounds are placed inside of their slide when exporting to PDF */
|
/* Slide backgrounds are placed inside of their slide when exporting to PDF */
|
||||||
.reveal .backgrounds {
|
.reveal .backgrounds {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -147,6 +149,7 @@ html.print-pdf {
|
|||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This accessibility tool is not useful in PDF and breaks it visually */
|
/* This accessibility tool is not useful in PDF and breaks it visually */
|
||||||
|
|||||||
393
css/reveal.scss
393
css/reveal.scss
@@ -1,3 +1,5 @@
|
|||||||
|
@use "sass:math";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reveal.js
|
* reveal.js
|
||||||
* http://revealjs.com
|
* http://revealjs.com
|
||||||
@@ -17,6 +19,7 @@ html.reveal-full-page {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
height: calc( var(--vh, 1vh) * 100 );
|
height: calc( var(--vh, 1vh) * 100 );
|
||||||
|
height: 100svh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +32,18 @@ html.reveal-full-page {
|
|||||||
|
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
color: #000;
|
color: #000;
|
||||||
|
|
||||||
|
--r-controls-spacing: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force the presentation to cover the full viewport when we
|
||||||
|
// enter fullscreen mode. Fixes sizing issues in Safari.
|
||||||
|
.reveal-viewport:fullscreen {
|
||||||
|
top: 0 !important;
|
||||||
|
left: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
transform: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -36,11 +51,14 @@ html.reveal-full-page {
|
|||||||
* VIEW FRAGMENTS
|
* VIEW FRAGMENTS
|
||||||
*********************************************/
|
*********************************************/
|
||||||
|
|
||||||
.reveal .slides section .fragment {
|
.reveal .fragment {
|
||||||
|
transition: all .2s ease;
|
||||||
|
|
||||||
|
&:not(.custom) {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
transition: all .2s ease;
|
|
||||||
will-change: opacity;
|
will-change: opacity;
|
||||||
|
}
|
||||||
|
|
||||||
&.visible {
|
&.visible {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
@@ -52,7 +70,7 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.grow {
|
.reveal .fragment.grow {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: inherit;
|
visibility: inherit;
|
||||||
|
|
||||||
@@ -61,7 +79,7 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.shrink {
|
.reveal .fragment.shrink {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: inherit;
|
visibility: inherit;
|
||||||
|
|
||||||
@@ -70,7 +88,7 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.zoom-in {
|
.reveal .fragment.zoom-in {
|
||||||
transform: scale( 0.1 );
|
transform: scale( 0.1 );
|
||||||
|
|
||||||
&.visible {
|
&.visible {
|
||||||
@@ -78,7 +96,7 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.fade-out {
|
.reveal .fragment.fade-out {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: inherit;
|
visibility: inherit;
|
||||||
|
|
||||||
@@ -88,7 +106,7 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.semi-fade-out {
|
.reveal .fragment.semi-fade-out {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: inherit;
|
visibility: inherit;
|
||||||
|
|
||||||
@@ -98,7 +116,7 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.strike {
|
.reveal .fragment.strike {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: inherit;
|
visibility: inherit;
|
||||||
|
|
||||||
@@ -107,7 +125,7 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.fade-up {
|
.reveal .fragment.fade-up {
|
||||||
transform: translate(0, 40px);
|
transform: translate(0, 40px);
|
||||||
|
|
||||||
&.visible {
|
&.visible {
|
||||||
@@ -115,7 +133,7 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.fade-down {
|
.reveal .fragment.fade-down {
|
||||||
transform: translate(0, -40px);
|
transform: translate(0, -40px);
|
||||||
|
|
||||||
&.visible {
|
&.visible {
|
||||||
@@ -123,7 +141,7 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.fade-right {
|
.reveal .fragment.fade-right {
|
||||||
transform: translate(-40px, 0);
|
transform: translate(-40px, 0);
|
||||||
|
|
||||||
&.visible {
|
&.visible {
|
||||||
@@ -131,7 +149,7 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.fade-left {
|
.reveal .fragment.fade-left {
|
||||||
transform: translate(40px, 0);
|
transform: translate(40px, 0);
|
||||||
|
|
||||||
&.visible {
|
&.visible {
|
||||||
@@ -139,8 +157,8 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.fade-in-then-out,
|
.reveal .fragment.fade-in-then-out,
|
||||||
.reveal .slides section .fragment.current-visible {
|
.reveal .fragment.current-visible {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
|
||||||
@@ -150,7 +168,7 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.fade-in-then-semi-out {
|
.reveal .fragment.fade-in-then-semi-out {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
|
||||||
@@ -165,32 +183,32 @@ html.reveal-full-page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.highlight-red,
|
.reveal .fragment.highlight-red,
|
||||||
.reveal .slides section .fragment.highlight-current-red,
|
.reveal .fragment.highlight-current-red,
|
||||||
.reveal .slides section .fragment.highlight-green,
|
.reveal .fragment.highlight-green,
|
||||||
.reveal .slides section .fragment.highlight-current-green,
|
.reveal .fragment.highlight-current-green,
|
||||||
.reveal .slides section .fragment.highlight-blue,
|
.reveal .fragment.highlight-blue,
|
||||||
.reveal .slides section .fragment.highlight-current-blue {
|
.reveal .fragment.highlight-current-blue {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: inherit;
|
visibility: inherit;
|
||||||
}
|
}
|
||||||
.reveal .slides section .fragment.highlight-red.visible {
|
.reveal .fragment.highlight-red.visible {
|
||||||
color: #ff2c2d
|
color: #ff2c2d
|
||||||
}
|
}
|
||||||
.reveal .slides section .fragment.highlight-green.visible {
|
.reveal .fragment.highlight-green.visible {
|
||||||
color: #17ff2e;
|
color: #17ff2e;
|
||||||
}
|
}
|
||||||
.reveal .slides section .fragment.highlight-blue.visible {
|
.reveal .fragment.highlight-blue.visible {
|
||||||
color: #1b91ff;
|
color: #1b91ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .slides section .fragment.highlight-current-red.current-fragment {
|
.reveal .fragment.highlight-current-red.current-fragment {
|
||||||
color: #ff2c2d
|
color: #ff2c2d
|
||||||
}
|
}
|
||||||
.reveal .slides section .fragment.highlight-current-green.current-fragment {
|
.reveal .fragment.highlight-current-green.current-fragment {
|
||||||
color: #17ff2e;
|
color: #17ff2e;
|
||||||
}
|
}
|
||||||
.reveal .slides section .fragment.highlight-current-blue.current-fragment {
|
.reveal .fragment.highlight-current-blue.current-fragment {
|
||||||
color: #1b91ff;
|
color: #1b91ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,22 +265,20 @@ $controlsArrowAngleActive: 36deg;
|
|||||||
|
|
||||||
@mixin controlsArrowTransform( $angle ) {
|
@mixin controlsArrowTransform( $angle ) {
|
||||||
&:before {
|
&:before {
|
||||||
transform: translateX(($controlArrowSize - $controlArrowLength)/2) translateY(($controlArrowSize - $controlArrowThickness)/2) rotate( $angle );
|
transform: translateX(($controlArrowSize - $controlArrowLength)*0.5) translateY(($controlArrowSize - $controlArrowThickness)*0.5) rotate( $angle );
|
||||||
}
|
}
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
transform: translateX(($controlArrowSize - $controlArrowLength)/2) translateY(($controlArrowSize - $controlArrowThickness)/2) rotate( -$angle );
|
transform: translateX(($controlArrowSize - $controlArrowLength)*0.5) translateY(($controlArrowSize - $controlArrowThickness)*0.5) rotate( -$angle );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal .controls {
|
.reveal .controls {
|
||||||
$spacing: 12px;
|
|
||||||
|
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: auto;
|
top: auto;
|
||||||
bottom: $spacing;
|
bottom: var(--r-controls-spacing);
|
||||||
right: $spacing;
|
right: var(--r-controls-spacing);
|
||||||
left: auto;
|
left: auto;
|
||||||
z-index: 11;
|
z-index: 11;
|
||||||
color: #000;
|
color: #000;
|
||||||
@@ -300,11 +316,11 @@ $controlsArrowAngleActive: 36deg;
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: $controlArrowLength;
|
width: $controlArrowLength;
|
||||||
height: $controlArrowThickness;
|
height: $controlArrowThickness;
|
||||||
border-radius: $controlArrowThickness/2;
|
border-radius: $controlArrowThickness*0.5;
|
||||||
background-color: currentColor;
|
background-color: currentColor;
|
||||||
|
|
||||||
transition: all 0.15s ease, background-color 0.8s ease;
|
transition: all 0.15s ease, background-color 0.8s ease;
|
||||||
transform-origin: floor(($controlArrowThickness/2)*10)/10 50%;
|
transform-origin: math.div(floor(($controlArrowThickness*0.5)*10), 10) 50%;
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +342,7 @@ $controlsArrowAngleActive: 36deg;
|
|||||||
|
|
||||||
.navigate-left {
|
.navigate-left {
|
||||||
right: $controlArrowSize + $controlArrowSpacing*2;
|
right: $controlArrowSize + $controlArrowSpacing*2;
|
||||||
bottom: $controlArrowSpacing + $controlArrowSize/2;
|
bottom: $controlArrowSpacing + $controlArrowSize*0.5;
|
||||||
transform: translateX( -10px );
|
transform: translateX( -10px );
|
||||||
|
|
||||||
&.highlight {
|
&.highlight {
|
||||||
@@ -336,7 +352,7 @@ $controlsArrowAngleActive: 36deg;
|
|||||||
|
|
||||||
.navigate-right {
|
.navigate-right {
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: $controlArrowSpacing + $controlArrowSize/2;
|
bottom: $controlArrowSpacing + $controlArrowSize*0.5;
|
||||||
transform: translateX( 10px );
|
transform: translateX( 10px );
|
||||||
|
|
||||||
.controls-arrow {
|
.controls-arrow {
|
||||||
@@ -349,7 +365,7 @@ $controlsArrowAngleActive: 36deg;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.navigate-up {
|
.navigate-up {
|
||||||
right: $controlArrowSpacing + $controlArrowSize/2;
|
right: $controlArrowSpacing + $controlArrowSize*0.5;
|
||||||
bottom: $controlArrowSpacing*2 + $controlArrowSize;
|
bottom: $controlArrowSpacing*2 + $controlArrowSize;
|
||||||
transform: translateY( -10px );
|
transform: translateY( -10px );
|
||||||
|
|
||||||
@@ -359,7 +375,7 @@ $controlsArrowAngleActive: 36deg;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.navigate-down {
|
.navigate-down {
|
||||||
right: $controlArrowSpacing + $controlArrowSize/2;
|
right: $controlArrowSpacing + $controlArrowSize*0.5;
|
||||||
bottom: -$controlArrowSpacing;
|
bottom: -$controlArrowSpacing;
|
||||||
padding-bottom: $controlArrowSpacing;
|
padding-bottom: $controlArrowSpacing;
|
||||||
transform: translateY( 10px );
|
transform: translateY( 10px );
|
||||||
@@ -494,7 +510,9 @@ $controlsArrowAngleActive: 36deg;
|
|||||||
// Edge aligned controls layout
|
// Edge aligned controls layout
|
||||||
@media screen and (min-width: 500px) {
|
@media screen and (min-width: 500px) {
|
||||||
|
|
||||||
$spacing: 0.8em;
|
.reveal-viewport {
|
||||||
|
--r-controls-spacing: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
.reveal .controls[data-controls-layout="edges"] {
|
.reveal .controls[data-controls-layout="edges"] {
|
||||||
& {
|
& {
|
||||||
@@ -514,26 +532,26 @@ $controlsArrowAngleActive: 36deg;
|
|||||||
|
|
||||||
.navigate-left {
|
.navigate-left {
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: $spacing;
|
left: var(--r-controls-spacing);
|
||||||
margin-top: -$controlArrowSize/2;
|
margin-top: -$controlArrowSize*0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigate-right {
|
.navigate-right {
|
||||||
top: 50%;
|
top: 50%;
|
||||||
right: $spacing;
|
right: var(--r-controls-spacing);
|
||||||
margin-top: -$controlArrowSize/2;
|
margin-top: -$controlArrowSize*0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigate-up {
|
.navigate-up {
|
||||||
top: $spacing;
|
top: var(--r-controls-spacing);
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -$controlArrowSize/2;
|
margin-left: -$controlArrowSize*0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigate-down {
|
.navigate-down {
|
||||||
bottom: $spacing - $controlArrowSpacing + 0.3em;
|
bottom: calc(var(--r-controls-spacing) - #{$controlArrowSpacing} + 0.3em);
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -$controlArrowSize/2;
|
margin-left: -$controlArrowSize*0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,6 +729,8 @@ $controlsArrowAngleActive: 36deg;
|
|||||||
|
|
||||||
.reveal .slides>section.past,
|
.reveal .slides>section.past,
|
||||||
.reveal .slides>section.future,
|
.reveal .slides>section.future,
|
||||||
|
.reveal .slides>section.past>section,
|
||||||
|
.reveal .slides>section.future>section,
|
||||||
.reveal .slides>section>section.past,
|
.reveal .slides>section>section.past,
|
||||||
.reveal .slides>section>section.future {
|
.reveal .slides>section>section.future {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@@ -769,9 +789,6 @@ $controlsArrowAngleActive: 36deg;
|
|||||||
*********************************************/
|
*********************************************/
|
||||||
|
|
||||||
@each $stylename in slide, linear {
|
@each $stylename in slide, linear {
|
||||||
.reveal.#{$stylename} section {
|
|
||||||
backface-visibility: hidden;
|
|
||||||
}
|
|
||||||
@include transition-horizontal-past(#{$stylename}) {
|
@include transition-horizontal-past(#{$stylename}) {
|
||||||
transform: translate(-150%, 0);
|
transform: translate(-150%, 0);
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1184,6 @@ $controlsArrowAngleActive: 36deg;
|
|||||||
.reveal[data-background-transition=slide]>.backgrounds .slide-background:not([data-background-transition]),
|
.reveal[data-background-transition=slide]>.backgrounds .slide-background:not([data-background-transition]),
|
||||||
.reveal>.backgrounds .slide-background[data-background-transition=slide] {
|
.reveal>.backgrounds .slide-background[data-background-transition=slide] {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
backface-visibility: hidden;
|
|
||||||
}
|
}
|
||||||
.reveal[data-background-transition=slide]>.backgrounds .slide-background.past:not([data-background-transition]),
|
.reveal[data-background-transition=slide]>.backgrounds .slide-background.past:not([data-background-transition]),
|
||||||
.reveal>.backgrounds .slide-background.past[data-background-transition=slide] {
|
.reveal>.backgrounds .slide-background.past[data-background-transition=slide] {
|
||||||
@@ -1623,6 +1639,10 @@ $overlayHeaderPadding: 5px;
|
|||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reveal .hljs.has-highlights.fragment {
|
||||||
|
transition: all .2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
.reveal .hljs:not(:first-child).fragment {
|
.reveal .hljs:not(:first-child).fragment {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -1701,7 +1721,7 @@ $notesWidthPercent: 25%;
|
|||||||
.reveal .speaker-notes {
|
.reveal .speaker-notes {
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: $notesWidthPercent / (1-$notesWidthPercent/100) * 1%;
|
width: math.div($notesWidthPercent, (1 - math.div($notesWidthPercent,100))) * 1%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 100%;
|
left: 100%;
|
||||||
@@ -1764,7 +1784,6 @@ $notesWidthPercent: 25%;
|
|||||||
top: 100%;
|
top: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: (30/0.7)*1%;
|
|
||||||
height: 30vh;
|
height: 30vh;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
@@ -1778,7 +1797,6 @@ $notesWidthPercent: 25%;
|
|||||||
|
|
||||||
.reveal.show-notes .speaker-notes {
|
.reveal.show-notes .speaker-notes {
|
||||||
top: 100%;
|
top: 100%;
|
||||||
height: (40/0.6)*1%;
|
|
||||||
height: 40vh;
|
height: 40vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1788,6 +1806,43 @@ $notesWidthPercent: 25%;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* JUMP-TO-SLIDE COMPONENT
|
||||||
|
*********************************************/
|
||||||
|
|
||||||
|
.reveal .jump-to-slide {
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
left: 15px;
|
||||||
|
z-index: 30;
|
||||||
|
font-size: 32px;
|
||||||
|
-webkit-tap-highlight-color: rgba( 0, 0, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .jump-to-slide-input {
|
||||||
|
background: transparent;
|
||||||
|
padding: 8px;
|
||||||
|
font-size: inherit;
|
||||||
|
color: currentColor;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
.reveal .jump-to-slide-input::placeholder {
|
||||||
|
color: currentColor;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal.has-dark-background .jump-to-slide-input {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.reveal.has-light-background .jump-to-slide-input {
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .jump-to-slide-input:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
* ZOOM PLUGIN
|
* ZOOM PLUGIN
|
||||||
*********************************************/
|
*********************************************/
|
||||||
@@ -1812,6 +1867,234 @@ $notesWidthPercent: 25%;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* SCROLL VIEW
|
||||||
|
*********************************************/
|
||||||
|
.reveal-viewport.loading-scroll-mode {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal-viewport.reveal-scroll {
|
||||||
|
& {
|
||||||
|
margin: 0 auto;
|
||||||
|
overflow: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
--r-scrollbar-width: 7px;
|
||||||
|
--r-scrollbar-trigger-size: 5px;
|
||||||
|
--r-controls-spacing: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 500px) {
|
||||||
|
--r-scrollbar-width: 3px;
|
||||||
|
--r-scrollbar-trigger-size: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls,
|
||||||
|
.progress,
|
||||||
|
.playback,
|
||||||
|
.backgrounds,
|
||||||
|
.slide-number,
|
||||||
|
.speaker-notes {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal {
|
||||||
|
overflow: visible;
|
||||||
|
touch-action: manipulation;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slides {
|
||||||
|
position: static;
|
||||||
|
pointer-events: initial;
|
||||||
|
|
||||||
|
left: auto;
|
||||||
|
top: auto;
|
||||||
|
width: 100% !important;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
overflow: visible;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
perspective: none;
|
||||||
|
perspective-origin: 50% 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-page {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(var(--page-height) + var(--page-scroll-padding));
|
||||||
|
z-index: 1;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-page-sticky {
|
||||||
|
position: sticky;
|
||||||
|
height: var(--page-height);
|
||||||
|
top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-page-content {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-page section {
|
||||||
|
visibility: visible !important;
|
||||||
|
display: block !important;
|
||||||
|
position: absolute !important;
|
||||||
|
width: var(--slide-width) !important;
|
||||||
|
height: var(--slide-height) !important;
|
||||||
|
top: 50% !important;
|
||||||
|
left: 50% !important;
|
||||||
|
opacity: 1 !important;
|
||||||
|
transform: scale(var(--slide-scale)) translate(-50%, -50%) !important;
|
||||||
|
transform-style: flat !important;
|
||||||
|
transform-origin: 0 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-background {
|
||||||
|
display: block !important;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: auto !important;
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
touch-action: manipulation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chromium
|
||||||
|
.reveal-viewport.reveal-scroll[data-scrollbar="true"]::-webkit-scrollbar,
|
||||||
|
.reveal-viewport.reveal-scroll[data-scrollbar="auto"]::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Firefox
|
||||||
|
.reveal-viewport.reveal-scroll[data-scrollbar="true"],
|
||||||
|
.reveal-viewport.reveal-scroll[data-scrollbar="auto"] {
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal.has-dark-background,
|
||||||
|
.reveal-viewport.has-dark-background {
|
||||||
|
--r-overlay-element-bg-color: 240, 240, 240;
|
||||||
|
--r-overlay-element-fg-color: 0, 0, 0;
|
||||||
|
}
|
||||||
|
.reveal.has-light-background,
|
||||||
|
.reveal-viewport.has-light-background {
|
||||||
|
--r-overlay-element-bg-color: 0, 0, 0;
|
||||||
|
--r-overlay-element-fg-color: 240, 240, 240;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal-viewport.reveal-scroll .scrollbar {
|
||||||
|
position: sticky;
|
||||||
|
top: 50%;
|
||||||
|
z-index: 20;
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&.visible,
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-inner {
|
||||||
|
position: absolute;
|
||||||
|
width: var(--r-scrollbar-width);
|
||||||
|
height: calc(var(--viewport-height) - var(--r-controls-spacing) * 2);
|
||||||
|
right: var(--r-controls-spacing);
|
||||||
|
top: 0;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border-radius: var(--r-scrollbar-width);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-playhead {
|
||||||
|
position: absolute;
|
||||||
|
width: var(--r-scrollbar-width);
|
||||||
|
height: var(--r-scrollbar-width);
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
border-radius: var(--r-scrollbar-width);
|
||||||
|
background-color: rgba(var(--r-overlay-element-bg-color), 1);
|
||||||
|
z-index: 11;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-slide {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
background-color: rgba(var(--r-overlay-element-bg-color), 0.2);
|
||||||
|
box-shadow: 0 0 0px 1px rgba(var(--r-overlay-element-fg-color), 0.1);
|
||||||
|
border-radius: var(--r-scrollbar-width);
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hit area
|
||||||
|
.scrollbar-slide:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 200%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: -50%;
|
||||||
|
background: rgba( 0, 0, 0, 0 );
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-slide:hover,
|
||||||
|
.scrollbar-slide.active {
|
||||||
|
background-color: rgba(var(--r-overlay-element-bg-color), 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-trigger {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-slide.active.has-triggers {
|
||||||
|
background-color: rgba(var(--r-overlay-element-bg-color), 0.4);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-slide.active .scrollbar-trigger:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: var(--r-scrollbar-trigger-size);
|
||||||
|
height: var(--r-scrollbar-trigger-size);
|
||||||
|
border-radius: 20px;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: rgba(var(--r-overlay-element-bg-color), 1);
|
||||||
|
transition: transform 0.2s ease, opacity 0.2s ease;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-slide.active .scrollbar-trigger.active:after,
|
||||||
|
.scrollbar-slide.active .scrollbar-trigger.active ~ .scrollbar-trigger:after {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-slide.active .scrollbar-trigger ~ .scrollbar-trigger.active:after {
|
||||||
|
transform: translate(calc( var(--r-scrollbar-width) * -2), 0);
|
||||||
|
background-color: rgba(var(--r-overlay-element-bg-color), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
* PRINT STYLES
|
* PRINT STYLES
|
||||||
*********************************************/
|
*********************************************/
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ $linkColorHover: lighten( $linkColor, 20% );
|
|||||||
$selectionBackgroundColor: rgba(79, 64, 28, 0.99);
|
$selectionBackgroundColor: rgba(79, 64, 28, 0.99);
|
||||||
$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
|
$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
|
||||||
|
|
||||||
|
$overlayElementBgColor: 0, 0, 0;
|
||||||
|
$overlayElementFgColor: 240, 240, 240;
|
||||||
|
|
||||||
// Background generator
|
// Background generator
|
||||||
@mixin bodyBackground() {
|
@mixin bodyBackground() {
|
||||||
@include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) );
|
@include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) );
|
||||||
|
|||||||
49
css/theme/source/black-contrast.scss
Normal file
49
css/theme/source/black-contrast.scss
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* Black compact & high contrast reveal.js theme, with headers not in capitals.
|
||||||
|
*
|
||||||
|
* By Peter Kehl. Based on black.(s)css by Hakim El Hattab, http://hakim.se
|
||||||
|
*
|
||||||
|
* - Keep the source similar to black.css - for easy comparison.
|
||||||
|
* - $mainFontSize controls code blocks, too (although under some ratio).
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Default mixins and settings -----------------
|
||||||
|
@import "../template/mixins";
|
||||||
|
@import "../template/settings";
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Include theme-specific fonts
|
||||||
|
@import url(./fonts/source-sans-pro/source-sans-pro.css);
|
||||||
|
|
||||||
|
|
||||||
|
// Override theme settings (see ../template/settings.scss)
|
||||||
|
$backgroundColor: #000000;
|
||||||
|
|
||||||
|
$mainColor: #fff;
|
||||||
|
$headingColor: #fff;
|
||||||
|
|
||||||
|
$mainFontSize: 42px;
|
||||||
|
$mainFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||||
|
$headingFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||||
|
$headingTextShadow: none;
|
||||||
|
$headingLetterSpacing: normal;
|
||||||
|
$headingTextTransform: uppercase;
|
||||||
|
$headingFontWeight: 600;
|
||||||
|
$linkColor: #42affa;
|
||||||
|
$linkColorHover: lighten( $linkColor, 15% );
|
||||||
|
$selectionBackgroundColor: lighten( $linkColor, 25% );
|
||||||
|
|
||||||
|
$heading1Size: 2.5em;
|
||||||
|
$heading2Size: 1.6em;
|
||||||
|
$heading3Size: 1.3em;
|
||||||
|
$heading4Size: 1.0em;
|
||||||
|
|
||||||
|
// Change text colors against light slide backgrounds
|
||||||
|
@include light-bg-text-color(#000);
|
||||||
|
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
||||||
@@ -30,7 +30,7 @@ $headingTextTransform: uppercase;
|
|||||||
$headingFontWeight: 600;
|
$headingFontWeight: 600;
|
||||||
$linkColor: #42affa;
|
$linkColor: #42affa;
|
||||||
$linkColorHover: lighten( $linkColor, 15% );
|
$linkColorHover: lighten( $linkColor, 15% );
|
||||||
$selectionBackgroundColor: lighten( $linkColor, 25% );
|
$selectionBackgroundColor: rgba( $linkColor, 0.75 );
|
||||||
|
|
||||||
$heading1Size: 2.5em;
|
$heading1Size: 2.5em;
|
||||||
$heading2Size: 1.6em;
|
$heading2Size: 1.6em;
|
||||||
|
|||||||
106
css/theme/source/dracula.scss
Normal file
106
css/theme/source/dracula.scss
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/**
|
||||||
|
* Dracula Dark theme for reveal.js.
|
||||||
|
* Based on https://draculatheme.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Default mixins and settings -----------------
|
||||||
|
@import "../template/mixins";
|
||||||
|
@import "../template/settings";
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Include theme-specific fonts
|
||||||
|
$systemFontsSansSerif: -apple-system,
|
||||||
|
BlinkMacSystemFont,
|
||||||
|
avenir next,
|
||||||
|
avenir,
|
||||||
|
segoe ui,
|
||||||
|
helvetica neue,
|
||||||
|
helvetica,
|
||||||
|
Cantarell,
|
||||||
|
Ubuntu,
|
||||||
|
roboto,
|
||||||
|
noto,
|
||||||
|
arial,
|
||||||
|
sans-serif;
|
||||||
|
$systemFontsMono: Menlo,
|
||||||
|
Consolas,
|
||||||
|
Monaco,
|
||||||
|
Liberation Mono,
|
||||||
|
Lucida Console,
|
||||||
|
monospace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dracula colors by Zeno Rocha
|
||||||
|
* https://draculatheme.com/contribute
|
||||||
|
*/
|
||||||
|
html * {
|
||||||
|
color-profile: sRGB;
|
||||||
|
rendering-intent: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
$background: #282A36;
|
||||||
|
$foreground: #F8F8F2;
|
||||||
|
$selection: #44475A;
|
||||||
|
$comment: #6272A4;
|
||||||
|
$red: #FF5555;
|
||||||
|
$orange: #FFB86C;
|
||||||
|
$yellow: #F1FA8C;
|
||||||
|
$green: #50FA7B;
|
||||||
|
$purple: #BD93F9;
|
||||||
|
$cyan: #8BE9FD;
|
||||||
|
$pink: #FF79C6;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Override theme settings (see ../template/settings.scss)
|
||||||
|
$mainColor: $foreground;
|
||||||
|
$headingColor: $purple;
|
||||||
|
$headingTextShadow: none;
|
||||||
|
$headingTextTransform: none;
|
||||||
|
$backgroundColor: $background;
|
||||||
|
$linkColor: $pink;
|
||||||
|
$linkColorHover: $cyan;
|
||||||
|
$selectionBackgroundColor: $selection;
|
||||||
|
$inlineCodeColor: $green;
|
||||||
|
$listBulletColor: $cyan;
|
||||||
|
|
||||||
|
$mainFont: $systemFontsSansSerif;
|
||||||
|
$codeFont: "Fira Code", $systemFontsMono;
|
||||||
|
|
||||||
|
// Change text colors against light slide backgrounds
|
||||||
|
@include light-bg-text-color($background);
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
// Define additional color effects based on Dracula spec
|
||||||
|
// https://spec.draculatheme.com/
|
||||||
|
:root {
|
||||||
|
--r-bold-color: #{$orange};
|
||||||
|
--r-italic-color: #{$yellow};
|
||||||
|
--r-inline-code-color: #{$inlineCodeColor};
|
||||||
|
--r-list-bullet-color: #{$listBulletColor};
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal {
|
||||||
|
strong, b {
|
||||||
|
color: var(--r-bold-color);
|
||||||
|
}
|
||||||
|
em, i, blockquote {
|
||||||
|
color: var(--r-italic-color);
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
color: var(--r-inline-code-color);
|
||||||
|
}
|
||||||
|
// Dracula colored list bullets and numbers
|
||||||
|
ul, ol {
|
||||||
|
li::marker {
|
||||||
|
color: var(--r-list-bullet-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -18,10 +18,6 @@
|
|||||||
/**
|
/**
|
||||||
* Solarized colors by Ethan Schoonover
|
* Solarized colors by Ethan Schoonover
|
||||||
*/
|
*/
|
||||||
html * {
|
|
||||||
color-profile: sRGB;
|
|
||||||
rendering-intent: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Solarized colors
|
// Solarized colors
|
||||||
$base03: #002b36;
|
$base03: #002b36;
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ $linkColor: #51483D;
|
|||||||
$linkColorHover: lighten( $linkColor, 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
$selectionBackgroundColor: #26351C;
|
$selectionBackgroundColor: #26351C;
|
||||||
|
|
||||||
|
$overlayElementBgColor: 0, 0, 0;
|
||||||
|
$overlayElementFgColor: 240, 240, 240;
|
||||||
|
|
||||||
.reveal a {
|
.reveal a {
|
||||||
line-height: 1.3em;
|
line-height: 1.3em;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ $linkColor: #00008B;
|
|||||||
$linkColorHover: lighten( $linkColor, 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
$selectionBackgroundColor: rgba(0, 0, 0, 0.99);
|
$selectionBackgroundColor: rgba(0, 0, 0, 0.99);
|
||||||
|
|
||||||
|
$overlayElementBgColor: 0, 0, 0;
|
||||||
|
$overlayElementFgColor: 240, 240, 240;
|
||||||
|
|
||||||
// Change text colors against dark slide backgrounds
|
// Change text colors against dark slide backgrounds
|
||||||
@include dark-bg-text-color(#fff);
|
@include dark-bg-text-color(#fff);
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ $linkColor: #3b759e;
|
|||||||
$linkColorHover: lighten( $linkColor, 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
$selectionBackgroundColor: #134674;
|
$selectionBackgroundColor: #134674;
|
||||||
|
|
||||||
|
$overlayElementBgColor: 0, 0, 0;
|
||||||
|
$overlayElementFgColor: 240, 240, 240;
|
||||||
|
|
||||||
// Fix links so they are not cut off
|
// Fix links so they are not cut off
|
||||||
.reveal a {
|
.reveal a {
|
||||||
line-height: 1.3em;
|
line-height: 1.3em;
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ $linkColor: $blue;
|
|||||||
$linkColorHover: lighten( $linkColor, 20% );
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
$selectionBackgroundColor: $magenta;
|
$selectionBackgroundColor: $magenta;
|
||||||
|
|
||||||
|
$overlayElementBgColor: 0, 0, 0;
|
||||||
|
$overlayElementFgColor: 240, 240, 240;
|
||||||
|
|
||||||
// Background generator
|
// Background generator
|
||||||
// @mixin bodyBackground() {
|
// @mixin bodyBackground() {
|
||||||
// @include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) );
|
// @include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) );
|
||||||
|
|||||||
52
css/theme/source/white-contrast.scss
Normal file
52
css/theme/source/white-contrast.scss
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* White compact & high contrast reveal.js theme, with headers not in capitals.
|
||||||
|
*
|
||||||
|
* By Peter Kehl. Based on white.(s)css by Hakim El Hattab, http://hakim.se
|
||||||
|
*
|
||||||
|
* - Keep the source similar to black.css - for easy comparison.
|
||||||
|
* - $mainFontSize controls code blocks, too (although under some ratio).
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Default mixins and settings -----------------
|
||||||
|
@import "../template/mixins";
|
||||||
|
@import "../template/settings";
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Include theme-specific fonts
|
||||||
|
@import url(./fonts/source-sans-pro/source-sans-pro.css);
|
||||||
|
|
||||||
|
|
||||||
|
// Override theme settings (see ../template/settings.scss)
|
||||||
|
$backgroundColor: #fff;
|
||||||
|
|
||||||
|
$mainColor: #000;
|
||||||
|
$headingColor: #000;
|
||||||
|
|
||||||
|
$mainFontSize: 42px;
|
||||||
|
$mainFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||||
|
$headingFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||||
|
$headingTextShadow: none;
|
||||||
|
$headingLetterSpacing: normal;
|
||||||
|
$headingTextTransform: uppercase;
|
||||||
|
$headingFontWeight: 600;
|
||||||
|
$linkColor: #2a76dd;
|
||||||
|
$linkColorHover: lighten( $linkColor, 15% );
|
||||||
|
$selectionBackgroundColor: lighten( $linkColor, 25% );
|
||||||
|
|
||||||
|
$heading1Size: 2.5em;
|
||||||
|
$heading2Size: 1.6em;
|
||||||
|
$heading3Size: 1.3em;
|
||||||
|
$heading4Size: 1.0em;
|
||||||
|
|
||||||
|
$overlayElementBgColor: 0, 0, 0;
|
||||||
|
$overlayElementFgColor: 240, 240, 240;
|
||||||
|
|
||||||
|
// Change text colors against dark slide backgrounds
|
||||||
|
@include dark-bg-text-color(#fff);
|
||||||
|
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
||||||
@@ -37,6 +37,9 @@ $heading2Size: 1.6em;
|
|||||||
$heading3Size: 1.3em;
|
$heading3Size: 1.3em;
|
||||||
$heading4Size: 1.0em;
|
$heading4Size: 1.0em;
|
||||||
|
|
||||||
|
$overlayElementBgColor: 0, 0, 0;
|
||||||
|
$overlayElementFgColor: 240, 240, 240;
|
||||||
|
|
||||||
// Change text colors against dark slide backgrounds
|
// Change text colors against dark slide backgrounds
|
||||||
@include dark-bg-text-color(#fff);
|
@include dark-bg-text-color(#fff);
|
||||||
|
|
||||||
|
|||||||
@@ -25,4 +25,6 @@
|
|||||||
--r-link-color-hover: #{$linkColorHover};
|
--r-link-color-hover: #{$linkColorHover};
|
||||||
--r-selection-background-color: #{$selectionBackgroundColor};
|
--r-selection-background-color: #{$selectionBackgroundColor};
|
||||||
--r-selection-color: #{$selectionColor};
|
--r-selection-color: #{$selectionColor};
|
||||||
|
--r-overlay-element-bg-color: #{$overlayElementBgColor};
|
||||||
|
--r-overlay-element-fg-color: #{$overlayElementFgColor};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ $linkColorHover: lighten( $linkColor, 20% );
|
|||||||
$selectionBackgroundColor: #FF5E99;
|
$selectionBackgroundColor: #FF5E99;
|
||||||
$selectionColor: #fff;
|
$selectionColor: #fff;
|
||||||
|
|
||||||
|
// Colors used for UI elements that are overlaid on top of
|
||||||
|
// the presentation
|
||||||
|
$overlayElementBgColor: 240, 240, 240;
|
||||||
|
$overlayElementFgColor: 0, 0, 0;
|
||||||
|
|
||||||
// Generates the presentation background, can be overridden
|
// Generates the presentation background, can be overridden
|
||||||
// to return a background image or gradient
|
// to return a background image or gradient
|
||||||
@mixin bodyBackground() {
|
@mixin bodyBackground() {
|
||||||
|
|||||||
41
demo.html
41
demo.html
@@ -52,7 +52,7 @@
|
|||||||
<p>Slides can be nested inside of each other.</p>
|
<p>Slides can be nested inside of each other.</p>
|
||||||
<p>Use the <em>Space</em> key to navigate through all slides.</p>
|
<p>Use the <em>Space</em> key to navigate through all slides.</p>
|
||||||
<br>
|
<br>
|
||||||
<a href="#" class="navigate-down">
|
<a href="#/2/1" class="navigate-down">
|
||||||
<img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow">
|
<img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow">
|
||||||
</a>
|
</a>
|
||||||
</section>
|
</section>
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
|
|
||||||
<section data-auto-animate>
|
<section data-auto-animate>
|
||||||
<h2 data-id="code-title">Pretty Code</h2>
|
<h2 data-id="code-title">Pretty Code</h2>
|
||||||
<pre data-id="code-animation"><code class="hljs" data-trim data-line-numbers>
|
<pre data-id="code-animation"><code class="hljs javascript" data-trim data-line-numbers>
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
function Example() {
|
function Example() {
|
||||||
@@ -101,8 +101,8 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-auto-animate>
|
<section data-auto-animate>
|
||||||
<h2 data-id="code-title">With animations</h2>
|
<h2 data-id="code-title">With Animations</h2>
|
||||||
<pre data-id="code-animation"><code class="hljs" data-trim data-line-numbers="|4,8-11|17|22-24"><script type="text/template">
|
<pre data-id="code-animation"><code class="hljs javascript" data-trim data-line-numbers="|4,8-11|17|22-24"><script type="text/template">
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
function Example() {
|
function Example() {
|
||||||
@@ -181,14 +181,14 @@
|
|||||||
|
|
||||||
<section data-markdown>
|
<section data-markdown>
|
||||||
<script type="text/template">
|
<script type="text/template">
|
||||||
## Markdown support
|
## Markdown Support
|
||||||
|
|
||||||
Write content using inline or external Markdown.
|
Write content using inline or external Markdown.
|
||||||
Instructions and more info available in the [docs](https://revealjs.com/markdown/).
|
Instructions and more info available in the [docs](https://revealjs.com/markdown/).
|
||||||
|
|
||||||
```html []
|
```html []
|
||||||
<section data-markdown>
|
<section data-markdown>
|
||||||
## Markdown support
|
## Markdown Support
|
||||||
|
|
||||||
Write content using inline or external Markdown.
|
Write content using inline or external Markdown.
|
||||||
Instructions and more info available in the [docs](https://revealjs.com/markdown/).
|
Instructions and more info available in the [docs](https://revealjs.com/markdown/).
|
||||||
@@ -249,17 +249,17 @@
|
|||||||
<p>
|
<p>
|
||||||
reveal.js comes with a few themes built in: <br>
|
reveal.js comes with a few themes built in: <br>
|
||||||
<!-- Hacks to swap themes after the page has loaded. Not flexible and only intended for the reveal.js demo deck. -->
|
<!-- Hacks to swap themes after the page has loaded. Not flexible and only intended for the reveal.js demo deck. -->
|
||||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/black.css'); return false;">Black (default)</a> -
|
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/black.css'); return false;">Black (default)</a> -
|
||||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/white.css'); return false;">White</a> -
|
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/white.css'); return false;">White</a> -
|
||||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/league.css'); return false;">League</a> -
|
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/league.css'); return false;">League</a> -
|
||||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/sky.css'); return false;">Sky</a> -
|
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/sky.css'); return false;">Sky</a> -
|
||||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/beige.css'); return false;">Beige</a> -
|
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/beige.css'); return false;">Beige</a> -
|
||||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/simple.css'); return false;">Simple</a> <br>
|
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/simple.css'); return false;">Simple</a> <br>
|
||||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/serif.css'); return false;">Serif</a> -
|
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/serif.css'); return false;">Serif</a> -
|
||||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/blood.css'); return false;">Blood</a> -
|
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/blood.css'); return false;">Blood</a> -
|
||||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/night.css'); return false;">Night</a> -
|
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/night.css'); return false;">Night</a> -
|
||||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/moon.css'); return false;">Moon</a> -
|
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/moon.css'); return false;">Moon</a> -
|
||||||
<a href="#" onclick="document.getElementById('theme').setAttribute('href','dist/theme/solarized.css'); return false;">Solarized</a>
|
<a href="#/themes" onclick="document.getElementById('theme').setAttribute('href','dist/theme/solarized.css'); return false;">Solarized</a>
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -273,6 +273,11 @@
|
|||||||
<img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow">
|
<img class="r-frame" style="background: rgba(255,255,255,0.1);" width="178" height="238" data-src="https://static.slid.es/reveal/arrow.png" alt="Down arrow">
|
||||||
</a>
|
</a>
|
||||||
</section>
|
</section>
|
||||||
|
<section data-background-gradient="linear-gradient(to bottom, #283b95, #17b2c3)">
|
||||||
|
<h2>Gradient Backgrounds</h2>
|
||||||
|
<pre><code class="hljs html wrap"><section data-background-gradient=
|
||||||
|
"linear-gradient(to bottom, #ddd, #191919)"></code></pre>
|
||||||
|
</section>
|
||||||
<section data-background="https://static.slid.es/reveal/image-placeholder.png">
|
<section data-background="https://static.slid.es/reveal/image-placeholder.png">
|
||||||
<h2>Image Backgrounds</h2>
|
<h2>Image Backgrounds</h2>
|
||||||
<pre><code class="hljs html"><section data-background="image.png"></code></pre>
|
<pre><code class="hljs html"><section data-background="image.png"></code></pre>
|
||||||
@@ -281,7 +286,7 @@
|
|||||||
<h2>Tiled Backgrounds</h2>
|
<h2>Tiled Backgrounds</h2>
|
||||||
<pre><code class="hljs html" style="word-wrap: break-word;"><section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"></code></pre>
|
<pre><code class="hljs html" style="word-wrap: break-word;"><section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"></code></pre>
|
||||||
</section>
|
</section>
|
||||||
<section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4" data-background-color="#000000">
|
<section data-background-video="https://static.slid.es/site/homepage/v1/homepage-video-editor.mp4" data-background-color="#000000">
|
||||||
<div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;">
|
<div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;">
|
||||||
<h2>Video Backgrounds</h2>
|
<h2>Video Backgrounds</h2>
|
||||||
<pre><code class="hljs html" style="word-wrap: break-word;"><section data-background-video="video.mp4,video.webm"></code></pre>
|
<pre><code class="hljs html" style="word-wrap: break-word;"><section data-background-video="video.mp4,video.webm"></code></pre>
|
||||||
|
|||||||
6
dist/reveal.css
vendored
6
dist/reveal.css
vendored
File diff suppressed because one or more lines are too long
6
dist/reveal.esm.js
vendored
6
dist/reveal.esm.js
vendored
File diff suppressed because one or more lines are too long
1
dist/reveal.esm.js.map
vendored
Normal file
1
dist/reveal.esm.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
6
dist/reveal.js
vendored
6
dist/reveal.js
vendored
File diff suppressed because one or more lines are too long
1
dist/reveal.js.map
vendored
Normal file
1
dist/reveal.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
16
dist/theme/beige.css
vendored
16
dist/theme/beige.css
vendored
@@ -37,16 +37,18 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
|||||||
--r-link-color-hover: #c0a86e;
|
--r-link-color-hover: #c0a86e;
|
||||||
--r-selection-background-color: rgba(79, 64, 28, 0.99);
|
--r-selection-background-color: rgba(79, 64, 28, 0.99);
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 0, 0, 0;
|
||||||
|
--r-overlay-element-fg-color: 240, 240, 240;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
background: #f7f2d3;
|
background: rgb(247, 242, 211);
|
||||||
background: -moz-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
background: -moz-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
||||||
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, white), color-stop(100%, #f7f2d3));
|
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgb(255, 255, 255)), color-stop(100%, rgb(247, 242, 211)));
|
||||||
background: -webkit-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
background: -webkit-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
||||||
background: -o-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
background: -o-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
||||||
background: -ms-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
background: -ms-radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
||||||
background: radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
|
background: radial-gradient(center, circle cover, rgb(255, 255, 255) 0%, rgb(247, 242, 211) 100%);
|
||||||
background-color: var(--r-background-color);
|
background-color: var(--r-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
362
dist/theme/black-contrast.css
vendored
Normal file
362
dist/theme/black-contrast.css
vendored
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
/**
|
||||||
|
* Black compact & high contrast reveal.js theme, with headers not in capitals.
|
||||||
|
*
|
||||||
|
* By Peter Kehl. Based on black.(s)css by Hakim El Hattab, http://hakim.se
|
||||||
|
*
|
||||||
|
* - Keep the source similar to black.css - for easy comparison.
|
||||||
|
* - $mainFontSize controls code blocks, too (although under some ratio).
|
||||||
|
*/
|
||||||
|
@import url(./fonts/source-sans-pro/source-sans-pro.css);
|
||||||
|
section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* GLOBAL STYLES
|
||||||
|
*********************************************/
|
||||||
|
:root {
|
||||||
|
--r-background-color: #000000;
|
||||||
|
--r-main-font: Source Sans Pro, Helvetica, sans-serif;
|
||||||
|
--r-main-font-size: 42px;
|
||||||
|
--r-main-color: #fff;
|
||||||
|
--r-block-margin: 20px;
|
||||||
|
--r-heading-margin: 0 0 20px 0;
|
||||||
|
--r-heading-font: Source Sans Pro, Helvetica, sans-serif;
|
||||||
|
--r-heading-color: #fff;
|
||||||
|
--r-heading-line-height: 1.2;
|
||||||
|
--r-heading-letter-spacing: normal;
|
||||||
|
--r-heading-text-transform: uppercase;
|
||||||
|
--r-heading-text-shadow: none;
|
||||||
|
--r-heading-font-weight: 600;
|
||||||
|
--r-heading1-text-shadow: none;
|
||||||
|
--r-heading1-size: 2.5em;
|
||||||
|
--r-heading2-size: 1.6em;
|
||||||
|
--r-heading3-size: 1.3em;
|
||||||
|
--r-heading4-size: 1em;
|
||||||
|
--r-code-font: monospace;
|
||||||
|
--r-link-color: #42affa;
|
||||||
|
--r-link-color-dark: #068de9;
|
||||||
|
--r-link-color-hover: #8dcffc;
|
||||||
|
--r-selection-background-color: #bee4fd;
|
||||||
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 240, 240, 240;
|
||||||
|
--r-overlay-element-fg-color: 0, 0, 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal-viewport {
|
||||||
|
background: #000000;
|
||||||
|
background-color: var(--r-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal {
|
||||||
|
font-family: var(--r-main-font);
|
||||||
|
font-size: var(--r-main-font-size);
|
||||||
|
font-weight: normal;
|
||||||
|
color: var(--r-main-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ::selection {
|
||||||
|
color: var(--r-selection-color);
|
||||||
|
background: var(--r-selection-background-color);
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ::-moz-selection {
|
||||||
|
color: var(--r-selection-color);
|
||||||
|
background: var(--r-selection-background-color);
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .slides section,
|
||||||
|
.reveal .slides section > section {
|
||||||
|
line-height: 1.3;
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* HEADERS
|
||||||
|
*********************************************/
|
||||||
|
.reveal h1,
|
||||||
|
.reveal h2,
|
||||||
|
.reveal h3,
|
||||||
|
.reveal h4,
|
||||||
|
.reveal h5,
|
||||||
|
.reveal h6 {
|
||||||
|
margin: var(--r-heading-margin);
|
||||||
|
color: var(--r-heading-color);
|
||||||
|
font-family: var(--r-heading-font);
|
||||||
|
font-weight: var(--r-heading-font-weight);
|
||||||
|
line-height: var(--r-heading-line-height);
|
||||||
|
letter-spacing: var(--r-heading-letter-spacing);
|
||||||
|
text-transform: var(--r-heading-text-transform);
|
||||||
|
text-shadow: var(--r-heading-text-shadow);
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h1 {
|
||||||
|
font-size: var(--r-heading1-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h2 {
|
||||||
|
font-size: var(--r-heading2-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h3 {
|
||||||
|
font-size: var(--r-heading3-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h4 {
|
||||||
|
font-size: var(--r-heading4-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h1 {
|
||||||
|
text-shadow: var(--r-heading1-text-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* OTHER
|
||||||
|
*********************************************/
|
||||||
|
.reveal p {
|
||||||
|
margin: var(--r-block-margin) 0;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove trailing margins after titles */
|
||||||
|
.reveal h1:last-child,
|
||||||
|
.reveal h2:last-child,
|
||||||
|
.reveal h3:last-child,
|
||||||
|
.reveal h4:last-child,
|
||||||
|
.reveal h5:last-child,
|
||||||
|
.reveal h6:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure certain elements are never larger than the slide itself */
|
||||||
|
.reveal img,
|
||||||
|
.reveal video,
|
||||||
|
.reveal iframe {
|
||||||
|
max-width: 95%;
|
||||||
|
max-height: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal strong,
|
||||||
|
.reveal b {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal em {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ol,
|
||||||
|
.reveal dl,
|
||||||
|
.reveal ul {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: left;
|
||||||
|
margin: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ol {
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul {
|
||||||
|
list-style-type: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul {
|
||||||
|
list-style-type: square;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul ul {
|
||||||
|
list-style-type: circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul,
|
||||||
|
.reveal ul ol,
|
||||||
|
.reveal ol ol,
|
||||||
|
.reveal ol ul {
|
||||||
|
display: block;
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal dd {
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal blockquote {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 70%;
|
||||||
|
margin: var(--r-block-margin) auto;
|
||||||
|
padding: 5px;
|
||||||
|
font-style: italic;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal blockquote p:first-child,
|
||||||
|
.reveal blockquote p:last-child {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal q {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 90%;
|
||||||
|
margin: var(--r-block-margin) auto;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 0.55em;
|
||||||
|
font-family: var(--r-code-font);
|
||||||
|
line-height: 1.2em;
|
||||||
|
word-wrap: break-word;
|
||||||
|
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal code {
|
||||||
|
font-family: var(--r-code-font);
|
||||||
|
text-transform: none;
|
||||||
|
tab-size: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre code {
|
||||||
|
display: block;
|
||||||
|
padding: 5px;
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 400px;
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .code-wrapper {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .code-wrapper code {
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table {
|
||||||
|
margin: auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th,
|
||||||
|
.reveal table td {
|
||||||
|
text-align: left;
|
||||||
|
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align=center],
|
||||||
|
.reveal table td[align=center] {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align=right],
|
||||||
|
.reveal table td[align=right] {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table tbody tr:last-child th,
|
||||||
|
.reveal table tbody tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal sup {
|
||||||
|
vertical-align: super;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal sub {
|
||||||
|
vertical-align: sub;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.6em;
|
||||||
|
line-height: 1.2em;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small * {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal img {
|
||||||
|
margin: var(--r-block-margin) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* LINKS
|
||||||
|
*********************************************/
|
||||||
|
.reveal a {
|
||||||
|
color: var(--r-link-color);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a:hover {
|
||||||
|
color: var(--r-link-color-hover);
|
||||||
|
text-shadow: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .roll span:after {
|
||||||
|
color: #fff;
|
||||||
|
background: var(--r-link-color-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* Frame helper
|
||||||
|
*********************************************/
|
||||||
|
.reveal .r-frame {
|
||||||
|
border: 4px solid var(--r-main-color);
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a .r-frame {
|
||||||
|
transition: all 0.15s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a:hover .r-frame {
|
||||||
|
border-color: var(--r-link-color);
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* NAVIGATION CONTROLS
|
||||||
|
*********************************************/
|
||||||
|
.reveal .controls {
|
||||||
|
color: var(--r-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* PROGRESS BAR
|
||||||
|
*********************************************/
|
||||||
|
.reveal .progress {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: var(--r-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* PRINT BACKGROUND
|
||||||
|
*********************************************/
|
||||||
|
@media print {
|
||||||
|
.backgrounds {
|
||||||
|
background-color: var(--r-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
dist/theme/black.css
vendored
4
dist/theme/black.css
vendored
@@ -34,8 +34,10 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
|||||||
--r-link-color: #42affa;
|
--r-link-color: #42affa;
|
||||||
--r-link-color-dark: #068de9;
|
--r-link-color-dark: #068de9;
|
||||||
--r-link-color-hover: #8dcffc;
|
--r-link-color-hover: #8dcffc;
|
||||||
--r-selection-background-color: #bee4fd;
|
--r-selection-background-color: rgba(66, 175, 250, 0.75);
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 240, 240, 240;
|
||||||
|
--r-overlay-element-fg-color: 0, 0, 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
2
dist/theme/blood.css
vendored
2
dist/theme/blood.css
vendored
@@ -42,6 +42,8 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
|||||||
--r-link-color-hover: #dd5566;
|
--r-link-color-hover: #dd5566;
|
||||||
--r-selection-background-color: #a23;
|
--r-selection-background-color: #a23;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 240, 240, 240;
|
||||||
|
--r-overlay-element-fg-color: 0, 0, 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
385
dist/theme/dracula.css
vendored
Normal file
385
dist/theme/dracula.css
vendored
Normal file
@@ -0,0 +1,385 @@
|
|||||||
|
/**
|
||||||
|
* Dracula Dark theme for reveal.js.
|
||||||
|
* Based on https://draculatheme.com
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Dracula colors by Zeno Rocha
|
||||||
|
* https://draculatheme.com/contribute
|
||||||
|
*/
|
||||||
|
html * {
|
||||||
|
color-profile: sRGB;
|
||||||
|
rendering-intent: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
|
||||||
|
color: #282A36;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* GLOBAL STYLES
|
||||||
|
*********************************************/
|
||||||
|
:root {
|
||||||
|
--r-background-color: #282A36;
|
||||||
|
--r-main-font: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;
|
||||||
|
--r-main-font-size: 40px;
|
||||||
|
--r-main-color: #F8F8F2;
|
||||||
|
--r-block-margin: 20px;
|
||||||
|
--r-heading-margin: 0 0 20px 0;
|
||||||
|
--r-heading-font: League Gothic, Impact, sans-serif;
|
||||||
|
--r-heading-color: #BD93F9;
|
||||||
|
--r-heading-line-height: 1.2;
|
||||||
|
--r-heading-letter-spacing: normal;
|
||||||
|
--r-heading-text-transform: none;
|
||||||
|
--r-heading-text-shadow: none;
|
||||||
|
--r-heading-font-weight: normal;
|
||||||
|
--r-heading1-text-shadow: none;
|
||||||
|
--r-heading1-size: 3.77em;
|
||||||
|
--r-heading2-size: 2.11em;
|
||||||
|
--r-heading3-size: 1.55em;
|
||||||
|
--r-heading4-size: 1em;
|
||||||
|
--r-code-font: Fira Code, Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
|
||||||
|
--r-link-color: #FF79C6;
|
||||||
|
--r-link-color-dark: #ff2da5;
|
||||||
|
--r-link-color-hover: #8BE9FD;
|
||||||
|
--r-selection-background-color: #44475A;
|
||||||
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 240, 240, 240;
|
||||||
|
--r-overlay-element-fg-color: 0, 0, 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal-viewport {
|
||||||
|
background: #282A36;
|
||||||
|
background-color: var(--r-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal {
|
||||||
|
font-family: var(--r-main-font);
|
||||||
|
font-size: var(--r-main-font-size);
|
||||||
|
font-weight: normal;
|
||||||
|
color: var(--r-main-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ::selection {
|
||||||
|
color: var(--r-selection-color);
|
||||||
|
background: var(--r-selection-background-color);
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ::-moz-selection {
|
||||||
|
color: var(--r-selection-color);
|
||||||
|
background: var(--r-selection-background-color);
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .slides section,
|
||||||
|
.reveal .slides section > section {
|
||||||
|
line-height: 1.3;
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* HEADERS
|
||||||
|
*********************************************/
|
||||||
|
.reveal h1,
|
||||||
|
.reveal h2,
|
||||||
|
.reveal h3,
|
||||||
|
.reveal h4,
|
||||||
|
.reveal h5,
|
||||||
|
.reveal h6 {
|
||||||
|
margin: var(--r-heading-margin);
|
||||||
|
color: var(--r-heading-color);
|
||||||
|
font-family: var(--r-heading-font);
|
||||||
|
font-weight: var(--r-heading-font-weight);
|
||||||
|
line-height: var(--r-heading-line-height);
|
||||||
|
letter-spacing: var(--r-heading-letter-spacing);
|
||||||
|
text-transform: var(--r-heading-text-transform);
|
||||||
|
text-shadow: var(--r-heading-text-shadow);
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h1 {
|
||||||
|
font-size: var(--r-heading1-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h2 {
|
||||||
|
font-size: var(--r-heading2-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h3 {
|
||||||
|
font-size: var(--r-heading3-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h4 {
|
||||||
|
font-size: var(--r-heading4-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h1 {
|
||||||
|
text-shadow: var(--r-heading1-text-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* OTHER
|
||||||
|
*********************************************/
|
||||||
|
.reveal p {
|
||||||
|
margin: var(--r-block-margin) 0;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove trailing margins after titles */
|
||||||
|
.reveal h1:last-child,
|
||||||
|
.reveal h2:last-child,
|
||||||
|
.reveal h3:last-child,
|
||||||
|
.reveal h4:last-child,
|
||||||
|
.reveal h5:last-child,
|
||||||
|
.reveal h6:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure certain elements are never larger than the slide itself */
|
||||||
|
.reveal img,
|
||||||
|
.reveal video,
|
||||||
|
.reveal iframe {
|
||||||
|
max-width: 95%;
|
||||||
|
max-height: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal strong,
|
||||||
|
.reveal b {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal em {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ol,
|
||||||
|
.reveal dl,
|
||||||
|
.reveal ul {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: left;
|
||||||
|
margin: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ol {
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul {
|
||||||
|
list-style-type: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul {
|
||||||
|
list-style-type: square;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul ul {
|
||||||
|
list-style-type: circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul,
|
||||||
|
.reveal ul ol,
|
||||||
|
.reveal ol ol,
|
||||||
|
.reveal ol ul {
|
||||||
|
display: block;
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal dd {
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal blockquote {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 70%;
|
||||||
|
margin: var(--r-block-margin) auto;
|
||||||
|
padding: 5px;
|
||||||
|
font-style: italic;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal blockquote p:first-child,
|
||||||
|
.reveal blockquote p:last-child {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal q {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 90%;
|
||||||
|
margin: var(--r-block-margin) auto;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 0.55em;
|
||||||
|
font-family: var(--r-code-font);
|
||||||
|
line-height: 1.2em;
|
||||||
|
word-wrap: break-word;
|
||||||
|
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal code {
|
||||||
|
font-family: var(--r-code-font);
|
||||||
|
text-transform: none;
|
||||||
|
tab-size: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre code {
|
||||||
|
display: block;
|
||||||
|
padding: 5px;
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 400px;
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .code-wrapper {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .code-wrapper code {
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table {
|
||||||
|
margin: auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th,
|
||||||
|
.reveal table td {
|
||||||
|
text-align: left;
|
||||||
|
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align=center],
|
||||||
|
.reveal table td[align=center] {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align=right],
|
||||||
|
.reveal table td[align=right] {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table tbody tr:last-child th,
|
||||||
|
.reveal table tbody tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal sup {
|
||||||
|
vertical-align: super;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal sub {
|
||||||
|
vertical-align: sub;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.6em;
|
||||||
|
line-height: 1.2em;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small * {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal img {
|
||||||
|
margin: var(--r-block-margin) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* LINKS
|
||||||
|
*********************************************/
|
||||||
|
.reveal a {
|
||||||
|
color: var(--r-link-color);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a:hover {
|
||||||
|
color: var(--r-link-color-hover);
|
||||||
|
text-shadow: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .roll span:after {
|
||||||
|
color: #fff;
|
||||||
|
background: var(--r-link-color-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* Frame helper
|
||||||
|
*********************************************/
|
||||||
|
.reveal .r-frame {
|
||||||
|
border: 4px solid var(--r-main-color);
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a .r-frame {
|
||||||
|
transition: all 0.15s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a:hover .r-frame {
|
||||||
|
border-color: var(--r-link-color);
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* NAVIGATION CONTROLS
|
||||||
|
*********************************************/
|
||||||
|
.reveal .controls {
|
||||||
|
color: var(--r-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* PROGRESS BAR
|
||||||
|
*********************************************/
|
||||||
|
.reveal .progress {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: var(--r-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* PRINT BACKGROUND
|
||||||
|
*********************************************/
|
||||||
|
@media print {
|
||||||
|
.backgrounds {
|
||||||
|
background-color: var(--r-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:root {
|
||||||
|
--r-bold-color: #FFB86C;
|
||||||
|
--r-italic-color: #F1FA8C;
|
||||||
|
--r-inline-code-color: #50FA7B;
|
||||||
|
--r-list-bullet-color: #8BE9FD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal strong, .reveal b {
|
||||||
|
color: var(--r-bold-color);
|
||||||
|
}
|
||||||
|
.reveal em, .reveal i, .reveal blockquote {
|
||||||
|
color: var(--r-italic-color);
|
||||||
|
}
|
||||||
|
.reveal code {
|
||||||
|
color: var(--r-inline-code-color);
|
||||||
|
}
|
||||||
|
.reveal ul li::marker, .reveal ol li::marker {
|
||||||
|
color: var(--r-list-bullet-color);
|
||||||
|
}
|
||||||
16
dist/theme/league.css
vendored
16
dist/theme/league.css
vendored
@@ -39,16 +39,18 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
|||||||
--r-link-color-hover: #71e9f4;
|
--r-link-color-hover: #71e9f4;
|
||||||
--r-selection-background-color: #FF5E99;
|
--r-selection-background-color: #FF5E99;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 240, 240, 240;
|
||||||
|
--r-overlay-element-fg-color: 0, 0, 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
background: #1c1e20;
|
background: rgb(28, 30, 32);
|
||||||
background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
background: -moz-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
||||||
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20));
|
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgb(85, 90, 95)), color-stop(100%, rgb(28, 30, 32)));
|
||||||
background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
background: -webkit-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
||||||
background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
background: -o-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
||||||
background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
background: -ms-radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
||||||
background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
|
background: radial-gradient(center, circle cover, rgb(85, 90, 95) 0%, rgb(28, 30, 32) 100%);
|
||||||
background-color: var(--r-background-color);
|
background-color: var(--r-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
dist/theme/moon.css
vendored
7
dist/theme/moon.css
vendored
@@ -7,11 +7,6 @@
|
|||||||
/**
|
/**
|
||||||
* Solarized colors by Ethan Schoonover
|
* Solarized colors by Ethan Schoonover
|
||||||
*/
|
*/
|
||||||
html * {
|
|
||||||
color-profile: sRGB;
|
|
||||||
rendering-intent: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
|
section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
|
||||||
color: #222;
|
color: #222;
|
||||||
}
|
}
|
||||||
@@ -44,6 +39,8 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
|||||||
--r-link-color-hover: #78b9e6;
|
--r-link-color-hover: #78b9e6;
|
||||||
--r-selection-background-color: #d33682;
|
--r-selection-background-color: #d33682;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 240, 240, 240;
|
||||||
|
--r-overlay-element-fg-color: 0, 0, 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
2
dist/theme/night.css
vendored
2
dist/theme/night.css
vendored
@@ -37,6 +37,8 @@ section.has-light-background, section.has-light-background h1, section.has-light
|
|||||||
--r-link-color-hover: #f3d7ac;
|
--r-link-color-hover: #f3d7ac;
|
||||||
--r-selection-background-color: #e7ad52;
|
--r-selection-background-color: #e7ad52;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 240, 240, 240;
|
||||||
|
--r-overlay-element-fg-color: 0, 0, 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
2
dist/theme/serif.css
vendored
2
dist/theme/serif.css
vendored
@@ -40,6 +40,8 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
|||||||
--r-link-color-hover: #8b7c69;
|
--r-link-color-hover: #8b7c69;
|
||||||
--r-selection-background-color: #26351C;
|
--r-selection-background-color: #26351C;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 0, 0, 0;
|
||||||
|
--r-overlay-element-fg-color: 240, 240, 240;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
2
dist/theme/simple.css
vendored
2
dist/theme/simple.css
vendored
@@ -39,6 +39,8 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
|||||||
--r-link-color-hover: #0000f1;
|
--r-link-color-hover: #0000f1;
|
||||||
--r-selection-background-color: rgba(0, 0, 0, 0.99);
|
--r-selection-background-color: rgba(0, 0, 0, 0.99);
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 0, 0, 0;
|
||||||
|
--r-overlay-element-fg-color: 240, 240, 240;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
2
dist/theme/sky.css
vendored
2
dist/theme/sky.css
vendored
@@ -41,6 +41,8 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
|||||||
--r-link-color-hover: #74a7cb;
|
--r-link-color-hover: #74a7cb;
|
||||||
--r-selection-background-color: #134674;
|
--r-selection-background-color: #134674;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 0, 0, 0;
|
||||||
|
--r-overlay-element-fg-color: 240, 240, 240;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
2
dist/theme/solarized.css
vendored
2
dist/theme/solarized.css
vendored
@@ -40,6 +40,8 @@ html * {
|
|||||||
--r-link-color-hover: #78b9e6;
|
--r-link-color-hover: #78b9e6;
|
||||||
--r-selection-background-color: #d33682;
|
--r-selection-background-color: #d33682;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 0, 0, 0;
|
||||||
|
--r-overlay-element-fg-color: 240, 240, 240;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
362
dist/theme/white-contrast.css
vendored
Normal file
362
dist/theme/white-contrast.css
vendored
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
/**
|
||||||
|
* White compact & high contrast reveal.js theme, with headers not in capitals.
|
||||||
|
*
|
||||||
|
* By Peter Kehl. Based on white.(s)css by Hakim El Hattab, http://hakim.se
|
||||||
|
*
|
||||||
|
* - Keep the source similar to black.css - for easy comparison.
|
||||||
|
* - $mainFontSize controls code blocks, too (although under some ratio).
|
||||||
|
*/
|
||||||
|
@import url(./fonts/source-sans-pro/source-sans-pro.css);
|
||||||
|
section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* GLOBAL STYLES
|
||||||
|
*********************************************/
|
||||||
|
:root {
|
||||||
|
--r-background-color: #fff;
|
||||||
|
--r-main-font: Source Sans Pro, Helvetica, sans-serif;
|
||||||
|
--r-main-font-size: 42px;
|
||||||
|
--r-main-color: #000;
|
||||||
|
--r-block-margin: 20px;
|
||||||
|
--r-heading-margin: 0 0 20px 0;
|
||||||
|
--r-heading-font: Source Sans Pro, Helvetica, sans-serif;
|
||||||
|
--r-heading-color: #000;
|
||||||
|
--r-heading-line-height: 1.2;
|
||||||
|
--r-heading-letter-spacing: normal;
|
||||||
|
--r-heading-text-transform: uppercase;
|
||||||
|
--r-heading-text-shadow: none;
|
||||||
|
--r-heading-font-weight: 600;
|
||||||
|
--r-heading1-text-shadow: none;
|
||||||
|
--r-heading1-size: 2.5em;
|
||||||
|
--r-heading2-size: 1.6em;
|
||||||
|
--r-heading3-size: 1.3em;
|
||||||
|
--r-heading4-size: 1em;
|
||||||
|
--r-code-font: monospace;
|
||||||
|
--r-link-color: #2a76dd;
|
||||||
|
--r-link-color-dark: #1a53a1;
|
||||||
|
--r-link-color-hover: #6ca0e8;
|
||||||
|
--r-selection-background-color: #98bdef;
|
||||||
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 0, 0, 0;
|
||||||
|
--r-overlay-element-fg-color: 240, 240, 240;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal-viewport {
|
||||||
|
background: #fff;
|
||||||
|
background-color: var(--r-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal {
|
||||||
|
font-family: var(--r-main-font);
|
||||||
|
font-size: var(--r-main-font-size);
|
||||||
|
font-weight: normal;
|
||||||
|
color: var(--r-main-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ::selection {
|
||||||
|
color: var(--r-selection-color);
|
||||||
|
background: var(--r-selection-background-color);
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ::-moz-selection {
|
||||||
|
color: var(--r-selection-color);
|
||||||
|
background: var(--r-selection-background-color);
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .slides section,
|
||||||
|
.reveal .slides section > section {
|
||||||
|
line-height: 1.3;
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* HEADERS
|
||||||
|
*********************************************/
|
||||||
|
.reveal h1,
|
||||||
|
.reveal h2,
|
||||||
|
.reveal h3,
|
||||||
|
.reveal h4,
|
||||||
|
.reveal h5,
|
||||||
|
.reveal h6 {
|
||||||
|
margin: var(--r-heading-margin);
|
||||||
|
color: var(--r-heading-color);
|
||||||
|
font-family: var(--r-heading-font);
|
||||||
|
font-weight: var(--r-heading-font-weight);
|
||||||
|
line-height: var(--r-heading-line-height);
|
||||||
|
letter-spacing: var(--r-heading-letter-spacing);
|
||||||
|
text-transform: var(--r-heading-text-transform);
|
||||||
|
text-shadow: var(--r-heading-text-shadow);
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h1 {
|
||||||
|
font-size: var(--r-heading1-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h2 {
|
||||||
|
font-size: var(--r-heading2-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h3 {
|
||||||
|
font-size: var(--r-heading3-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h4 {
|
||||||
|
font-size: var(--r-heading4-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h1 {
|
||||||
|
text-shadow: var(--r-heading1-text-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* OTHER
|
||||||
|
*********************************************/
|
||||||
|
.reveal p {
|
||||||
|
margin: var(--r-block-margin) 0;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove trailing margins after titles */
|
||||||
|
.reveal h1:last-child,
|
||||||
|
.reveal h2:last-child,
|
||||||
|
.reveal h3:last-child,
|
||||||
|
.reveal h4:last-child,
|
||||||
|
.reveal h5:last-child,
|
||||||
|
.reveal h6:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure certain elements are never larger than the slide itself */
|
||||||
|
.reveal img,
|
||||||
|
.reveal video,
|
||||||
|
.reveal iframe {
|
||||||
|
max-width: 95%;
|
||||||
|
max-height: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal strong,
|
||||||
|
.reveal b {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal em {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ol,
|
||||||
|
.reveal dl,
|
||||||
|
.reveal ul {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: left;
|
||||||
|
margin: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ol {
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul {
|
||||||
|
list-style-type: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul {
|
||||||
|
list-style-type: square;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul ul {
|
||||||
|
list-style-type: circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul,
|
||||||
|
.reveal ul ol,
|
||||||
|
.reveal ol ol,
|
||||||
|
.reveal ol ul {
|
||||||
|
display: block;
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal dd {
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal blockquote {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 70%;
|
||||||
|
margin: var(--r-block-margin) auto;
|
||||||
|
padding: 5px;
|
||||||
|
font-style: italic;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal blockquote p:first-child,
|
||||||
|
.reveal blockquote p:last-child {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal q {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 90%;
|
||||||
|
margin: var(--r-block-margin) auto;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 0.55em;
|
||||||
|
font-family: var(--r-code-font);
|
||||||
|
line-height: 1.2em;
|
||||||
|
word-wrap: break-word;
|
||||||
|
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal code {
|
||||||
|
font-family: var(--r-code-font);
|
||||||
|
text-transform: none;
|
||||||
|
tab-size: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre code {
|
||||||
|
display: block;
|
||||||
|
padding: 5px;
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 400px;
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .code-wrapper {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .code-wrapper code {
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table {
|
||||||
|
margin: auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th,
|
||||||
|
.reveal table td {
|
||||||
|
text-align: left;
|
||||||
|
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align=center],
|
||||||
|
.reveal table td[align=center] {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align=right],
|
||||||
|
.reveal table td[align=right] {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table tbody tr:last-child th,
|
||||||
|
.reveal table tbody tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal sup {
|
||||||
|
vertical-align: super;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal sub {
|
||||||
|
vertical-align: sub;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.6em;
|
||||||
|
line-height: 1.2em;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small * {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal img {
|
||||||
|
margin: var(--r-block-margin) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* LINKS
|
||||||
|
*********************************************/
|
||||||
|
.reveal a {
|
||||||
|
color: var(--r-link-color);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a:hover {
|
||||||
|
color: var(--r-link-color-hover);
|
||||||
|
text-shadow: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .roll span:after {
|
||||||
|
color: #fff;
|
||||||
|
background: var(--r-link-color-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* Frame helper
|
||||||
|
*********************************************/
|
||||||
|
.reveal .r-frame {
|
||||||
|
border: 4px solid var(--r-main-color);
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a .r-frame {
|
||||||
|
transition: all 0.15s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a:hover .r-frame {
|
||||||
|
border-color: var(--r-link-color);
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* NAVIGATION CONTROLS
|
||||||
|
*********************************************/
|
||||||
|
.reveal .controls {
|
||||||
|
color: var(--r-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* PROGRESS BAR
|
||||||
|
*********************************************/
|
||||||
|
.reveal .progress {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: var(--r-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* PRINT BACKGROUND
|
||||||
|
*********************************************/
|
||||||
|
@media print {
|
||||||
|
.backgrounds {
|
||||||
|
background-color: var(--r-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
2
dist/theme/white.css
vendored
2
dist/theme/white.css
vendored
@@ -36,6 +36,8 @@ section.has-dark-background, section.has-dark-background h1, section.has-dark-ba
|
|||||||
--r-link-color-hover: #6ca0e8;
|
--r-link-color-hover: #6ca0e8;
|
||||||
--r-selection-background-color: #98bdef;
|
--r-selection-background-color: #98bdef;
|
||||||
--r-selection-color: #fff;
|
--r-selection-color: #fff;
|
||||||
|
--r-overlay-element-bg-color: 0, 0, 0;
|
||||||
|
--r-overlay-element-fg-color: 240, 240, 240;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reveal-viewport {
|
.reveal-viewport {
|
||||||
|
|||||||
360
dist/theme/white_contrast_compact_verbatim_headers.css
vendored
Normal file
360
dist/theme/white_contrast_compact_verbatim_headers.css
vendored
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
/**
|
||||||
|
* White compact & high contrast reveal.js theme, with headers not in capitals.
|
||||||
|
*
|
||||||
|
* By Peter Kehl. Based on white.(s)css by Hakim El Hattab, http://hakim.se
|
||||||
|
*
|
||||||
|
* - Keep the source similar to black.css - for easy comparison.
|
||||||
|
* - $mainFontSize controls code blocks, too (although under some ratio).
|
||||||
|
*/
|
||||||
|
@import url(./fonts/source-sans-pro/source-sans-pro.css);
|
||||||
|
section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* GLOBAL STYLES
|
||||||
|
*********************************************/
|
||||||
|
:root {
|
||||||
|
--r-background-color: #fff;
|
||||||
|
--r-main-font: Source Sans Pro, Helvetica, sans-serif;
|
||||||
|
--r-main-font-size: 25px;
|
||||||
|
--r-main-color: #000;
|
||||||
|
--r-block-margin: 20px;
|
||||||
|
--r-heading-margin: 0 0 20px 0;
|
||||||
|
--r-heading-font: Source Sans Pro, Helvetica, sans-serif;
|
||||||
|
--r-heading-color: #000;
|
||||||
|
--r-heading-line-height: 1.2;
|
||||||
|
--r-heading-letter-spacing: normal;
|
||||||
|
--r-heading-text-transform: none;
|
||||||
|
--r-heading-text-shadow: none;
|
||||||
|
--r-heading-font-weight: 450;
|
||||||
|
--r-heading1-text-shadow: none;
|
||||||
|
--r-heading1-size: 2.5em;
|
||||||
|
--r-heading2-size: 1.6em;
|
||||||
|
--r-heading3-size: 1.3em;
|
||||||
|
--r-heading4-size: 1em;
|
||||||
|
--r-code-font: monospace;
|
||||||
|
--r-link-color: #2a76dd;
|
||||||
|
--r-link-color-dark: #1a53a1;
|
||||||
|
--r-link-color-hover: #6ca0e8;
|
||||||
|
--r-selection-background-color: #98bdef;
|
||||||
|
--r-selection-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal-viewport {
|
||||||
|
background: #fff;
|
||||||
|
background-color: var(--r-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal {
|
||||||
|
font-family: var(--r-main-font);
|
||||||
|
font-size: var(--r-main-font-size);
|
||||||
|
font-weight: normal;
|
||||||
|
color: var(--r-main-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ::selection {
|
||||||
|
color: var(--r-selection-color);
|
||||||
|
background: var(--r-selection-background-color);
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ::-moz-selection {
|
||||||
|
color: var(--r-selection-color);
|
||||||
|
background: var(--r-selection-background-color);
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .slides section,
|
||||||
|
.reveal .slides section > section {
|
||||||
|
line-height: 1.3;
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* HEADERS
|
||||||
|
*********************************************/
|
||||||
|
.reveal h1,
|
||||||
|
.reveal h2,
|
||||||
|
.reveal h3,
|
||||||
|
.reveal h4,
|
||||||
|
.reveal h5,
|
||||||
|
.reveal h6 {
|
||||||
|
margin: var(--r-heading-margin);
|
||||||
|
color: var(--r-heading-color);
|
||||||
|
font-family: var(--r-heading-font);
|
||||||
|
font-weight: var(--r-heading-font-weight);
|
||||||
|
line-height: var(--r-heading-line-height);
|
||||||
|
letter-spacing: var(--r-heading-letter-spacing);
|
||||||
|
text-transform: var(--r-heading-text-transform);
|
||||||
|
text-shadow: var(--r-heading-text-shadow);
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h1 {
|
||||||
|
font-size: var(--r-heading1-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h2 {
|
||||||
|
font-size: var(--r-heading2-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h3 {
|
||||||
|
font-size: var(--r-heading3-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h4 {
|
||||||
|
font-size: var(--r-heading4-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h1 {
|
||||||
|
text-shadow: var(--r-heading1-text-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* OTHER
|
||||||
|
*********************************************/
|
||||||
|
.reveal p {
|
||||||
|
margin: var(--r-block-margin) 0;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove trailing margins after titles */
|
||||||
|
.reveal h1:last-child,
|
||||||
|
.reveal h2:last-child,
|
||||||
|
.reveal h3:last-child,
|
||||||
|
.reveal h4:last-child,
|
||||||
|
.reveal h5:last-child,
|
||||||
|
.reveal h6:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure certain elements are never larger than the slide itself */
|
||||||
|
.reveal img,
|
||||||
|
.reveal video,
|
||||||
|
.reveal iframe {
|
||||||
|
max-width: 95%;
|
||||||
|
max-height: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal strong,
|
||||||
|
.reveal b {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal em {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ol,
|
||||||
|
.reveal dl,
|
||||||
|
.reveal ul {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: left;
|
||||||
|
margin: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ol {
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul {
|
||||||
|
list-style-type: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul {
|
||||||
|
list-style-type: square;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul ul {
|
||||||
|
list-style-type: circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul,
|
||||||
|
.reveal ul ol,
|
||||||
|
.reveal ol ol,
|
||||||
|
.reveal ol ul {
|
||||||
|
display: block;
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal dd {
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal blockquote {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 70%;
|
||||||
|
margin: var(--r-block-margin) auto;
|
||||||
|
padding: 5px;
|
||||||
|
font-style: italic;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal blockquote p:first-child,
|
||||||
|
.reveal blockquote p:last-child {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal q {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 90%;
|
||||||
|
margin: var(--r-block-margin) auto;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 0.55em;
|
||||||
|
font-family: var(--r-code-font);
|
||||||
|
line-height: 1.2em;
|
||||||
|
word-wrap: break-word;
|
||||||
|
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal code {
|
||||||
|
font-family: var(--r-code-font);
|
||||||
|
text-transform: none;
|
||||||
|
tab-size: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre code {
|
||||||
|
display: block;
|
||||||
|
padding: 5px;
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 400px;
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .code-wrapper {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .code-wrapper code {
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table {
|
||||||
|
margin: auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th,
|
||||||
|
.reveal table td {
|
||||||
|
text-align: left;
|
||||||
|
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align=center],
|
||||||
|
.reveal table td[align=center] {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align=right],
|
||||||
|
.reveal table td[align=right] {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table tbody tr:last-child th,
|
||||||
|
.reveal table tbody tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal sup {
|
||||||
|
vertical-align: super;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal sub {
|
||||||
|
vertical-align: sub;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.6em;
|
||||||
|
line-height: 1.2em;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small * {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal img {
|
||||||
|
margin: var(--r-block-margin) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* LINKS
|
||||||
|
*********************************************/
|
||||||
|
.reveal a {
|
||||||
|
color: var(--r-link-color);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a:hover {
|
||||||
|
color: var(--r-link-color-hover);
|
||||||
|
text-shadow: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .roll span:after {
|
||||||
|
color: #fff;
|
||||||
|
background: var(--r-link-color-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* Frame helper
|
||||||
|
*********************************************/
|
||||||
|
.reveal .r-frame {
|
||||||
|
border: 4px solid var(--r-main-color);
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a .r-frame {
|
||||||
|
transition: all 0.15s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a:hover .r-frame {
|
||||||
|
border-color: var(--r-link-color);
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* NAVIGATION CONTROLS
|
||||||
|
*********************************************/
|
||||||
|
.reveal .controls {
|
||||||
|
color: var(--r-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* PROGRESS BAR
|
||||||
|
*********************************************/
|
||||||
|
.reveal .progress {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: var(--r-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* PRINT BACKGROUND
|
||||||
|
*********************************************/
|
||||||
|
@media print {
|
||||||
|
.backgrounds {
|
||||||
|
background-color: var(--r-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
526
examples/500-slides.html
Normal file
526
examples/500-slides.html
Normal file
@@ -0,0 +1,526 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
|
||||||
|
<title>reveal.js - 500 slides</title>
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../dist/reveal.css">
|
||||||
|
<link rel="stylesheet" href="../dist/theme/black.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="reveal">
|
||||||
|
<div class="slides">
|
||||||
|
<section><h1>1</h1></section>
|
||||||
|
<section><h1>2</h1></section>
|
||||||
|
<section><h1>3</h1></section>
|
||||||
|
<section><h1>4</h1></section>
|
||||||
|
<section><h1>5</h1></section>
|
||||||
|
<section><h1>6</h1></section>
|
||||||
|
<section><h1>7</h1></section>
|
||||||
|
<section><h1>8</h1></section>
|
||||||
|
<section><h1>9</h1></section>
|
||||||
|
<section><h1>10</h1></section>
|
||||||
|
<section><h1>11</h1></section>
|
||||||
|
<section><h1>12</h1></section>
|
||||||
|
<section><h1>13</h1></section>
|
||||||
|
<section><h1>14</h1></section>
|
||||||
|
<section><h1>15</h1></section>
|
||||||
|
<section><h1>16</h1></section>
|
||||||
|
<section><h1>17</h1></section>
|
||||||
|
<section><h1>18</h1></section>
|
||||||
|
<section><h1>19</h1></section>
|
||||||
|
<section><h1>20</h1></section>
|
||||||
|
<section><h1>21</h1></section>
|
||||||
|
<section><h1>22</h1></section>
|
||||||
|
<section><h1>23</h1></section>
|
||||||
|
<section><h1>24</h1></section>
|
||||||
|
<section><h1>25</h1></section>
|
||||||
|
<section><h1>26</h1></section>
|
||||||
|
<section><h1>27</h1></section>
|
||||||
|
<section><h1>28</h1></section>
|
||||||
|
<section><h1>29</h1></section>
|
||||||
|
<section><h1>30</h1></section>
|
||||||
|
<section><h1>31</h1></section>
|
||||||
|
<section><h1>32</h1></section>
|
||||||
|
<section><h1>33</h1></section>
|
||||||
|
<section><h1>34</h1></section>
|
||||||
|
<section><h1>35</h1></section>
|
||||||
|
<section><h1>36</h1></section>
|
||||||
|
<section><h1>37</h1></section>
|
||||||
|
<section><h1>38</h1></section>
|
||||||
|
<section><h1>39</h1></section>
|
||||||
|
<section><h1>40</h1></section>
|
||||||
|
<section><h1>41</h1></section>
|
||||||
|
<section><h1>42</h1></section>
|
||||||
|
<section><h1>43</h1></section>
|
||||||
|
<section><h1>44</h1></section>
|
||||||
|
<section><h1>45</h1></section>
|
||||||
|
<section><h1>46</h1></section>
|
||||||
|
<section><h1>47</h1></section>
|
||||||
|
<section><h1>48</h1></section>
|
||||||
|
<section><h1>49</h1></section>
|
||||||
|
<section><h1>50</h1></section>
|
||||||
|
<section><h1>51</h1></section>
|
||||||
|
<section><h1>52</h1></section>
|
||||||
|
<section><h1>53</h1></section>
|
||||||
|
<section><h1>54</h1></section>
|
||||||
|
<section><h1>55</h1></section>
|
||||||
|
<section><h1>56</h1></section>
|
||||||
|
<section><h1>57</h1></section>
|
||||||
|
<section><h1>58</h1></section>
|
||||||
|
<section><h1>59</h1></section>
|
||||||
|
<section><h1>60</h1></section>
|
||||||
|
<section><h1>61</h1></section>
|
||||||
|
<section><h1>62</h1></section>
|
||||||
|
<section><h1>63</h1></section>
|
||||||
|
<section><h1>64</h1></section>
|
||||||
|
<section><h1>65</h1></section>
|
||||||
|
<section><h1>66</h1></section>
|
||||||
|
<section><h1>67</h1></section>
|
||||||
|
<section><h1>68</h1></section>
|
||||||
|
<section><h1>69</h1></section>
|
||||||
|
<section><h1>70</h1></section>
|
||||||
|
<section><h1>71</h1></section>
|
||||||
|
<section><h1>72</h1></section>
|
||||||
|
<section><h1>73</h1></section>
|
||||||
|
<section><h1>74</h1></section>
|
||||||
|
<section><h1>75</h1></section>
|
||||||
|
<section><h1>76</h1></section>
|
||||||
|
<section><h1>77</h1></section>
|
||||||
|
<section><h1>78</h1></section>
|
||||||
|
<section><h1>79</h1></section>
|
||||||
|
<section><h1>80</h1></section>
|
||||||
|
<section><h1>81</h1></section>
|
||||||
|
<section><h1>82</h1></section>
|
||||||
|
<section><h1>83</h1></section>
|
||||||
|
<section><h1>84</h1></section>
|
||||||
|
<section><h1>85</h1></section>
|
||||||
|
<section><h1>86</h1></section>
|
||||||
|
<section><h1>87</h1></section>
|
||||||
|
<section><h1>88</h1></section>
|
||||||
|
<section><h1>89</h1></section>
|
||||||
|
<section><h1>90</h1></section>
|
||||||
|
<section><h1>91</h1></section>
|
||||||
|
<section><h1>92</h1></section>
|
||||||
|
<section><h1>93</h1></section>
|
||||||
|
<section><h1>94</h1></section>
|
||||||
|
<section><h1>95</h1></section>
|
||||||
|
<section><h1>96</h1></section>
|
||||||
|
<section><h1>97</h1></section>
|
||||||
|
<section><h1>98</h1></section>
|
||||||
|
<section><h1>99</h1></section>
|
||||||
|
<section><h1>100</h1></section>
|
||||||
|
<section><h1>101</h1></section>
|
||||||
|
<section><h1>102</h1></section>
|
||||||
|
<section><h1>103</h1></section>
|
||||||
|
<section><h1>104</h1></section>
|
||||||
|
<section><h1>105</h1></section>
|
||||||
|
<section><h1>106</h1></section>
|
||||||
|
<section><h1>107</h1></section>
|
||||||
|
<section><h1>108</h1></section>
|
||||||
|
<section><h1>109</h1></section>
|
||||||
|
<section><h1>110</h1></section>
|
||||||
|
<section><h1>111</h1></section>
|
||||||
|
<section><h1>112</h1></section>
|
||||||
|
<section><h1>113</h1></section>
|
||||||
|
<section><h1>114</h1></section>
|
||||||
|
<section><h1>115</h1></section>
|
||||||
|
<section><h1>116</h1></section>
|
||||||
|
<section><h1>117</h1></section>
|
||||||
|
<section><h1>118</h1></section>
|
||||||
|
<section><h1>119</h1></section>
|
||||||
|
<section><h1>120</h1></section>
|
||||||
|
<section><h1>121</h1></section>
|
||||||
|
<section><h1>122</h1></section>
|
||||||
|
<section><h1>123</h1></section>
|
||||||
|
<section><h1>124</h1></section>
|
||||||
|
<section><h1>125</h1></section>
|
||||||
|
<section><h1>126</h1></section>
|
||||||
|
<section><h1>127</h1></section>
|
||||||
|
<section><h1>128</h1></section>
|
||||||
|
<section><h1>129</h1></section>
|
||||||
|
<section><h1>130</h1></section>
|
||||||
|
<section><h1>131</h1></section>
|
||||||
|
<section><h1>132</h1></section>
|
||||||
|
<section><h1>133</h1></section>
|
||||||
|
<section><h1>134</h1></section>
|
||||||
|
<section><h1>135</h1></section>
|
||||||
|
<section><h1>136</h1></section>
|
||||||
|
<section><h1>137</h1></section>
|
||||||
|
<section><h1>138</h1></section>
|
||||||
|
<section><h1>139</h1></section>
|
||||||
|
<section><h1>140</h1></section>
|
||||||
|
<section><h1>141</h1></section>
|
||||||
|
<section><h1>142</h1></section>
|
||||||
|
<section><h1>143</h1></section>
|
||||||
|
<section><h1>144</h1></section>
|
||||||
|
<section><h1>145</h1></section>
|
||||||
|
<section><h1>146</h1></section>
|
||||||
|
<section><h1>147</h1></section>
|
||||||
|
<section><h1>148</h1></section>
|
||||||
|
<section><h1>149</h1></section>
|
||||||
|
<section><h1>150</h1></section>
|
||||||
|
<section><h1>151</h1></section>
|
||||||
|
<section><h1>152</h1></section>
|
||||||
|
<section><h1>153</h1></section>
|
||||||
|
<section><h1>154</h1></section>
|
||||||
|
<section><h1>155</h1></section>
|
||||||
|
<section><h1>156</h1></section>
|
||||||
|
<section><h1>157</h1></section>
|
||||||
|
<section><h1>158</h1></section>
|
||||||
|
<section><h1>159</h1></section>
|
||||||
|
<section><h1>160</h1></section>
|
||||||
|
<section><h1>161</h1></section>
|
||||||
|
<section><h1>162</h1></section>
|
||||||
|
<section><h1>163</h1></section>
|
||||||
|
<section><h1>164</h1></section>
|
||||||
|
<section><h1>165</h1></section>
|
||||||
|
<section><h1>166</h1></section>
|
||||||
|
<section><h1>167</h1></section>
|
||||||
|
<section><h1>168</h1></section>
|
||||||
|
<section><h1>169</h1></section>
|
||||||
|
<section><h1>170</h1></section>
|
||||||
|
<section><h1>171</h1></section>
|
||||||
|
<section><h1>172</h1></section>
|
||||||
|
<section><h1>173</h1></section>
|
||||||
|
<section><h1>174</h1></section>
|
||||||
|
<section><h1>175</h1></section>
|
||||||
|
<section><h1>176</h1></section>
|
||||||
|
<section><h1>177</h1></section>
|
||||||
|
<section><h1>178</h1></section>
|
||||||
|
<section><h1>179</h1></section>
|
||||||
|
<section><h1>180</h1></section>
|
||||||
|
<section><h1>181</h1></section>
|
||||||
|
<section><h1>182</h1></section>
|
||||||
|
<section><h1>183</h1></section>
|
||||||
|
<section><h1>184</h1></section>
|
||||||
|
<section><h1>185</h1></section>
|
||||||
|
<section><h1>186</h1></section>
|
||||||
|
<section><h1>187</h1></section>
|
||||||
|
<section><h1>188</h1></section>
|
||||||
|
<section><h1>189</h1></section>
|
||||||
|
<section><h1>190</h1></section>
|
||||||
|
<section><h1>191</h1></section>
|
||||||
|
<section><h1>192</h1></section>
|
||||||
|
<section><h1>193</h1></section>
|
||||||
|
<section><h1>194</h1></section>
|
||||||
|
<section><h1>195</h1></section>
|
||||||
|
<section><h1>196</h1></section>
|
||||||
|
<section><h1>197</h1></section>
|
||||||
|
<section><h1>198</h1></section>
|
||||||
|
<section><h1>199</h1></section>
|
||||||
|
<section><h1>200</h1></section>
|
||||||
|
<section><h1>201</h1></section>
|
||||||
|
<section><h1>202</h1></section>
|
||||||
|
<section><h1>203</h1></section>
|
||||||
|
<section><h1>204</h1></section>
|
||||||
|
<section><h1>205</h1></section>
|
||||||
|
<section><h1>206</h1></section>
|
||||||
|
<section><h1>207</h1></section>
|
||||||
|
<section><h1>208</h1></section>
|
||||||
|
<section><h1>209</h1></section>
|
||||||
|
<section><h1>210</h1></section>
|
||||||
|
<section><h1>211</h1></section>
|
||||||
|
<section><h1>212</h1></section>
|
||||||
|
<section><h1>213</h1></section>
|
||||||
|
<section><h1>214</h1></section>
|
||||||
|
<section><h1>215</h1></section>
|
||||||
|
<section><h1>216</h1></section>
|
||||||
|
<section><h1>217</h1></section>
|
||||||
|
<section><h1>218</h1></section>
|
||||||
|
<section><h1>219</h1></section>
|
||||||
|
<section><h1>220</h1></section>
|
||||||
|
<section><h1>221</h1></section>
|
||||||
|
<section><h1>222</h1></section>
|
||||||
|
<section><h1>223</h1></section>
|
||||||
|
<section><h1>224</h1></section>
|
||||||
|
<section><h1>225</h1></section>
|
||||||
|
<section><h1>226</h1></section>
|
||||||
|
<section><h1>227</h1></section>
|
||||||
|
<section><h1>228</h1></section>
|
||||||
|
<section><h1>229</h1></section>
|
||||||
|
<section><h1>230</h1></section>
|
||||||
|
<section><h1>231</h1></section>
|
||||||
|
<section><h1>232</h1></section>
|
||||||
|
<section><h1>233</h1></section>
|
||||||
|
<section><h1>234</h1></section>
|
||||||
|
<section><h1>235</h1></section>
|
||||||
|
<section><h1>236</h1></section>
|
||||||
|
<section><h1>237</h1></section>
|
||||||
|
<section><h1>238</h1></section>
|
||||||
|
<section><h1>239</h1></section>
|
||||||
|
<section><h1>240</h1></section>
|
||||||
|
<section><h1>241</h1></section>
|
||||||
|
<section><h1>242</h1></section>
|
||||||
|
<section><h1>243</h1></section>
|
||||||
|
<section><h1>244</h1></section>
|
||||||
|
<section><h1>245</h1></section>
|
||||||
|
<section><h1>246</h1></section>
|
||||||
|
<section><h1>247</h1></section>
|
||||||
|
<section><h1>248</h1></section>
|
||||||
|
<section><h1>249</h1></section>
|
||||||
|
<section><h1>250</h1></section>
|
||||||
|
<section><h1>251</h1></section>
|
||||||
|
<section><h1>252</h1></section>
|
||||||
|
<section><h1>253</h1></section>
|
||||||
|
<section><h1>254</h1></section>
|
||||||
|
<section><h1>255</h1></section>
|
||||||
|
<section><h1>256</h1></section>
|
||||||
|
<section><h1>257</h1></section>
|
||||||
|
<section><h1>258</h1></section>
|
||||||
|
<section><h1>259</h1></section>
|
||||||
|
<section><h1>260</h1></section>
|
||||||
|
<section><h1>261</h1></section>
|
||||||
|
<section><h1>262</h1></section>
|
||||||
|
<section><h1>263</h1></section>
|
||||||
|
<section><h1>264</h1></section>
|
||||||
|
<section><h1>265</h1></section>
|
||||||
|
<section><h1>266</h1></section>
|
||||||
|
<section><h1>267</h1></section>
|
||||||
|
<section><h1>268</h1></section>
|
||||||
|
<section><h1>269</h1></section>
|
||||||
|
<section><h1>270</h1></section>
|
||||||
|
<section><h1>271</h1></section>
|
||||||
|
<section><h1>272</h1></section>
|
||||||
|
<section><h1>273</h1></section>
|
||||||
|
<section><h1>274</h1></section>
|
||||||
|
<section><h1>275</h1></section>
|
||||||
|
<section><h1>276</h1></section>
|
||||||
|
<section><h1>277</h1></section>
|
||||||
|
<section><h1>278</h1></section>
|
||||||
|
<section><h1>279</h1></section>
|
||||||
|
<section><h1>280</h1></section>
|
||||||
|
<section><h1>281</h1></section>
|
||||||
|
<section><h1>282</h1></section>
|
||||||
|
<section><h1>283</h1></section>
|
||||||
|
<section><h1>284</h1></section>
|
||||||
|
<section><h1>285</h1></section>
|
||||||
|
<section><h1>286</h1></section>
|
||||||
|
<section><h1>287</h1></section>
|
||||||
|
<section><h1>288</h1></section>
|
||||||
|
<section><h1>289</h1></section>
|
||||||
|
<section><h1>290</h1></section>
|
||||||
|
<section><h1>291</h1></section>
|
||||||
|
<section><h1>292</h1></section>
|
||||||
|
<section><h1>293</h1></section>
|
||||||
|
<section><h1>294</h1></section>
|
||||||
|
<section><h1>295</h1></section>
|
||||||
|
<section><h1>296</h1></section>
|
||||||
|
<section><h1>297</h1></section>
|
||||||
|
<section><h1>298</h1></section>
|
||||||
|
<section><h1>299</h1></section>
|
||||||
|
<section><h1>300</h1></section>
|
||||||
|
<section><h1>301</h1></section>
|
||||||
|
<section><h1>302</h1></section>
|
||||||
|
<section><h1>303</h1></section>
|
||||||
|
<section><h1>304</h1></section>
|
||||||
|
<section><h1>305</h1></section>
|
||||||
|
<section><h1>306</h1></section>
|
||||||
|
<section><h1>307</h1></section>
|
||||||
|
<section><h1>308</h1></section>
|
||||||
|
<section><h1>309</h1></section>
|
||||||
|
<section><h1>310</h1></section>
|
||||||
|
<section><h1>311</h1></section>
|
||||||
|
<section><h1>312</h1></section>
|
||||||
|
<section><h1>313</h1></section>
|
||||||
|
<section><h1>314</h1></section>
|
||||||
|
<section><h1>315</h1></section>
|
||||||
|
<section><h1>316</h1></section>
|
||||||
|
<section><h1>317</h1></section>
|
||||||
|
<section><h1>318</h1></section>
|
||||||
|
<section><h1>319</h1></section>
|
||||||
|
<section><h1>320</h1></section>
|
||||||
|
<section><h1>321</h1></section>
|
||||||
|
<section><h1>322</h1></section>
|
||||||
|
<section><h1>323</h1></section>
|
||||||
|
<section><h1>324</h1></section>
|
||||||
|
<section><h1>325</h1></section>
|
||||||
|
<section><h1>326</h1></section>
|
||||||
|
<section><h1>327</h1></section>
|
||||||
|
<section><h1>328</h1></section>
|
||||||
|
<section><h1>329</h1></section>
|
||||||
|
<section><h1>330</h1></section>
|
||||||
|
<section><h1>331</h1></section>
|
||||||
|
<section><h1>332</h1></section>
|
||||||
|
<section><h1>333</h1></section>
|
||||||
|
<section><h1>334</h1></section>
|
||||||
|
<section><h1>335</h1></section>
|
||||||
|
<section><h1>336</h1></section>
|
||||||
|
<section><h1>337</h1></section>
|
||||||
|
<section><h1>338</h1></section>
|
||||||
|
<section><h1>339</h1></section>
|
||||||
|
<section><h1>340</h1></section>
|
||||||
|
<section><h1>341</h1></section>
|
||||||
|
<section><h1>342</h1></section>
|
||||||
|
<section><h1>343</h1></section>
|
||||||
|
<section><h1>344</h1></section>
|
||||||
|
<section><h1>345</h1></section>
|
||||||
|
<section><h1>346</h1></section>
|
||||||
|
<section><h1>347</h1></section>
|
||||||
|
<section><h1>348</h1></section>
|
||||||
|
<section><h1>349</h1></section>
|
||||||
|
<section><h1>350</h1></section>
|
||||||
|
<section><h1>351</h1></section>
|
||||||
|
<section><h1>352</h1></section>
|
||||||
|
<section><h1>353</h1></section>
|
||||||
|
<section><h1>354</h1></section>
|
||||||
|
<section><h1>355</h1></section>
|
||||||
|
<section><h1>356</h1></section>
|
||||||
|
<section><h1>357</h1></section>
|
||||||
|
<section><h1>358</h1></section>
|
||||||
|
<section><h1>359</h1></section>
|
||||||
|
<section><h1>360</h1></section>
|
||||||
|
<section><h1>361</h1></section>
|
||||||
|
<section><h1>362</h1></section>
|
||||||
|
<section><h1>363</h1></section>
|
||||||
|
<section><h1>364</h1></section>
|
||||||
|
<section><h1>365</h1></section>
|
||||||
|
<section><h1>366</h1></section>
|
||||||
|
<section><h1>367</h1></section>
|
||||||
|
<section><h1>368</h1></section>
|
||||||
|
<section><h1>369</h1></section>
|
||||||
|
<section><h1>370</h1></section>
|
||||||
|
<section><h1>371</h1></section>
|
||||||
|
<section><h1>372</h1></section>
|
||||||
|
<section><h1>373</h1></section>
|
||||||
|
<section><h1>374</h1></section>
|
||||||
|
<section><h1>375</h1></section>
|
||||||
|
<section><h1>376</h1></section>
|
||||||
|
<section><h1>377</h1></section>
|
||||||
|
<section><h1>378</h1></section>
|
||||||
|
<section><h1>379</h1></section>
|
||||||
|
<section><h1>380</h1></section>
|
||||||
|
<section><h1>381</h1></section>
|
||||||
|
<section><h1>382</h1></section>
|
||||||
|
<section><h1>383</h1></section>
|
||||||
|
<section><h1>384</h1></section>
|
||||||
|
<section><h1>385</h1></section>
|
||||||
|
<section><h1>386</h1></section>
|
||||||
|
<section><h1>387</h1></section>
|
||||||
|
<section><h1>388</h1></section>
|
||||||
|
<section><h1>389</h1></section>
|
||||||
|
<section><h1>390</h1></section>
|
||||||
|
<section><h1>391</h1></section>
|
||||||
|
<section><h1>392</h1></section>
|
||||||
|
<section><h1>393</h1></section>
|
||||||
|
<section><h1>394</h1></section>
|
||||||
|
<section><h1>395</h1></section>
|
||||||
|
<section><h1>396</h1></section>
|
||||||
|
<section><h1>397</h1></section>
|
||||||
|
<section><h1>398</h1></section>
|
||||||
|
<section><h1>399</h1></section>
|
||||||
|
<section><h1>400</h1></section>
|
||||||
|
<section><h1>401</h1></section>
|
||||||
|
<section><h1>402</h1></section>
|
||||||
|
<section><h1>403</h1></section>
|
||||||
|
<section><h1>404</h1></section>
|
||||||
|
<section><h1>405</h1></section>
|
||||||
|
<section><h1>406</h1></section>
|
||||||
|
<section><h1>407</h1></section>
|
||||||
|
<section><h1>408</h1></section>
|
||||||
|
<section><h1>409</h1></section>
|
||||||
|
<section><h1>410</h1></section>
|
||||||
|
<section><h1>411</h1></section>
|
||||||
|
<section><h1>412</h1></section>
|
||||||
|
<section><h1>413</h1></section>
|
||||||
|
<section><h1>414</h1></section>
|
||||||
|
<section><h1>415</h1></section>
|
||||||
|
<section><h1>416</h1></section>
|
||||||
|
<section><h1>417</h1></section>
|
||||||
|
<section><h1>418</h1></section>
|
||||||
|
<section><h1>419</h1></section>
|
||||||
|
<section><h1>420</h1></section>
|
||||||
|
<section><h1>421</h1></section>
|
||||||
|
<section><h1>422</h1></section>
|
||||||
|
<section><h1>423</h1></section>
|
||||||
|
<section><h1>424</h1></section>
|
||||||
|
<section><h1>425</h1></section>
|
||||||
|
<section><h1>426</h1></section>
|
||||||
|
<section><h1>427</h1></section>
|
||||||
|
<section><h1>428</h1></section>
|
||||||
|
<section><h1>429</h1></section>
|
||||||
|
<section><h1>430</h1></section>
|
||||||
|
<section><h1>431</h1></section>
|
||||||
|
<section><h1>432</h1></section>
|
||||||
|
<section><h1>433</h1></section>
|
||||||
|
<section><h1>434</h1></section>
|
||||||
|
<section><h1>435</h1></section>
|
||||||
|
<section><h1>436</h1></section>
|
||||||
|
<section><h1>437</h1></section>
|
||||||
|
<section><h1>438</h1></section>
|
||||||
|
<section><h1>439</h1></section>
|
||||||
|
<section><h1>440</h1></section>
|
||||||
|
<section><h1>441</h1></section>
|
||||||
|
<section><h1>442</h1></section>
|
||||||
|
<section><h1>443</h1></section>
|
||||||
|
<section><h1>444</h1></section>
|
||||||
|
<section><h1>445</h1></section>
|
||||||
|
<section><h1>446</h1></section>
|
||||||
|
<section><h1>447</h1></section>
|
||||||
|
<section><h1>448</h1></section>
|
||||||
|
<section><h1>449</h1></section>
|
||||||
|
<section><h1>450</h1></section>
|
||||||
|
<section><h1>451</h1></section>
|
||||||
|
<section><h1>452</h1></section>
|
||||||
|
<section><h1>453</h1></section>
|
||||||
|
<section><h1>454</h1></section>
|
||||||
|
<section><h1>455</h1></section>
|
||||||
|
<section><h1>456</h1></section>
|
||||||
|
<section><h1>457</h1></section>
|
||||||
|
<section><h1>458</h1></section>
|
||||||
|
<section><h1>459</h1></section>
|
||||||
|
<section><h1>460</h1></section>
|
||||||
|
<section><h1>461</h1></section>
|
||||||
|
<section><h1>462</h1></section>
|
||||||
|
<section><h1>463</h1></section>
|
||||||
|
<section><h1>464</h1></section>
|
||||||
|
<section><h1>465</h1></section>
|
||||||
|
<section><h1>466</h1></section>
|
||||||
|
<section><h1>467</h1></section>
|
||||||
|
<section><h1>468</h1></section>
|
||||||
|
<section><h1>469</h1></section>
|
||||||
|
<section><h1>470</h1></section>
|
||||||
|
<section><h1>471</h1></section>
|
||||||
|
<section><h1>472</h1></section>
|
||||||
|
<section><h1>473</h1></section>
|
||||||
|
<section><h1>474</h1></section>
|
||||||
|
<section><h1>475</h1></section>
|
||||||
|
<section><h1>476</h1></section>
|
||||||
|
<section><h1>477</h1></section>
|
||||||
|
<section><h1>478</h1></section>
|
||||||
|
<section><h1>479</h1></section>
|
||||||
|
<section><h1>480</h1></section>
|
||||||
|
<section><h1>481</h1></section>
|
||||||
|
<section><h1>482</h1></section>
|
||||||
|
<section><h1>483</h1></section>
|
||||||
|
<section><h1>484</h1></section>
|
||||||
|
<section><h1>485</h1></section>
|
||||||
|
<section><h1>486</h1></section>
|
||||||
|
<section><h1>487</h1></section>
|
||||||
|
<section><h1>488</h1></section>
|
||||||
|
<section><h1>489</h1></section>
|
||||||
|
<section><h1>490</h1></section>
|
||||||
|
<section><h1>491</h1></section>
|
||||||
|
<section><h1>492</h1></section>
|
||||||
|
<section><h1>493</h1></section>
|
||||||
|
<section><h1>494</h1></section>
|
||||||
|
<section><h1>495</h1></section>
|
||||||
|
<section><h1>496</h1></section>
|
||||||
|
<section><h1>497</h1></section>
|
||||||
|
<section><h1>498</h1></section>
|
||||||
|
<section><h1>499</h1></section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="../dist/reveal.js"></script>
|
||||||
|
<script>
|
||||||
|
Reveal.initialize({
|
||||||
|
transition: 'linear'
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -125,7 +125,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-auto-animate style="height: 600px">
|
<section data-auto-animate style="height: 600px">
|
||||||
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 1</h2>
|
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 1</h3>
|
||||||
<h2 data-id="title" style="margin-top: 260px;">Animate Anything</h2>
|
<h2 data-id="title" style="margin-top: 260px;">Animate Anything</h2>
|
||||||
<div data-id="1" style="background: white; position: absolute; top: 150px; left: 16%; width: 60px; height: 60px;"></div>
|
<div data-id="1" style="background: white; position: absolute; top: 150px; left: 16%; width: 60px; height: 60px;"></div>
|
||||||
<div data-id="2" style="background: white; position: absolute; top: 150px; left: 36%; width: 60px; height: 60px;"></div>
|
<div data-id="2" style="background: white; position: absolute; top: 150px; left: 36%; width: 60px; height: 60px;"></div>
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
<div data-id="4" style="background: white; position: absolute; top: 150px; left: 76%; width: 60px; height: 60px;"></div>
|
<div data-id="4" style="background: white; position: absolute; top: 150px; left: 76%; width: 60px; height: 60px;"></div>
|
||||||
</section>
|
</section>
|
||||||
<section data-auto-animate style="height: 600px">
|
<section data-auto-animate style="height: 600px">
|
||||||
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 2</h2>
|
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 2</h3>
|
||||||
<h2 data-id="title" style="margin-top: 500px">With Auto Animate</h2>
|
<h2 data-id="title" style="margin-top: 500px">With Auto Animate</h2>
|
||||||
<div data-id="1" style="background: cyan; position: absolute; bottom: 190px; left: 16%; width: 60px; height: 60px;"></div>
|
<div data-id="1" style="background: cyan; position: absolute; bottom: 190px; left: 16%; width: 60px; height: 60px;"></div>
|
||||||
<div data-id="2" style="background: magenta; position: absolute; bottom: 190px; left: 36%; width: 60px; height: 160px;"></div>
|
<div data-id="2" style="background: magenta; position: absolute; bottom: 190px; left: 36%; width: 60px; height: 160px;"></div>
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
<div data-id="4" style="background: red; position: absolute; bottom: 190px; left: 76%; width: 60px; height: 360px;"></div>
|
<div data-id="4" style="background: red; position: absolute; bottom: 190px; left: 76%; width: 60px; height: 360px;"></div>
|
||||||
</section>
|
</section>
|
||||||
<section data-auto-animate style="height: 600px">
|
<section data-auto-animate style="height: 600px">
|
||||||
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h2>
|
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h3>
|
||||||
<h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2>
|
<h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2>
|
||||||
<div data-id="1" style="background: cyan; position: absolute; top: 50%; left: 50%; width: 400px; height: 400px; margin: -200px 0 0 -200px; border-radius: 400px;"></div>
|
<div data-id="1" style="background: cyan; position: absolute; top: 50%; left: 50%; width: 400px; height: 400px; margin: -200px 0 0 -200px; border-radius: 400px;"></div>
|
||||||
<div data-id="2" style="background: magenta; position: absolute; top: 50%; left: 50%; width: 300px; height: 300px; margin: -150px 0 0 -150px; border-radius: 400px;"></div>
|
<div data-id="2" style="background: magenta; position: absolute; top: 50%; left: 50%; width: 300px; height: 300px; margin: -150px 0 0 -150px; border-radius: 400px;"></div>
|
||||||
@@ -149,7 +149,7 @@
|
|||||||
<div data-id="4" style="background: red; position: absolute; top: 50%; left: 50%; width: 100px; height: 100px; margin: -50px 0 0 -50px; border-radius: 400px;"></div>
|
<div data-id="4" style="background: red; position: absolute; top: 50%; left: 50%; width: 100px; height: 100px; margin: -50px 0 0 -50px; border-radius: 400px;"></div>
|
||||||
</section>
|
</section>
|
||||||
<section data-auto-animate style="height: 600px">
|
<section data-auto-animate style="height: 600px">
|
||||||
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h2>
|
<h3 style="opacity: 0.3; font-size: 18px;">SLIDE 3</h3>
|
||||||
<h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2>
|
<h2 data-id="title" style="margin-top: 500px; opacity: 0;">With Auto Animate</h2>
|
||||||
<div data-id="1" style="background: red; position: absolute; top: 250px; left: 16%; width: 60px; height: 60px;"></div>
|
<div data-id="1" style="background: red; position: absolute; top: 250px; left: 16%; width: 60px; height: 60px;"></div>
|
||||||
<div data-id="2" style="background: yellow; position: absolute; top: 250px; left: 36%; width: 60px; height: 60px;"></div>
|
<div data-id="2" style="background: yellow; position: absolute; top: 250px; left: 36%; width: 60px; height: 60px;"></div>
|
||||||
@@ -176,6 +176,37 @@
|
|||||||
<h3>B2</h3>
|
<h3>B2</h3>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<section id="stacked-slide-1" data-auto-animate>
|
||||||
|
<a href="#/stacked-slide-1">Slide 1</a><br>
|
||||||
|
<a href="#/stacked-slide-2">Slide 2</a><br>
|
||||||
|
<a href="#/stacked-slide-3">Slide 3</a><br>
|
||||||
|
<a href="#/stacked-slide-4">Slide 4</a><br>
|
||||||
|
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 0px;">A</div>
|
||||||
|
</section>
|
||||||
|
<section id="stacked-slide-2" data-auto-animate>
|
||||||
|
<a href="#/stacked-slide-1">Slide 1</a><br>
|
||||||
|
<a href="#/stacked-slide-2">Slide 2</a><br>
|
||||||
|
<a href="#/stacked-slide-3">Slide 3</a><br>
|
||||||
|
<a href="#/stacked-slide-4">Slide 4</a><br>
|
||||||
|
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 25%;">A</div>
|
||||||
|
</section>
|
||||||
|
<section id="stacked-slide-3" data-auto-animate>
|
||||||
|
<a href="#/stacked-slide-1">Slide 1</a><br>
|
||||||
|
<a href="#/stacked-slide-2">Slide 2</a><br>
|
||||||
|
<a href="#/stacked-slide-3">Slide 3</a><br>
|
||||||
|
<a href="#/stacked-slide-4">Slide 4</a><br>
|
||||||
|
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 50%;">A</div>
|
||||||
|
</section>
|
||||||
|
<section id="stacked-slide-4" data-auto-animate>
|
||||||
|
<a href="#/stacked-slide-1">Slide 1</a><br>
|
||||||
|
<a href="#/stacked-slide-2">Slide 2</a><br>
|
||||||
|
<a href="#/stacked-slide-3">Slide 3</a><br>
|
||||||
|
<a href="#/stacked-slide-4">Slide 4</a><br>
|
||||||
|
<div data-id="anim" style="background: indigo; padding: 8px; width: 50px; height: 50px; position: absolute; left: 75%;">A</div>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -123,7 +123,7 @@
|
|||||||
|
|
||||||
<section id="vstack">
|
<section id="vstack">
|
||||||
<h2>VStack</h2>
|
<h2>VStack</h2>
|
||||||
<p>Stacks multiple elements horizontally.</p>
|
<p>Stacks multiple elements vertically.</p>
|
||||||
<pre><code class="html" data-trim data-line-numbers>
|
<pre><code class="html" data-trim data-line-numbers>
|
||||||
<div class="r-vstack">
|
<div class="r-vstack">
|
||||||
<img width="450" height="300" src="...">
|
<img width="450" height="300" src="...">
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
<!-- Use external markdown resource, separate slides by three newlines; vertical slides by two newlines -->
|
<!-- Use external markdown resource, separate slides by three newlines; vertical slides by two newlines -->
|
||||||
<section data-markdown="markdown.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section>
|
<section data-markdown="markdown.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section>
|
||||||
|
|
||||||
<!-- Slides are separated by three dashes (quick 'n dirty regular expression) -->
|
<!-- Slides are separated by three dashes (the default) -->
|
||||||
<section data-markdown data-separator="---">
|
<section data-markdown>
|
||||||
<script type="text/template">
|
<script type="text/template">
|
||||||
## Demo 1
|
## Demo 1
|
||||||
Slide 1
|
Slide 1
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
</script>
|
</script>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
|
<!-- Slides are separated by regexp matching newline + three dashes + newline, vertical slides identical but two dashes -->
|
||||||
<section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$">
|
<section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$">
|
||||||
<script type="text/template">
|
<script type="text/template">
|
||||||
## Demo 2
|
## Demo 2
|
||||||
@@ -53,8 +53,8 @@
|
|||||||
</script>
|
</script>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- No "extra" slides, since there are no separators defined (so they'll become horizontal rulers) -->
|
<!-- No "extra" slides, since the separator can't be matched ("---" will become horizontal rulers) -->
|
||||||
<section data-markdown>
|
<section data-markdown data-separator="$x">
|
||||||
<script type="text/template">
|
<script type="text/template">
|
||||||
A
|
A
|
||||||
|
|
||||||
@@ -99,6 +99,25 @@
|
|||||||
</script>
|
</script>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- add optional line count offset, in this case 287 -->
|
||||||
|
<section data-markdown>
|
||||||
|
<script type="text/template">
|
||||||
|
## echo.c
|
||||||
|
|
||||||
|
```c [287: 2|4,6]
|
||||||
|
/* All of the options in this arg are valid, so handle them. */
|
||||||
|
p = arg + 1;
|
||||||
|
do {
|
||||||
|
if (*p == 'n')
|
||||||
|
nflag = 0;
|
||||||
|
if (*p == 'e')
|
||||||
|
eflag = '\\';
|
||||||
|
} while (*++p);
|
||||||
|
```
|
||||||
|
[source](https://git.busybox.net/busybox/tree/coreutils/echo.c?h=1_36_stable#n287)
|
||||||
|
</script>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- Images -->
|
<!-- Images -->
|
||||||
<section data-markdown>
|
<section data-markdown>
|
||||||
<script type="text/template">
|
<script type="text/template">
|
||||||
@@ -106,6 +125,16 @@
|
|||||||
</script>
|
</script>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- Math -->
|
||||||
|
<section data-markdown>
|
||||||
|
## The Lorenz Equations
|
||||||
|
`\[\begin{aligned}
|
||||||
|
\dot{x} & = \sigma(y-x) \\
|
||||||
|
\dot{y} & = \rho x - y - xz \\
|
||||||
|
\dot{z} & = -\beta z + xy
|
||||||
|
\end{aligned} \]`
|
||||||
|
</section>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -113,6 +142,7 @@
|
|||||||
<script src="../plugin/markdown/markdown.js"></script>
|
<script src="../plugin/markdown/markdown.js"></script>
|
||||||
<script src="../plugin/highlight/highlight.js"></script>
|
<script src="../plugin/highlight/highlight.js"></script>
|
||||||
<script src="../plugin/notes/notes.js"></script>
|
<script src="../plugin/notes/notes.js"></script>
|
||||||
|
<script src="../plugin/math/math.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
@@ -122,7 +152,7 @@
|
|||||||
history: true,
|
history: true,
|
||||||
center: true,
|
center: true,
|
||||||
|
|
||||||
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
|
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes, RevealMath.KaTeX ]
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ Content 3.1
|
|||||||
Content 3.2
|
Content 3.2
|
||||||
|
|
||||||
|
|
||||||
## External 3.3
|
## External 3.3 (Image)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
## External 3.4 (Math)
|
||||||
|
|
||||||
|
`\[ J(\theta_0,\theta_1) = \sum_{i=0} \]`
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2>reveal.js Math Plugin</h2>
|
<h2>reveal.js Math Plugin</h2>
|
||||||
<p>A thin wrapper for MathJax</p>
|
<p>Render math with KaTeX, MathJax 2 or MathJax 3</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
@@ -182,8 +182,7 @@
|
|||||||
history: true,
|
history: true,
|
||||||
transition: 'linear',
|
transition: 'linear',
|
||||||
|
|
||||||
math: {
|
mathjax2: {
|
||||||
// mathjax: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js',
|
|
||||||
config: 'TeX-AMS_HTML-full',
|
config: 'TeX-AMS_HTML-full',
|
||||||
TeX: {
|
TeX: {
|
||||||
Macros: {
|
Macros: {
|
||||||
@@ -193,7 +192,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
plugins: [ RevealMath ]
|
// There are three typesetters available
|
||||||
|
// RevealMath.MathJax2 (default)
|
||||||
|
// RevealMath.MathJax3
|
||||||
|
// RevealMath.KaTeX
|
||||||
|
//
|
||||||
|
// More info at https://revealjs.com/math/
|
||||||
|
plugins: [ RevealMath.MathJax2 ]
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
118
examples/scroll.html
Normal file
118
examples/scroll.html
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
|
||||||
|
<title>reveal.js - Scroll View</title>
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../dist/reset.css">
|
||||||
|
<link rel="stylesheet" href="../dist/reveal.css">
|
||||||
|
<link rel="stylesheet" href="../dist/theme/black.css" id="theme">
|
||||||
|
<link rel="stylesheet" href="../plugin/highlight/monokai.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="reveal">
|
||||||
|
|
||||||
|
<div class="slides">
|
||||||
|
|
||||||
|
<section><h1>Scroll View</h1></section>
|
||||||
|
<section data-background="indigo">
|
||||||
|
<h2>Scroll triggered fragments</h2>
|
||||||
|
<ul>
|
||||||
|
<li class="fragment fade-left">Step one</li>
|
||||||
|
<li class="fragment fade-left">Step two</li>
|
||||||
|
<li class="fragment fade-left">Step three</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
<section data-background-color="#fff"><h2>Scrollbar inverts<br>based on slide bg</h2></section>
|
||||||
|
<section data-auto-animate data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)">
|
||||||
|
<h2>Auto-Animate</h2>
|
||||||
|
<p>Scroll triggered auto-animations 😍</p>
|
||||||
|
<div class="r-hstack justify-center">
|
||||||
|
<div data-id="box1" style="background: #999; width: 50px; height: 50px; margin: 10px; border-radius: 5px;"></div>
|
||||||
|
<div data-id="box2" style="background: #999; width: 50px; height: 50px; margin: 10px; border-radius: 5px;"></div>
|
||||||
|
<div data-id="box3" style="background: #999; width: 50px; height: 50px; margin: 10px; border-radius: 5px;"></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section data-auto-animate data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)">
|
||||||
|
<div class="r-hstack justify-center">
|
||||||
|
<div data-id="box1" data-auto-animate-delay="0" style="background: cyan; width: 150px; height: 100px; margin: 10px;"></div>
|
||||||
|
<div data-id="box2" data-auto-animate-delay="0.1" style="background: magenta; width: 150px; height: 100px; margin: 10px;"></div>
|
||||||
|
<div data-id="box3" data-auto-animate-delay="0.2" style="background: yellow; width: 150px; height: 100px; margin: 10px;"></div>
|
||||||
|
</div>
|
||||||
|
<h2 style="margin-top: 20px;">Auto-Animate</h2>
|
||||||
|
</section>
|
||||||
|
<section data-auto-animate data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)">
|
||||||
|
<div class="r-stack">
|
||||||
|
<div data-id="box1" style="background: cyan; width: 300px; height: 300px; border-radius: 200px;"></div>
|
||||||
|
<div data-id="box2" style="background: magenta; width: 200px; height: 200px; border-radius: 200px;"></div>
|
||||||
|
<div data-id="box3" style="background: yellow; width: 100px; height: 100px; border-radius: 200px;"></div>
|
||||||
|
</div>
|
||||||
|
<h2 style="margin-top: 20px;">Auto-Animate</h2>
|
||||||
|
</section>
|
||||||
|
<section data-background-gradient="linear-gradient(to bottom, #283b95, #17b2c3)" id="gradient-bg">
|
||||||
|
<h2 data-id="code-title">Code highlights,<br />meet scroll triggers</h2>
|
||||||
|
<pre data-id="code-animation"><code class="hljs javascript" data-trim data-line-numbers="|4,8-11|17|22-24"><script type="text/template">
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
function Example() {
|
||||||
|
const [count, setCount] = useState(0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>You clicked {count} times</p>
|
||||||
|
<button onClick={() => setCount(count + 1)}>
|
||||||
|
Click me
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SecondExample() {
|
||||||
|
const [count, setCount] = useState(0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>You clicked {count} times</p>
|
||||||
|
<button onClick={() => setCount(count + 1)}>
|
||||||
|
Click me
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
</script></code></pre>
|
||||||
|
</section>
|
||||||
|
<section class="stack">
|
||||||
|
<section data-background="https://static.slid.es/reveal/image-placeholder.png" id="image-bg">
|
||||||
|
<h2>Image Backgrounds</h2>
|
||||||
|
</section>
|
||||||
|
<section data-background-video-muted data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.webm">
|
||||||
|
<h2>Video background</h2>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<section><h2>The end</h2></section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="../dist/reveal.js"></script>
|
||||||
|
<script src="../plugin/notes/notes.js"></script>
|
||||||
|
<script src="../plugin/markdown/markdown.js"></script>
|
||||||
|
<script src="../plugin/highlight/highlight.js"></script>
|
||||||
|
<script>
|
||||||
|
Reveal.initialize({
|
||||||
|
view: 'scroll',
|
||||||
|
hash: true,
|
||||||
|
|
||||||
|
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
53
gulpfile.js
53
gulpfile.js
@@ -1,13 +1,11 @@
|
|||||||
const pkg = require('./package.json')
|
const pkg = require('./package.json')
|
||||||
const path = require('path')
|
|
||||||
const glob = require('glob')
|
const glob = require('glob')
|
||||||
const yargs = require('yargs')
|
const yargs = require('yargs')
|
||||||
const colors = require('colors')
|
|
||||||
const through = require('through2');
|
const through = require('through2');
|
||||||
const qunit = require('node-qunit-puppeteer')
|
const qunit = require('node-qunit-puppeteer')
|
||||||
|
|
||||||
const {rollup} = require('rollup')
|
const {rollup} = require('rollup')
|
||||||
const {terser} = require('rollup-plugin-terser')
|
const terser = require('@rollup/plugin-terser')
|
||||||
const babel = require('@rollup/plugin-babel').default
|
const babel = require('@rollup/plugin-babel').default
|
||||||
const commonjs = require('@rollup/plugin-commonjs')
|
const commonjs = require('@rollup/plugin-commonjs')
|
||||||
const resolve = require('@rollup/plugin-node-resolve').default
|
const resolve = require('@rollup/plugin-node-resolve').default
|
||||||
@@ -24,13 +22,14 @@ const autoprefixer = require('gulp-autoprefixer')
|
|||||||
|
|
||||||
const root = yargs.argv.root || '.'
|
const root = yargs.argv.root || '.'
|
||||||
const port = yargs.argv.port || 8000
|
const port = yargs.argv.port || 8000
|
||||||
|
const host = yargs.argv.host || 'localhost'
|
||||||
|
|
||||||
const banner = `/*!
|
const banner = `/*!
|
||||||
* reveal.js ${pkg.version}
|
* reveal.js ${pkg.version}
|
||||||
* ${pkg.homepage}
|
* ${pkg.homepage}
|
||||||
* MIT licensed
|
* MIT licensed
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 Hakim El Hattab, https://hakim.se
|
* Copyright (C) 2011-2023 Hakim El Hattab, https://hakim.se
|
||||||
*/\n`
|
*/\n`
|
||||||
|
|
||||||
// Prevents warnings from opening too many test pages
|
// Prevents warnings from opening too many test pages
|
||||||
@@ -60,11 +59,11 @@ const babelConfig = {
|
|||||||
// polyfilling older browsers and a larger bundle.
|
// polyfilling older browsers and a larger bundle.
|
||||||
const babelConfigESM = JSON.parse( JSON.stringify( babelConfig ) );
|
const babelConfigESM = JSON.parse( JSON.stringify( babelConfig ) );
|
||||||
babelConfigESM.presets[0][1].targets = { browsers: [
|
babelConfigESM.presets[0][1].targets = { browsers: [
|
||||||
'last 2 Chrome versions', 'not Chrome < 60',
|
'last 2 Chrome versions',
|
||||||
'last 2 Safari versions', 'not Safari < 10.1',
|
'last 2 Safari versions',
|
||||||
'last 2 iOS versions', 'not iOS < 10.3',
|
'last 2 iOS versions',
|
||||||
'last 2 Firefox versions', 'not Firefox < 60',
|
'last 2 Firefox versions',
|
||||||
'last 2 Edge versions', 'not Edge < 16',
|
'last 2 Edge versions',
|
||||||
] };
|
] };
|
||||||
|
|
||||||
let cache = {};
|
let cache = {};
|
||||||
@@ -163,11 +162,10 @@ function compileSass() {
|
|||||||
|
|
||||||
sass.render({
|
sass.render({
|
||||||
data: transformedFile.contents.toString(),
|
data: transformedFile.contents.toString(),
|
||||||
includePaths: ['css/', 'css/theme/template']
|
file: transformedFile.path,
|
||||||
}, ( err, result ) => {
|
}, ( err, result ) => {
|
||||||
if( err ) {
|
if( err ) {
|
||||||
console.log( vinylFile.path );
|
callback(err);
|
||||||
console.log( err.formatted );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
transformedFile.extname = '.css';
|
transformedFile.extname = '.css';
|
||||||
@@ -196,7 +194,7 @@ gulp.task('qunit', () => {
|
|||||||
let serverConfig = {
|
let serverConfig = {
|
||||||
root,
|
root,
|
||||||
port: 8009,
|
port: 8009,
|
||||||
host: '0.0.0.0',
|
host: 'localhost',
|
||||||
name: 'test-server'
|
name: 'test-server'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,20 +266,24 @@ gulp.task('default', gulp.series(gulp.parallel('js', 'css', 'plugins'), 'test'))
|
|||||||
|
|
||||||
gulp.task('build', gulp.parallel('js', 'css', 'plugins'))
|
gulp.task('build', gulp.parallel('js', 'css', 'plugins'))
|
||||||
|
|
||||||
gulp.task('package', gulp.series('default', () =>
|
gulp.task('package', gulp.series(() =>
|
||||||
|
|
||||||
gulp.src([
|
gulp.src(
|
||||||
|
[
|
||||||
'./index.html',
|
'./index.html',
|
||||||
'./dist/**',
|
'./dist/**',
|
||||||
'./lib/**',
|
'./lib/**',
|
||||||
'./images/**',
|
'./images/**',
|
||||||
'./plugin/**',
|
'./plugin/**',
|
||||||
'./**.md'
|
'./**/*.md'
|
||||||
]).pipe(zip('reveal-js-presentation.zip')).pipe(gulp.dest('./'))
|
],
|
||||||
|
{ base: './' }
|
||||||
|
)
|
||||||
|
.pipe(zip('reveal-js-presentation.zip')).pipe(gulp.dest('./'))
|
||||||
|
|
||||||
))
|
))
|
||||||
|
|
||||||
gulp.task('reload', () => gulp.src(['*.html', '*.md'])
|
gulp.task('reload', () => gulp.src(['index.html'])
|
||||||
.pipe(connect.reload()));
|
.pipe(connect.reload()));
|
||||||
|
|
||||||
gulp.task('serve', () => {
|
gulp.task('serve', () => {
|
||||||
@@ -289,18 +291,23 @@ gulp.task('serve', () => {
|
|||||||
connect.server({
|
connect.server({
|
||||||
root: root,
|
root: root,
|
||||||
port: port,
|
port: port,
|
||||||
host: '0.0.0.0',
|
host: host,
|
||||||
livereload: true
|
livereload: true
|
||||||
})
|
})
|
||||||
|
|
||||||
gulp.watch(['*.html', '*.md'], gulp.series('reload'))
|
const slidesRoot = root.endsWith('/') ? root : root + '/'
|
||||||
|
gulp.watch([
|
||||||
|
slidesRoot + '**/*.html',
|
||||||
|
slidesRoot + '**/*.md',
|
||||||
|
`!${slidesRoot}**/node_modules/**`, // ignore node_modules
|
||||||
|
], gulp.series('reload'))
|
||||||
|
|
||||||
gulp.watch(['js/**'], gulp.series('js', 'reload', 'test'))
|
gulp.watch(['js/**'], gulp.series('js', 'reload', 'eslint'))
|
||||||
|
|
||||||
gulp.watch(['plugin/**/plugin.js'], gulp.series('plugins', 'reload'))
|
gulp.watch(['plugin/**/plugin.js', 'plugin/**/*.html'], gulp.series('plugins', 'reload'))
|
||||||
|
|
||||||
gulp.watch([
|
gulp.watch([
|
||||||
'css/theme/source/*.{sass,scss}',
|
'css/theme/source/**/*.{sass,scss}',
|
||||||
'css/theme/template/*.{sass,scss}',
|
'css/theme/template/*.{sass,scss}',
|
||||||
], gulp.series('css-themes', 'reload'))
|
], gulp.series('css-themes', 'reload'))
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
|||||||
37
js/config.js
37
js/config.js
@@ -65,6 +65,9 @@ export default {
|
|||||||
// Flags if we should monitor the hash and change slides accordingly
|
// Flags if we should monitor the hash and change slides accordingly
|
||||||
respondToHashChanges: true,
|
respondToHashChanges: true,
|
||||||
|
|
||||||
|
// Enable support for jump-to-slide navigation shortcuts
|
||||||
|
jumpToSlide: true,
|
||||||
|
|
||||||
// Push each slide change to the browser history. Implies `hash: true`
|
// Push each slide change to the browser history. Implies `hash: true`
|
||||||
history: false,
|
history: false,
|
||||||
|
|
||||||
@@ -253,6 +256,36 @@ export default {
|
|||||||
parallaxBackgroundHorizontal: null,
|
parallaxBackgroundHorizontal: null,
|
||||||
parallaxBackgroundVertical: null,
|
parallaxBackgroundVertical: null,
|
||||||
|
|
||||||
|
// Can be used to initialize reveal.js in one of the following views:
|
||||||
|
// - print: Render the presentation so that it can be printed to PDF
|
||||||
|
// - scroll: Show the presentation as a tall scrollable page with scroll
|
||||||
|
// triggered animations
|
||||||
|
view: null,
|
||||||
|
|
||||||
|
// Adjusts the height of each slide in the scroll view.
|
||||||
|
// - full: Each slide is as tall as the viewport
|
||||||
|
// - compact: Slides are as small as possible, allowing multiple slides
|
||||||
|
// to be visible in parallel on tall devices
|
||||||
|
scrollLayout: 'full',
|
||||||
|
|
||||||
|
// Control how scroll snapping works in the scroll view.
|
||||||
|
// - false: No snapping, scrolling is continuous
|
||||||
|
// - proximity: Snap when close to a slide
|
||||||
|
// - mandatory: Always snap to the closest slide
|
||||||
|
//
|
||||||
|
// Only applies to presentations in scroll view.
|
||||||
|
scrollSnap: 'mandatory',
|
||||||
|
|
||||||
|
// Enables and configure the scroll view progress bar.
|
||||||
|
// - 'auto': Show the scrollbar while scrolling, hide while idle
|
||||||
|
// - true: Always show the scrollbar
|
||||||
|
// - false: Never show the scrollbar
|
||||||
|
scrollProgress: 'auto',
|
||||||
|
|
||||||
|
// Automatically activate the scroll view when we the viewport falls
|
||||||
|
// below the given width.
|
||||||
|
scrollActivationWidth: 435,
|
||||||
|
|
||||||
// The maximum number of pages a single slide can expand onto when printing
|
// The maximum number of pages a single slide can expand onto when printing
|
||||||
// to PDF, unlimited by default
|
// to PDF, unlimited by default
|
||||||
pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY,
|
pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY,
|
||||||
@@ -284,6 +317,10 @@ export default {
|
|||||||
// Time before the cursor is hidden (in ms)
|
// Time before the cursor is hidden (in ms)
|
||||||
hideCursorTime: 5000,
|
hideCursorTime: 5000,
|
||||||
|
|
||||||
|
// Should we automatically sort and set indices for fragments
|
||||||
|
// at each sync? (See Reveal.sync)
|
||||||
|
sortFragmentsOnSync: true,
|
||||||
|
|
||||||
// Script dependencies to load
|
// Script dependencies to load
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
|
|
||||||
|
|||||||
@@ -50,11 +50,19 @@ export default class AutoAnimate {
|
|||||||
// Flag the navigation direction, needed for fragment buildup
|
// Flag the navigation direction, needed for fragment buildup
|
||||||
animationOptions.slideDirection = toSlideIndex > fromSlideIndex ? 'forward' : 'backward';
|
animationOptions.slideDirection = toSlideIndex > fromSlideIndex ? 'forward' : 'backward';
|
||||||
|
|
||||||
|
// If the from-slide is hidden because it has moved outside
|
||||||
|
// the view distance, we need to temporarily show it while
|
||||||
|
// measuring
|
||||||
|
let fromSlideIsHidden = fromSlide.style.display === 'none';
|
||||||
|
if( fromSlideIsHidden ) fromSlide.style.display = this.Reveal.getConfig().display;
|
||||||
|
|
||||||
// Inject our auto-animate styles for this transition
|
// Inject our auto-animate styles for this transition
|
||||||
let css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => {
|
let css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => {
|
||||||
return this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, autoAnimateCounter++ );
|
return this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, autoAnimateCounter++ );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
if( fromSlideIsHidden ) fromSlide.style.display = 'none';
|
||||||
|
|
||||||
// Animate unmatched elements, if enabled
|
// Animate unmatched elements, if enabled
|
||||||
if( toSlide.dataset.autoAnimateUnmatched !== 'false' && this.Reveal.getConfig().autoAnimateUnmatched === true ) {
|
if( toSlide.dataset.autoAnimateUnmatched !== 'false' && this.Reveal.getConfig().autoAnimateUnmatched === true ) {
|
||||||
|
|
||||||
@@ -391,8 +399,15 @@ export default class AutoAnimate {
|
|||||||
value = { value: style.to, explicitValue: true };
|
value = { value: style.to, explicitValue: true };
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Use a unitless value for line-height so that it inherits properly
|
||||||
|
if( style.property === 'line-height' ) {
|
||||||
|
value = parseFloat( computedStyles['line-height'] ) / parseFloat( computedStyles['font-size'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isNaN(value) ) {
|
||||||
value = computedStyles[style.property];
|
value = computedStyles[style.property];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( value !== '' ) {
|
if( value !== '' ) {
|
||||||
properties.styles[style.property] = value;
|
properties.styles[style.property] = value;
|
||||||
@@ -446,7 +461,7 @@ export default class AutoAnimate {
|
|||||||
const textNodes = 'h1, h2, h3, h4, h5, h6, p, li';
|
const textNodes = 'h1, h2, h3, h4, h5, h6, p, li';
|
||||||
const mediaNodes = 'img, video, iframe';
|
const mediaNodes = 'img, video, iframe';
|
||||||
|
|
||||||
// Eplicit matches via data-id
|
// Explicit matches via data-id
|
||||||
this.findAutoAnimateMatches( pairs, fromSlide, toSlide, '[data-id]', node => {
|
this.findAutoAnimateMatches( pairs, fromSlide, toSlide, '[data-id]', node => {
|
||||||
return node.nodeName + ':::' + node.getAttribute( 'data-id' );
|
return node.nodeName + ':::' + node.getAttribute( 'data-id' );
|
||||||
} );
|
} );
|
||||||
@@ -467,7 +482,6 @@ export default class AutoAnimate {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
pairs.forEach( pair => {
|
pairs.forEach( pair => {
|
||||||
|
|
||||||
// Disable scale transformations on text nodes, we transition
|
// Disable scale transformations on text nodes, we transition
|
||||||
// each individual text property instead
|
// each individual text property instead
|
||||||
if( matches( pair.from, textNodes ) ) {
|
if( matches( pair.from, textNodes ) ) {
|
||||||
@@ -490,7 +504,7 @@ export default class AutoAnimate {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
// Line numbers
|
// Line numbers
|
||||||
this.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-line[data-line-number]', node => {
|
this.findAutoAnimateMatches( pairs, pair.from, pair.to, '.hljs .hljs-ln-numbers[data-line-number]', node => {
|
||||||
return node.getAttribute( 'data-line-number' );
|
return node.getAttribute( 'data-line-number' );
|
||||||
}, {
|
}, {
|
||||||
scale: false,
|
scale: false,
|
||||||
@@ -559,14 +573,14 @@ export default class AutoAnimate {
|
|||||||
|
|
||||||
// Retrieve the 'from' element
|
// Retrieve the 'from' element
|
||||||
if( fromMatches[key] ) {
|
if( fromMatches[key] ) {
|
||||||
const pimaryIndex = toMatches[key].length - 1;
|
const primaryIndex = toMatches[key].length - 1;
|
||||||
const secondaryIndex = fromMatches[key].length - 1;
|
const secondaryIndex = fromMatches[key].length - 1;
|
||||||
|
|
||||||
// If there are multiple identical from elements, retrieve
|
// If there are multiple identical from elements, retrieve
|
||||||
// the one at the same index as our to-element.
|
// the one at the same index as our to-element.
|
||||||
if( fromMatches[key][ pimaryIndex ] ) {
|
if( fromMatches[key][ primaryIndex ] ) {
|
||||||
fromElement = fromMatches[key][ pimaryIndex ];
|
fromElement = fromMatches[key][ primaryIndex ];
|
||||||
fromMatches[key][ pimaryIndex ] = null;
|
fromMatches[key][ primaryIndex ] = null;
|
||||||
}
|
}
|
||||||
// If there are no matching from-elements at the same index,
|
// If there are no matching from-elements at the same index,
|
||||||
// use the last one.
|
// use the last one.
|
||||||
@@ -594,7 +608,7 @@ export default class AutoAnimate {
|
|||||||
* fading of unmatched elements is turned on, these elements
|
* fading of unmatched elements is turned on, these elements
|
||||||
* will fade when going between auto-animate slides.
|
* will fade when going between auto-animate slides.
|
||||||
*
|
*
|
||||||
* Note that parents of auto-animate targets are NOT considerd
|
* Note that parents of auto-animate targets are NOT considered
|
||||||
* unmatched since fading them would break the auto-animation.
|
* unmatched since fading them would break the auto-animation.
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} rootElement
|
* @param {HTMLElement} rootElement
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ export default class Backgrounds {
|
|||||||
backgroundVideo: slide.getAttribute( 'data-background-video' ),
|
backgroundVideo: slide.getAttribute( 'data-background-video' ),
|
||||||
backgroundIframe: slide.getAttribute( 'data-background-iframe' ),
|
backgroundIframe: slide.getAttribute( 'data-background-iframe' ),
|
||||||
backgroundColor: slide.getAttribute( 'data-background-color' ),
|
backgroundColor: slide.getAttribute( 'data-background-color' ),
|
||||||
|
backgroundGradient: slide.getAttribute( 'data-background-gradient' ),
|
||||||
backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
|
backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
|
||||||
backgroundPosition: slide.getAttribute( 'data-background-position' ),
|
backgroundPosition: slide.getAttribute( 'data-background-position' ),
|
||||||
backgroundTransition: slide.getAttribute( 'data-background-transition' ),
|
backgroundTransition: slide.getAttribute( 'data-background-transition' ),
|
||||||
@@ -150,7 +151,7 @@ export default class Backgrounds {
|
|||||||
|
|
||||||
if( data.background ) {
|
if( data.background ) {
|
||||||
// Auto-wrap image urls in url(...)
|
// Auto-wrap image urls in url(...)
|
||||||
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/gi.test( data.background ) ) {
|
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp|webp)([?#\s]|$)/gi.test( data.background ) ) {
|
||||||
slide.setAttribute( 'data-background-image', data.background );
|
slide.setAttribute( 'data-background-image', data.background );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -161,13 +162,14 @@ export default class Backgrounds {
|
|||||||
// Create a hash for this combination of background settings.
|
// Create a hash for this combination of background settings.
|
||||||
// This is used to determine when two slide backgrounds are
|
// This is used to determine when two slide backgrounds are
|
||||||
// the same.
|
// the same.
|
||||||
if( data.background || data.backgroundColor || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) {
|
if( data.background || data.backgroundColor || data.backgroundGradient || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) {
|
||||||
element.setAttribute( 'data-background-hash', data.background +
|
element.setAttribute( 'data-background-hash', data.background +
|
||||||
data.backgroundSize +
|
data.backgroundSize +
|
||||||
data.backgroundImage +
|
data.backgroundImage +
|
||||||
data.backgroundVideo +
|
data.backgroundVideo +
|
||||||
data.backgroundIframe +
|
data.backgroundIframe +
|
||||||
data.backgroundColor +
|
data.backgroundColor +
|
||||||
|
data.backgroundGradient +
|
||||||
data.backgroundRepeat +
|
data.backgroundRepeat +
|
||||||
data.backgroundPosition +
|
data.backgroundPosition +
|
||||||
data.backgroundTransition +
|
data.backgroundTransition +
|
||||||
@@ -177,6 +179,7 @@ export default class Backgrounds {
|
|||||||
// Additional and optional background properties
|
// Additional and optional background properties
|
||||||
if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );
|
if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );
|
||||||
if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
|
if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
|
||||||
|
if( data.backgroundGradient ) element.style.backgroundImage = data.backgroundGradient;
|
||||||
if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
|
if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
|
||||||
|
|
||||||
if( dataPreload ) element.setAttribute( 'data-preload', '' );
|
if( dataPreload ) element.setAttribute( 'data-preload', '' );
|
||||||
@@ -187,10 +190,30 @@ export default class Backgrounds {
|
|||||||
if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition;
|
if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition;
|
||||||
if( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity;
|
if( data.backgroundOpacity ) contentElement.style.opacity = data.backgroundOpacity;
|
||||||
|
|
||||||
|
const contrastClass = this.getContrastClass( slide );
|
||||||
|
|
||||||
|
if( typeof contrastClass === 'string' ) {
|
||||||
|
slide.classList.add( contrastClass );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a class name that can be applied to a slide to indicate
|
||||||
|
* if it has a light or dark background.
|
||||||
|
*
|
||||||
|
* @param {*} slide
|
||||||
|
*
|
||||||
|
* @returns {string|null}
|
||||||
|
*/
|
||||||
|
getContrastClass( slide ) {
|
||||||
|
|
||||||
|
const element = slide.slideBackgroundElement;
|
||||||
|
|
||||||
// If this slide has a background color, we add a class that
|
// If this slide has a background color, we add a class that
|
||||||
// signals if it is light or dark. If the slide has no background
|
// signals if it is light or dark. If the slide has no background
|
||||||
// color, no class will be added
|
// color, no class will be added
|
||||||
let contrastColor = data.backgroundColor;
|
let contrastColor = slide.getAttribute( 'data-background-color' );
|
||||||
|
|
||||||
// If no bg color was found, or it cannot be converted by colorToRgb, check the computed background
|
// If no bg color was found, or it cannot be converted by colorToRgb, check the computed background
|
||||||
if( !contrastColor || !colorToRgb( contrastColor ) ) {
|
if( !contrastColor || !colorToRgb( contrastColor ) ) {
|
||||||
@@ -208,14 +231,32 @@ export default class Backgrounds {
|
|||||||
// an element with no background
|
// an element with no background
|
||||||
if( rgb && rgb.a !== 0 ) {
|
if( rgb && rgb.a !== 0 ) {
|
||||||
if( colorBrightness( contrastColor ) < 128 ) {
|
if( colorBrightness( contrastColor ) < 128 ) {
|
||||||
slide.classList.add( 'has-dark-background' );
|
return 'has-dark-background';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
slide.classList.add( 'has-light-background' );
|
return 'has-light-background';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bubble the 'has-light-background'/'has-dark-background' classes.
|
||||||
|
*/
|
||||||
|
bubbleSlideContrastClassToElement( slide, target ) {
|
||||||
|
|
||||||
|
[ 'has-light-background', 'has-dark-background' ].forEach( classToBubble => {
|
||||||
|
if( slide.classList.contains( classToBubble ) ) {
|
||||||
|
target.classList.add( classToBubble );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
target.classList.remove( classToBubble );
|
||||||
|
}
|
||||||
|
}, this );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -260,10 +301,12 @@ export default class Backgrounds {
|
|||||||
|
|
||||||
backgroundv.classList.remove( 'past', 'present', 'future' );
|
backgroundv.classList.remove( 'past', 'present', 'future' );
|
||||||
|
|
||||||
if( v < indices.v ) {
|
const indexv = typeof indices.v === 'number' ? indices.v : 0;
|
||||||
|
|
||||||
|
if( v < indexv ) {
|
||||||
backgroundv.classList.add( 'past' );
|
backgroundv.classList.add( 'past' );
|
||||||
}
|
}
|
||||||
else if ( v > indices.v ) {
|
else if ( v > indexv ) {
|
||||||
backgroundv.classList.add( 'future' );
|
backgroundv.classList.add( 'future' );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -319,14 +362,7 @@ export default class Backgrounds {
|
|||||||
// If there's a background brightness flag for this slide,
|
// If there's a background brightness flag for this slide,
|
||||||
// bubble it to the .reveal container
|
// bubble it to the .reveal container
|
||||||
if( currentSlide ) {
|
if( currentSlide ) {
|
||||||
[ 'has-light-background', 'has-dark-background' ].forEach( classToBubble => {
|
this.bubbleSlideContrastClassToElement( currentSlide, this.Reveal.getRevealElement() );
|
||||||
if( currentSlide.classList.contains( classToBubble ) ) {
|
|
||||||
this.Reveal.getRevealElement().classList.add( classToBubble );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.Reveal.getRevealElement().classList.remove( classToBubble );
|
|
||||||
}
|
|
||||||
}, this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow the first background to apply without transition
|
// Allow the first background to apply without transition
|
||||||
@@ -394,4 +430,10 @@ export default class Backgrounds {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
|
||||||
|
this.element.remove();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
7
js/controllers/controls.js
vendored
7
js/controllers/controls.js
vendored
@@ -188,6 +188,13 @@ export default class Controls {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
|
||||||
|
this.unbind();
|
||||||
|
this.element.remove();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event handlers for navigation control buttons.
|
* Event handlers for navigation control buttons.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -79,6 +79,12 @@ export default class Focus {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
|
||||||
|
this.Reveal.getRevealElement().classList.remove( 'focused' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
onRevealPointerDown( event ) {
|
onRevealPointerDown( event ) {
|
||||||
|
|
||||||
this.focus();
|
this.focus();
|
||||||
|
|||||||
@@ -174,24 +174,23 @@ export default class Fragments {
|
|||||||
*
|
*
|
||||||
* @return {{shown: array, hidden: array}}
|
* @return {{shown: array, hidden: array}}
|
||||||
*/
|
*/
|
||||||
update( index, fragments ) {
|
update( index, fragments, slide = this.Reveal.getCurrentSlide() ) {
|
||||||
|
|
||||||
let changedFragments = {
|
let changedFragments = {
|
||||||
shown: [],
|
shown: [],
|
||||||
hidden: []
|
hidden: []
|
||||||
};
|
};
|
||||||
|
|
||||||
let currentSlide = this.Reveal.getCurrentSlide();
|
if( slide && this.Reveal.getConfig().fragments ) {
|
||||||
if( currentSlide && this.Reveal.getConfig().fragments ) {
|
|
||||||
|
|
||||||
fragments = fragments || this.sort( currentSlide.querySelectorAll( '.fragment' ) );
|
fragments = fragments || this.sort( slide.querySelectorAll( '.fragment' ) );
|
||||||
|
|
||||||
if( fragments.length ) {
|
if( fragments.length ) {
|
||||||
|
|
||||||
let maxIndex = 0;
|
let maxIndex = 0;
|
||||||
|
|
||||||
if( typeof index !== 'number' ) {
|
if( typeof index !== 'number' ) {
|
||||||
let currentFragment = this.sort( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
|
let currentFragment = this.sort( slide.querySelectorAll( '.fragment.visible' ) ).pop();
|
||||||
if( currentFragment ) {
|
if( currentFragment ) {
|
||||||
index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
|
index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
|
||||||
}
|
}
|
||||||
@@ -252,7 +251,7 @@ export default class Fragments {
|
|||||||
// the current fragment index.
|
// the current fragment index.
|
||||||
index = typeof index === 'number' ? index : -1;
|
index = typeof index === 'number' ? index : -1;
|
||||||
index = Math.max( Math.min( index, maxIndex ), -1 );
|
index = Math.max( Math.min( index, maxIndex ), -1 );
|
||||||
currentSlide.setAttribute( 'data-fragment', index );
|
slide.setAttribute( 'data-fragment', index );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
170
js/controllers/jumptoslide.js
Normal file
170
js/controllers/jumptoslide.js
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
/**
|
||||||
|
* Makes it possible to jump to a slide by entering its
|
||||||
|
* slide number or id.
|
||||||
|
*/
|
||||||
|
export default class JumpToSlide {
|
||||||
|
|
||||||
|
constructor( Reveal ) {
|
||||||
|
|
||||||
|
this.Reveal = Reveal;
|
||||||
|
|
||||||
|
this.onInput = this.onInput.bind( this );
|
||||||
|
this.onBlur = this.onBlur.bind( this );
|
||||||
|
this.onKeyDown = this.onKeyDown.bind( this );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
this.element = document.createElement( 'div' );
|
||||||
|
this.element.className = 'jump-to-slide';
|
||||||
|
|
||||||
|
this.jumpInput = document.createElement( 'input' );
|
||||||
|
this.jumpInput.type = 'text';
|
||||||
|
this.jumpInput.className = 'jump-to-slide-input';
|
||||||
|
this.jumpInput.placeholder = 'Jump to slide';
|
||||||
|
this.jumpInput.addEventListener( 'input', this.onInput );
|
||||||
|
this.jumpInput.addEventListener( 'keydown', this.onKeyDown );
|
||||||
|
this.jumpInput.addEventListener( 'blur', this.onBlur );
|
||||||
|
|
||||||
|
this.element.appendChild( this.jumpInput );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
|
||||||
|
this.indicesOnShow = this.Reveal.getIndices();
|
||||||
|
|
||||||
|
this.Reveal.getRevealElement().appendChild( this.element );
|
||||||
|
this.jumpInput.focus();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
|
||||||
|
if( this.isVisible() ) {
|
||||||
|
this.element.remove();
|
||||||
|
this.jumpInput.value = '';
|
||||||
|
|
||||||
|
clearTimeout( this.jumpTimeout );
|
||||||
|
delete this.jumpTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
isVisible() {
|
||||||
|
|
||||||
|
return !!this.element.parentNode;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the current input and jumps to the given slide.
|
||||||
|
*/
|
||||||
|
jump() {
|
||||||
|
|
||||||
|
clearTimeout( this.jumpTimeout );
|
||||||
|
delete this.jumpTimeout;
|
||||||
|
|
||||||
|
const query = this.jumpInput.value.trim( '' );
|
||||||
|
let indices = this.Reveal.location.getIndicesFromHash( query, { oneBasedIndex: true } );
|
||||||
|
|
||||||
|
// If no valid index was found and the input query is a
|
||||||
|
// string, fall back on a simple search
|
||||||
|
if( !indices && /\S+/i.test( query ) && query.length > 1 ) {
|
||||||
|
indices = this.search( query );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( indices && query !== '' ) {
|
||||||
|
this.Reveal.slide( indices.h, indices.v, indices.f );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.Reveal.slide( this.indicesOnShow.h, this.indicesOnShow.v, this.indicesOnShow.f );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
jumpAfter( delay ) {
|
||||||
|
|
||||||
|
clearTimeout( this.jumpTimeout );
|
||||||
|
this.jumpTimeout = setTimeout( () => this.jump(), delay );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A lofi search that looks for the given query in all
|
||||||
|
* of our slides and returns the first match.
|
||||||
|
*/
|
||||||
|
search( query ) {
|
||||||
|
|
||||||
|
const regex = new RegExp( '\\b' + query.trim() + '\\b', 'i' );
|
||||||
|
|
||||||
|
const slide = this.Reveal.getSlides().find( ( slide ) => {
|
||||||
|
return regex.test( slide.innerText );
|
||||||
|
} );
|
||||||
|
|
||||||
|
if( slide ) {
|
||||||
|
return this.Reveal.getIndices( slide );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverts back to the slide we were on when jump to slide was
|
||||||
|
* invoked.
|
||||||
|
*/
|
||||||
|
cancel() {
|
||||||
|
|
||||||
|
this.Reveal.slide( this.indicesOnShow.h, this.indicesOnShow.v, this.indicesOnShow.f );
|
||||||
|
this.hide();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
confirm() {
|
||||||
|
|
||||||
|
this.jump();
|
||||||
|
this.hide();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
|
||||||
|
this.jumpInput.removeEventListener( 'input', this.onInput );
|
||||||
|
this.jumpInput.removeEventListener( 'keydown', this.onKeyDown );
|
||||||
|
this.jumpInput.removeEventListener( 'blur', this.onBlur );
|
||||||
|
|
||||||
|
this.element.remove();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyDown( event ) {
|
||||||
|
|
||||||
|
if( event.keyCode === 13 ) {
|
||||||
|
this.confirm();
|
||||||
|
}
|
||||||
|
else if( event.keyCode === 27 ) {
|
||||||
|
this.cancel();
|
||||||
|
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onInput( event ) {
|
||||||
|
|
||||||
|
this.jumpAfter( 200 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onBlur() {
|
||||||
|
|
||||||
|
setTimeout( () => this.hide(), 1 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@ export default class Keyboard {
|
|||||||
this.bindings = {};
|
this.bindings = {};
|
||||||
|
|
||||||
this.onDocumentKeyDown = this.onDocumentKeyDown.bind( this );
|
this.onDocumentKeyDown = this.onDocumentKeyDown.bind( this );
|
||||||
this.onDocumentKeyPress = this.onDocumentKeyPress.bind( this );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,17 +31,18 @@ export default class Keyboard {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.shortcuts['N , SPACE'] = 'Next slide';
|
this.shortcuts['N , SPACE'] = 'Next slide';
|
||||||
this.shortcuts['P'] = 'Previous slide';
|
this.shortcuts['P , Shift SPACE'] = 'Previous slide';
|
||||||
this.shortcuts['← , H'] = 'Navigate left';
|
this.shortcuts['← , H'] = 'Navigate left';
|
||||||
this.shortcuts['→ , L'] = 'Navigate right';
|
this.shortcuts['→ , L'] = 'Navigate right';
|
||||||
this.shortcuts['↑ , K'] = 'Navigate up';
|
this.shortcuts['↑ , K'] = 'Navigate up';
|
||||||
this.shortcuts['↓ , J'] = 'Navigate down';
|
this.shortcuts['↓ , J'] = 'Navigate down';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.shortcuts['Home , Shift ←'] = 'First slide';
|
this.shortcuts['Alt + ←/↑/→/↓'] = 'Navigate without fragments';
|
||||||
this.shortcuts['End , Shift →'] = 'Last slide';
|
this.shortcuts['Shift + ←/↑/→/↓'] = 'Jump to first/last slide';
|
||||||
this.shortcuts['B , .'] = 'Pause';
|
this.shortcuts['B , .'] = 'Pause';
|
||||||
this.shortcuts['F'] = 'Fullscreen';
|
this.shortcuts['F'] = 'Fullscreen';
|
||||||
|
this.shortcuts['G'] = 'Jump to slide';
|
||||||
this.shortcuts['ESC, O'] = 'Slide overview';
|
this.shortcuts['ESC, O'] = 'Slide overview';
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,6 @@ export default class Keyboard {
|
|||||||
bind() {
|
bind() {
|
||||||
|
|
||||||
document.addEventListener( 'keydown', this.onDocumentKeyDown, false );
|
document.addEventListener( 'keydown', this.onDocumentKeyDown, false );
|
||||||
document.addEventListener( 'keypress', this.onDocumentKeyPress, false );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +62,6 @@ export default class Keyboard {
|
|||||||
unbind() {
|
unbind() {
|
||||||
|
|
||||||
document.removeEventListener( 'keydown', this.onDocumentKeyDown, false );
|
document.removeEventListener( 'keydown', this.onDocumentKeyDown, false );
|
||||||
document.removeEventListener( 'keypress', this.onDocumentKeyPress, false );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,20 +132,6 @@ export default class Keyboard {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for the document level 'keypress' event.
|
|
||||||
*
|
|
||||||
* @param {object} event
|
|
||||||
*/
|
|
||||||
onDocumentKeyPress( event ) {
|
|
||||||
|
|
||||||
// Check if the pressed key is question mark
|
|
||||||
if( event.shiftKey && event.charCode === 63 ) {
|
|
||||||
this.Reveal.toggleHelp();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for the document level 'keydown' event.
|
* Handler for the document level 'keydown' event.
|
||||||
*
|
*
|
||||||
@@ -182,13 +166,11 @@ export default class Keyboard {
|
|||||||
let activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );
|
let activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );
|
||||||
let activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);
|
let activeElementIsNotes = document.activeElement && document.activeElement.className && /speaker-notes/i.test( document.activeElement.className);
|
||||||
|
|
||||||
// Whitelist specific modified + keycode combinations
|
// Whitelist certain modifiers for slide navigation shortcuts
|
||||||
let prevSlideShortcut = event.shiftKey && event.keyCode === 32;
|
let keyCodeUsesModifier = [32, 37, 38, 39, 40, 78, 80, 191].indexOf( event.keyCode ) !== -1;
|
||||||
let firstSlideShortcut = event.shiftKey && keyCode === 37;
|
|
||||||
let lastSlideShortcut = event.shiftKey && keyCode === 39;
|
|
||||||
|
|
||||||
// Prevent all other events when a modifier is pressed
|
// Prevent all other events when a modifier is pressed
|
||||||
let unusedModifier = !prevSlideShortcut && !firstSlideShortcut && !lastSlideShortcut &&
|
let unusedModifier = !( keyCodeUsesModifier && event.shiftKey || event.altKey ) &&
|
||||||
( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );
|
( event.shiftKey || event.altKey || event.ctrlKey || event.metaKey );
|
||||||
|
|
||||||
// Disregard the event if there's a focused element or a
|
// Disregard the event if there's a focused element or a
|
||||||
@@ -277,52 +259,58 @@ export default class Keyboard {
|
|||||||
|
|
||||||
// P, PAGE UP
|
// P, PAGE UP
|
||||||
if( keyCode === 80 || keyCode === 33 ) {
|
if( keyCode === 80 || keyCode === 33 ) {
|
||||||
this.Reveal.prev();
|
this.Reveal.prev({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
// N, PAGE DOWN
|
// N, PAGE DOWN
|
||||||
else if( keyCode === 78 || keyCode === 34 ) {
|
else if( keyCode === 78 || keyCode === 34 ) {
|
||||||
this.Reveal.next();
|
this.Reveal.next({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
// H, LEFT
|
// H, LEFT
|
||||||
else if( keyCode === 72 || keyCode === 37 ) {
|
else if( keyCode === 72 || keyCode === 37 ) {
|
||||||
if( firstSlideShortcut ) {
|
if( event.shiftKey ) {
|
||||||
this.Reveal.slide( 0 );
|
this.Reveal.slide( 0 );
|
||||||
}
|
}
|
||||||
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
this.Reveal.prev();
|
this.Reveal.prev({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.Reveal.left();
|
this.Reveal.left({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// L, RIGHT
|
// L, RIGHT
|
||||||
else if( keyCode === 76 || keyCode === 39 ) {
|
else if( keyCode === 76 || keyCode === 39 ) {
|
||||||
if( lastSlideShortcut ) {
|
if( event.shiftKey ) {
|
||||||
this.Reveal.slide( Number.MAX_VALUE );
|
this.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );
|
||||||
}
|
}
|
||||||
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
this.Reveal.next();
|
this.Reveal.next({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.Reveal.right();
|
this.Reveal.right({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// K, UP
|
// K, UP
|
||||||
else if( keyCode === 75 || keyCode === 38 ) {
|
else if( keyCode === 75 || keyCode === 38 ) {
|
||||||
if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
if( event.shiftKey ) {
|
||||||
this.Reveal.prev();
|
this.Reveal.slide( undefined, 0 );
|
||||||
|
}
|
||||||
|
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
|
this.Reveal.prev({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.Reveal.up();
|
this.Reveal.up({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// J, DOWN
|
// J, DOWN
|
||||||
else if( keyCode === 74 || keyCode === 40 ) {
|
else if( keyCode === 74 || keyCode === 40 ) {
|
||||||
if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
if( event.shiftKey ) {
|
||||||
this.Reveal.next();
|
this.Reveal.slide( undefined, Number.MAX_VALUE );
|
||||||
|
}
|
||||||
|
else if( !this.Reveal.overview.isActive() && useLinearMode ) {
|
||||||
|
this.Reveal.next({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.Reveal.down();
|
this.Reveal.down({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// HOME
|
// HOME
|
||||||
@@ -331,7 +319,7 @@ export default class Keyboard {
|
|||||||
}
|
}
|
||||||
// END
|
// END
|
||||||
else if( keyCode === 35 ) {
|
else if( keyCode === 35 ) {
|
||||||
this.Reveal.slide( Number.MAX_VALUE );
|
this.Reveal.slide( this.Reveal.getHorizontalSlides().length - 1 );
|
||||||
}
|
}
|
||||||
// SPACE
|
// SPACE
|
||||||
else if( keyCode === 32 ) {
|
else if( keyCode === 32 ) {
|
||||||
@@ -339,14 +327,14 @@ export default class Keyboard {
|
|||||||
this.Reveal.overview.deactivate();
|
this.Reveal.overview.deactivate();
|
||||||
}
|
}
|
||||||
if( event.shiftKey ) {
|
if( event.shiftKey ) {
|
||||||
this.Reveal.prev();
|
this.Reveal.prev({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.Reveal.next();
|
this.Reveal.next({skipFragments: event.altKey});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON
|
// TWO-SPOT, SEMICOLON, B, V, PERIOD, LOGITECH PRESENTER TOOLS "BLACK SCREEN" BUTTON
|
||||||
else if( keyCode === 58 || keyCode === 59 || keyCode === 66 || keyCode === 86 || keyCode === 190 || keyCode === 191 ) {
|
else if( [58, 59, 66, 86, 190].includes( keyCode ) || ( keyCode === 191 && !event.shiftKey ) ) {
|
||||||
this.Reveal.togglePause();
|
this.Reveal.togglePause();
|
||||||
}
|
}
|
||||||
// F
|
// F
|
||||||
@@ -355,10 +343,20 @@ export default class Keyboard {
|
|||||||
}
|
}
|
||||||
// A
|
// A
|
||||||
else if( keyCode === 65 ) {
|
else if( keyCode === 65 ) {
|
||||||
if ( config.autoSlideStoppable ) {
|
if( config.autoSlideStoppable ) {
|
||||||
this.Reveal.toggleAutoSlide( autoSlideWasPaused );
|
this.Reveal.toggleAutoSlide( autoSlideWasPaused );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// G
|
||||||
|
else if( keyCode === 71 ) {
|
||||||
|
if( config.jumpToSlide ) {
|
||||||
|
this.Reveal.toggleJumpToSlide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ?
|
||||||
|
else if( keyCode === 191 && event.shiftKey ) {
|
||||||
|
this.Reveal.toggleHelp();
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
triggered = false;
|
triggered = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
*/
|
*/
|
||||||
export default class Location {
|
export default class Location {
|
||||||
|
|
||||||
|
// The minimum number of milliseconds that must pass between
|
||||||
|
// calls to history.replaceState
|
||||||
|
MAX_REPLACE_STATE_FREQUENCY = 1000
|
||||||
|
|
||||||
constructor( Reveal ) {
|
constructor( Reveal ) {
|
||||||
|
|
||||||
this.Reveal = Reveal;
|
this.Reveal = Reveal;
|
||||||
@@ -10,6 +14,8 @@ export default class Location {
|
|||||||
// Delays updates to the URL due to a Chrome thumbnailer bug
|
// Delays updates to the URL due to a Chrome thumbnailer bug
|
||||||
this.writeURLTimeout = 0;
|
this.writeURLTimeout = 0;
|
||||||
|
|
||||||
|
this.replaceStateTimestamp = 0;
|
||||||
|
|
||||||
this.onWindowHashChange = this.onWindowHashChange.bind( this );
|
this.onWindowHashChange = this.onWindowHashChange.bind( this );
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -27,24 +33,23 @@ export default class Location {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the current URL (hash) and navigates accordingly.
|
* Returns the slide indices for the given hash link.
|
||||||
|
*
|
||||||
|
* @param {string} [hash] the hash string that we want to
|
||||||
|
* find the indices for
|
||||||
|
*
|
||||||
|
* @returns slide indices or null
|
||||||
*/
|
*/
|
||||||
readURL() {
|
getIndicesFromHash( hash=window.location.hash, options={} ) {
|
||||||
|
|
||||||
let config = this.Reveal.getConfig();
|
|
||||||
let indices = this.Reveal.getIndices();
|
|
||||||
let currentSlide = this.Reveal.getCurrentSlide();
|
|
||||||
|
|
||||||
let hash = window.location.hash;
|
|
||||||
|
|
||||||
// Attempt to parse the hash as either an index or name
|
// Attempt to parse the hash as either an index or name
|
||||||
let bits = hash.slice( 2 ).split( '/' ),
|
let name = hash.replace( /^#\/?/, '' );
|
||||||
name = hash.replace( /#\/?/gi, '' );
|
let bits = name.split( '/' );
|
||||||
|
|
||||||
// If the first bit is not fully numeric and there is a name we
|
// If the first bit is not fully numeric and there is a name we
|
||||||
// can assume that this is a named link
|
// can assume that this is a named link
|
||||||
if( !/^[0-9]*$/.test( bits[0] ) && name.length ) {
|
if( !/^[0-9]*$/.test( bits[0] ) && name.length ) {
|
||||||
let element;
|
let slide;
|
||||||
|
|
||||||
let f;
|
let f;
|
||||||
|
|
||||||
@@ -57,28 +62,19 @@ export default class Location {
|
|||||||
|
|
||||||
// Ensure the named link is a valid HTML ID attribute
|
// Ensure the named link is a valid HTML ID attribute
|
||||||
try {
|
try {
|
||||||
element = document.getElementById( decodeURIComponent( name ) );
|
slide = document
|
||||||
|
.getElementById( decodeURIComponent( name ) )
|
||||||
|
.closest('.slides section');
|
||||||
}
|
}
|
||||||
catch ( error ) { }
|
catch ( error ) { }
|
||||||
|
|
||||||
// Ensure that we're not already on a slide with the same name
|
if( slide ) {
|
||||||
let isSameNameAsCurrentSlide = currentSlide ? currentSlide.getAttribute( 'id' ) === name : false;
|
return { ...this.Reveal.getIndices( slide ), f };
|
||||||
|
|
||||||
if( element ) {
|
|
||||||
// If the slide exists and is not the current slide...
|
|
||||||
if ( !isSameNameAsCurrentSlide || typeof f !== 'undefined' ) {
|
|
||||||
// ...find the position of the named slide and navigate to it
|
|
||||||
let slideIndices = this.Reveal.getIndices( element );
|
|
||||||
this.Reveal.slide( slideIndices.h, slideIndices.v, f );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If the slide doesn't exist, navigate to the current slide
|
|
||||||
else {
|
|
||||||
this.Reveal.slide( indices.h || 0, indices.v || 0 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let hashIndexBase = config.hashOneBasedIndex ? 1 : 0;
|
const config = this.Reveal.getConfig();
|
||||||
|
let hashIndexBase = config.hashOneBasedIndex || options.oneBasedIndex ? 1 : 0;
|
||||||
|
|
||||||
// Read the index components of the hash
|
// Read the index components of the hash
|
||||||
let h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0,
|
let h = ( parseInt( bits[0], 10 ) - hashIndexBase ) || 0,
|
||||||
@@ -92,9 +88,31 @@ export default class Location {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( h !== indices.h || v !== indices.v || f !== undefined ) {
|
return { h, v, f };
|
||||||
this.Reveal.slide( h, v, f );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The hash couldn't be parsed or no matching named link was found
|
||||||
|
return null
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the current URL (hash) and navigates accordingly.
|
||||||
|
*/
|
||||||
|
readURL() {
|
||||||
|
|
||||||
|
const currentIndices = this.Reveal.getIndices();
|
||||||
|
const newIndices = this.getIndicesFromHash();
|
||||||
|
|
||||||
|
if( newIndices ) {
|
||||||
|
if( ( newIndices.h !== currentIndices.h || newIndices.v !== currentIndices.v || newIndices.f !== undefined ) ) {
|
||||||
|
this.Reveal.slide( newIndices.h, newIndices.v, newIndices.f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If no new indices are available, we're trying to navigate to
|
||||||
|
// a slide hash that does not exist
|
||||||
|
else {
|
||||||
|
this.Reveal.slide( currentIndices.h || 0, currentIndices.v || 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -123,7 +141,7 @@ export default class Location {
|
|||||||
let hash = this.getHash();
|
let hash = this.getHash();
|
||||||
|
|
||||||
// If we're configured to push to history OR the history
|
// If we're configured to push to history OR the history
|
||||||
// API is not avaialble.
|
// API is not available.
|
||||||
if( config.history ) {
|
if( config.history ) {
|
||||||
window.location.hash = hash;
|
window.location.hash = hash;
|
||||||
}
|
}
|
||||||
@@ -132,10 +150,10 @@ export default class Location {
|
|||||||
else if( config.hash ) {
|
else if( config.hash ) {
|
||||||
// If the hash is empty, don't add it to the URL
|
// If the hash is empty, don't add it to the URL
|
||||||
if( hash === '/' ) {
|
if( hash === '/' ) {
|
||||||
window.history.replaceState( null, null, window.location.pathname + window.location.search );
|
this.debouncedReplaceState( window.location.pathname + window.location.search );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
window.history.replaceState( null, null, '#' + hash );
|
this.debouncedReplaceState( '#' + hash );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// UPDATE: The below nuking of all hash changes breaks
|
// UPDATE: The below nuking of all hash changes breaks
|
||||||
@@ -153,6 +171,26 @@ export default class Location {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
replaceState( url ) {
|
||||||
|
|
||||||
|
window.history.replaceState( null, null, url );
|
||||||
|
this.replaceStateTimestamp = Date.now();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
debouncedReplaceState( url ) {
|
||||||
|
|
||||||
|
clearTimeout( this.replaceStateTimeout );
|
||||||
|
|
||||||
|
if( Date.now() - this.replaceStateTimestamp > this.MAX_REPLACE_STATE_FREQUENCY ) {
|
||||||
|
this.replaceState( url );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.replaceStateTimeout = setTimeout( () => this.replaceState( url ), this.MAX_REPLACE_STATE_FREQUENCY );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a hash URL that will resolve to the given slide location.
|
* Return a hash URL that will resolve to the given slide location.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Handles the showing and
|
* Handles the showing of speaker notes
|
||||||
*/
|
*/
|
||||||
export default class Notes {
|
export default class Notes {
|
||||||
|
|
||||||
@@ -38,10 +38,12 @@ export default class Notes {
|
|||||||
*/
|
*/
|
||||||
update() {
|
update() {
|
||||||
|
|
||||||
if( this.Reveal.getConfig().showNotes && this.element && this.Reveal.getCurrentSlide() && !this.Reveal.print.isPrintingPDF() ) {
|
if( this.Reveal.getConfig().showNotes &&
|
||||||
|
this.element && this.Reveal.getCurrentSlide() &&
|
||||||
|
!this.Reveal.isScrollView() &&
|
||||||
|
!this.Reveal.isPrintView()
|
||||||
|
) {
|
||||||
this.element.innerHTML = this.getSlideNotes() || '<span class="notes-placeholder">No notes on this slide.</span>';
|
this.element.innerHTML = this.getSlideNotes() || '<span class="notes-placeholder">No notes on this slide.</span>';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -54,7 +56,11 @@ export default class Notes {
|
|||||||
*/
|
*/
|
||||||
updateVisibility() {
|
updateVisibility() {
|
||||||
|
|
||||||
if( this.Reveal.getConfig().showNotes && this.hasNotes() && !this.Reveal.print.isPrintingPDF() ) {
|
if( this.Reveal.getConfig().showNotes &&
|
||||||
|
this.hasNotes() &&
|
||||||
|
!this.Reveal.isScrollView() &&
|
||||||
|
!this.Reveal.isPrintView()
|
||||||
|
) {
|
||||||
this.Reveal.getRevealElement().classList.add( 'show-notes' );
|
this.Reveal.getRevealElement().classList.add( 'show-notes' );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -89,7 +95,7 @@ export default class Notes {
|
|||||||
* Retrieves the speaker notes from a slide. Notes can be
|
* Retrieves the speaker notes from a slide. Notes can be
|
||||||
* defined in two ways:
|
* defined in two ways:
|
||||||
* 1. As a data-notes attribute on the slide <section>
|
* 1. As a data-notes attribute on the slide <section>
|
||||||
* 2. As an <aside class="notes"> inside of the slide
|
* 2. With <aside class="notes"> elements inside the slide
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} [slide=currentSlide]
|
* @param {HTMLElement} [slide=currentSlide]
|
||||||
* @return {(string|null)}
|
* @return {(string|null)}
|
||||||
@@ -101,14 +107,20 @@ export default class Notes {
|
|||||||
return slide.getAttribute( 'data-notes' );
|
return slide.getAttribute( 'data-notes' );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... or using an <aside class="notes"> element
|
// ... or using <aside class="notes"> elements
|
||||||
let notesElement = slide.querySelector( 'aside.notes' );
|
let notesElements = slide.querySelectorAll( 'aside.notes' );
|
||||||
if( notesElement ) {
|
if( notesElements ) {
|
||||||
return notesElement.innerHTML;
|
return Array.from(notesElements).map( notesElement => notesElement.innerHTML ).join( '\n' );
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
|
||||||
|
this.element.remove();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ export default class Overview {
|
|||||||
activate() {
|
activate() {
|
||||||
|
|
||||||
// Only proceed if enabled in config
|
// Only proceed if enabled in config
|
||||||
if( this.Reveal.getConfig().overview && !this.isActive() ) {
|
if( this.Reveal.getConfig().overview && !this.Reveal.isScrollView() && !this.isActive() ) {
|
||||||
|
|
||||||
this.active = true;
|
this.active = true;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export default class Plugins {
|
|||||||
// Flags our current state (idle -> loading -> loaded)
|
// Flags our current state (idle -> loading -> loaded)
|
||||||
this.state = 'idle';
|
this.state = 'idle';
|
||||||
|
|
||||||
// An id:instance map of currently registed plugins
|
// An id:instance map of currently registered plugins
|
||||||
this.registeredPlugins = {};
|
this.registeredPlugins = {};
|
||||||
|
|
||||||
this.asyncDependencies = [];
|
this.asyncDependencies = [];
|
||||||
@@ -171,7 +171,7 @@ export default class Plugins {
|
|||||||
/**
|
/**
|
||||||
* Registers a new plugin with this reveal.js instance.
|
* Registers a new plugin with this reveal.js instance.
|
||||||
*
|
*
|
||||||
* reveal.js waits for all regisered plugins to initialize
|
* reveal.js waits for all registered plugins to initialize
|
||||||
* before considering itself ready, as long as the plugin
|
* before considering itself ready, as long as the plugin
|
||||||
* is registered before calling `Reveal.initialize()`.
|
* is registered before calling `Reveal.initialize()`.
|
||||||
*/
|
*/
|
||||||
@@ -238,4 +238,17 @@ export default class Plugins {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
|
||||||
|
Object.values( this.registeredPlugins ).forEach( plugin => {
|
||||||
|
if( typeof plugin.destroy === 'function' ) {
|
||||||
|
plugin.destroy();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
this.registeredPlugins = {};
|
||||||
|
this.asyncDependencies = [];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,12 +27,10 @@ export default class Pointer {
|
|||||||
configure( config, oldConfig ) {
|
configure( config, oldConfig ) {
|
||||||
|
|
||||||
if( config.mouseWheel ) {
|
if( config.mouseWheel ) {
|
||||||
document.addEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF
|
document.addEventListener( 'wheel', this.onDocumentMouseScroll, false );
|
||||||
document.addEventListener( 'mousewheel', this.onDocumentMouseScroll, false );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
document.removeEventListener( 'DOMMouseScroll', this.onDocumentMouseScroll, false ); // FF
|
document.removeEventListener( 'wheel', this.onDocumentMouseScroll, false );
|
||||||
document.removeEventListener( 'mousewheel', this.onDocumentMouseScroll, false );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-hide the mouse pointer when its inactive
|
// Auto-hide the mouse pointer when its inactive
|
||||||
@@ -75,6 +73,16 @@ export default class Pointer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
|
||||||
|
this.showCursor();
|
||||||
|
|
||||||
|
document.removeEventListener( 'wheel', this.onDocumentMouseScroll, false );
|
||||||
|
document.removeEventListener( 'mousemove', this.onDocumentCursorActive, false );
|
||||||
|
document.removeEventListener( 'mousedown', this.onDocumentCursorActive, false );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called whenever there is mouse input at the document level
|
* Called whenever there is mouse input at the document level
|
||||||
* to determine if the cursor is active or not.
|
* to determine if the cursor is active or not.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { queryAll, createStyleSheet } from '../utils/util.js'
|
|||||||
/**
|
/**
|
||||||
* Setups up our presentation for printing/exporting to PDF.
|
* Setups up our presentation for printing/exporting to PDF.
|
||||||
*/
|
*/
|
||||||
export default class Print {
|
export default class PrintView {
|
||||||
|
|
||||||
constructor( Reveal ) {
|
constructor( Reveal ) {
|
||||||
|
|
||||||
@@ -16,13 +16,13 @@ export default class Print {
|
|||||||
* Configures the presentation for printing to a static
|
* Configures the presentation for printing to a static
|
||||||
* PDF.
|
* PDF.
|
||||||
*/
|
*/
|
||||||
async setupPDF() {
|
async activate() {
|
||||||
|
|
||||||
const config = this.Reveal.getConfig();
|
const config = this.Reveal.getConfig();
|
||||||
const slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )
|
const slides = queryAll( this.Reveal.getRevealElement(), SLIDES_SELECTOR )
|
||||||
|
|
||||||
// Compute slide numbers now, before we start duplicating slides
|
// Compute slide numbers now, before we start duplicating slides
|
||||||
const doingSlideNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );
|
const injectPageNumbers = config.slideNumber && /all|print/i.test( config.showSlideNumber );
|
||||||
|
|
||||||
const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
|
const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
|
||||||
|
|
||||||
@@ -42,18 +42,23 @@ export default class Print {
|
|||||||
// Limit the size of certain elements to the dimensions of the slide
|
// Limit the size of certain elements to the dimensions of the slide
|
||||||
createStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' );
|
createStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' );
|
||||||
|
|
||||||
document.documentElement.classList.add( 'print-pdf' );
|
document.documentElement.classList.add( 'reveal-print', 'print-pdf' );
|
||||||
document.body.style.width = pageWidth + 'px';
|
document.body.style.width = pageWidth + 'px';
|
||||||
document.body.style.height = pageHeight + 'px';
|
document.body.style.height = pageHeight + 'px';
|
||||||
|
|
||||||
|
const viewportElement = this.Reveal.getViewportElement();
|
||||||
|
let presentationBackground;
|
||||||
|
if( viewportElement ) {
|
||||||
|
const viewportStyles = window.getComputedStyle( viewportElement );
|
||||||
|
if( viewportStyles && viewportStyles.background ) {
|
||||||
|
presentationBackground = viewportStyles.background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure stretch elements fit on slide
|
// Make sure stretch elements fit on slide
|
||||||
await new Promise( requestAnimationFrame );
|
await new Promise( requestAnimationFrame );
|
||||||
this.Reveal.layoutSlideContents( slideWidth, slideHeight );
|
this.Reveal.layoutSlideContents( slideWidth, slideHeight );
|
||||||
|
|
||||||
// Re-run the slide layout so that r-fit-text is applied based on
|
|
||||||
// the printed slide size
|
|
||||||
slides.forEach( slide => this.Reveal.slideContent.layout( slide ) );
|
|
||||||
|
|
||||||
// Batch scrollHeight access to prevent layout thrashing
|
// Batch scrollHeight access to prevent layout thrashing
|
||||||
await new Promise( requestAnimationFrame );
|
await new Promise( requestAnimationFrame );
|
||||||
|
|
||||||
@@ -61,6 +66,7 @@ export default class Print {
|
|||||||
|
|
||||||
const pages = [];
|
const pages = [];
|
||||||
const pageContainer = slides[0].parentNode;
|
const pageContainer = slides[0].parentNode;
|
||||||
|
let slideNumber = 1;
|
||||||
|
|
||||||
// Slide and slide background layout
|
// Slide and slide background layout
|
||||||
slides.forEach( function( slide, index ) {
|
slides.forEach( function( slide, index ) {
|
||||||
@@ -90,6 +96,13 @@ export default class Print {
|
|||||||
|
|
||||||
page.className = 'pdf-page';
|
page.className = 'pdf-page';
|
||||||
page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';
|
page.style.height = ( ( pageHeight + config.pdfPageHeightOffset ) * numberOfPages ) + 'px';
|
||||||
|
|
||||||
|
// Copy the presentation-wide background to each individual
|
||||||
|
// page when printing
|
||||||
|
if( presentationBackground ) {
|
||||||
|
page.style.background = presentationBackground;
|
||||||
|
}
|
||||||
|
|
||||||
page.appendChild( slide );
|
page.appendChild( slide );
|
||||||
|
|
||||||
// Position the slide inside of the page
|
// Position the slide inside of the page
|
||||||
@@ -97,6 +110,8 @@ export default class Print {
|
|||||||
slide.style.top = top + 'px';
|
slide.style.top = top + 'px';
|
||||||
slide.style.width = slideWidth + 'px';
|
slide.style.width = slideWidth + 'px';
|
||||||
|
|
||||||
|
this.Reveal.slideContent.layout( slide );
|
||||||
|
|
||||||
if( slide.slideBackgroundElement ) {
|
if( slide.slideBackgroundElement ) {
|
||||||
page.insertBefore( slide.slideBackgroundElement, slide );
|
page.insertBefore( slide.slideBackgroundElement, slide );
|
||||||
}
|
}
|
||||||
@@ -130,13 +145,12 @@ export default class Print {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inject slide numbers if `slideNumbers` are enabled
|
// Inject page numbers if `slideNumbers` are enabled
|
||||||
if( doingSlideNumbers ) {
|
if( injectPageNumbers ) {
|
||||||
const slideNumber = index + 1;
|
|
||||||
const numberElement = document.createElement( 'div' );
|
const numberElement = document.createElement( 'div' );
|
||||||
numberElement.classList.add( 'slide-number' );
|
numberElement.classList.add( 'slide-number' );
|
||||||
numberElement.classList.add( 'slide-number-pdf' );
|
numberElement.classList.add( 'slide-number-pdf' );
|
||||||
numberElement.innerHTML = slideNumber;
|
numberElement.innerHTML = slideNumber++;
|
||||||
page.appendChild( numberElement );
|
page.appendChild( numberElement );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +164,7 @@ export default class Print {
|
|||||||
|
|
||||||
let previousFragmentStep;
|
let previousFragmentStep;
|
||||||
|
|
||||||
fragmentGroups.forEach( function( fragments ) {
|
fragmentGroups.forEach( function( fragments, index ) {
|
||||||
|
|
||||||
// Remove 'current-fragment' from the previous group
|
// Remove 'current-fragment' from the previous group
|
||||||
if( previousFragmentStep ) {
|
if( previousFragmentStep ) {
|
||||||
@@ -166,6 +180,14 @@ export default class Print {
|
|||||||
|
|
||||||
// Create a separate page for the current fragment state
|
// Create a separate page for the current fragment state
|
||||||
const clonedPage = page.cloneNode( true );
|
const clonedPage = page.cloneNode( true );
|
||||||
|
|
||||||
|
// Inject unique page numbers for fragments
|
||||||
|
if( injectPageNumbers ) {
|
||||||
|
const numberElement = clonedPage.querySelector( '.slide-number-pdf' );
|
||||||
|
const fragmentNumber = index + 1;
|
||||||
|
numberElement.innerHTML += '.' + fragmentNumber;
|
||||||
|
}
|
||||||
|
|
||||||
pages.push( clonedPage );
|
pages.push( clonedPage );
|
||||||
|
|
||||||
previousFragmentStep = fragments;
|
previousFragmentStep = fragments;
|
||||||
@@ -195,17 +217,20 @@ export default class Print {
|
|||||||
|
|
||||||
pages.forEach( page => pageContainer.appendChild( page ) );
|
pages.forEach( page => pageContainer.appendChild( page ) );
|
||||||
|
|
||||||
|
// Re-run JS-based content layout after the slide is added to page DOM
|
||||||
|
this.Reveal.slideContent.layout( this.Reveal.getSlidesElement() );
|
||||||
|
|
||||||
// Notify subscribers that the PDF layout is good to go
|
// Notify subscribers that the PDF layout is good to go
|
||||||
this.Reveal.dispatchEvent({ type: 'pdf-ready' });
|
this.Reveal.dispatchEvent({ type: 'pdf-ready' });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if this instance is being used to print a PDF.
|
* Checks if the print mode is/should be activated.
|
||||||
*/
|
*/
|
||||||
isPrintingPDF() {
|
isActive() {
|
||||||
|
|
||||||
return ( /print-pdf/gi ).test( window.location.search );
|
return this.Reveal.getConfig().view === 'print';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,5 +101,10 @@ export default class Progress {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
|
||||||
|
this.element.remove();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
888
js/controllers/scrollview.js
Normal file
888
js/controllers/scrollview.js
Normal file
@@ -0,0 +1,888 @@
|
|||||||
|
import { HORIZONTAL_SLIDES_SELECTOR } from '../utils/constants.js'
|
||||||
|
import { queryAll } from '../utils/util.js'
|
||||||
|
|
||||||
|
const HIDE_SCROLLBAR_TIMEOUT = 500;
|
||||||
|
const MAX_PROGRESS_SPACING = 4;
|
||||||
|
const MIN_PROGRESS_SEGMENT_HEIGHT = 6;
|
||||||
|
const MIN_PLAYHEAD_HEIGHT = 8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The scroll view lets you read a reveal.js presentation
|
||||||
|
* as a linear scrollable page.
|
||||||
|
*/
|
||||||
|
export default class ScrollView {
|
||||||
|
|
||||||
|
constructor( Reveal ) {
|
||||||
|
|
||||||
|
this.Reveal = Reveal;
|
||||||
|
|
||||||
|
this.active = false;
|
||||||
|
this.activatedCallbacks = [];
|
||||||
|
|
||||||
|
this.onScroll = this.onScroll.bind( this );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activates the scroll view. This rearranges the presentation DOM
|
||||||
|
* by—among other things—wrapping each slide in a page element.
|
||||||
|
*/
|
||||||
|
activate() {
|
||||||
|
|
||||||
|
if( this.active ) return;
|
||||||
|
|
||||||
|
const stateBeforeActivation = this.Reveal.getState();
|
||||||
|
|
||||||
|
this.active = true;
|
||||||
|
|
||||||
|
// Store the full presentation HTML so that we can restore it
|
||||||
|
// when/if the scroll view is deactivated
|
||||||
|
this.slideHTMLBeforeActivation = this.Reveal.getSlidesElement().innerHTML;
|
||||||
|
|
||||||
|
const horizontalSlides = queryAll( this.Reveal.getRevealElement(), HORIZONTAL_SLIDES_SELECTOR );
|
||||||
|
|
||||||
|
this.viewportElement.classList.add( 'loading-scroll-mode', 'reveal-scroll' );
|
||||||
|
|
||||||
|
let presentationBackground;
|
||||||
|
|
||||||
|
const viewportStyles = window.getComputedStyle( this.viewportElement );
|
||||||
|
if( viewportStyles && viewportStyles.background ) {
|
||||||
|
presentationBackground = viewportStyles.background;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageElements = [];
|
||||||
|
const pageContainer = horizontalSlides[0].parentNode;
|
||||||
|
|
||||||
|
let previousSlide;
|
||||||
|
|
||||||
|
// Creates a new page element and appends the given slide/bg
|
||||||
|
// to it.
|
||||||
|
const createPageElement = ( slide, h, v ) => {
|
||||||
|
|
||||||
|
let contentContainer;
|
||||||
|
|
||||||
|
// If this slide is part of an auto-animation sequence, we
|
||||||
|
// group it under the same page element as the previous slide
|
||||||
|
if( previousSlide && this.Reveal.shouldAutoAnimateBetween( previousSlide, slide ) ) {
|
||||||
|
contentContainer = document.createElement( 'div' );
|
||||||
|
contentContainer.className = 'scroll-page-content scroll-auto-animate-page';
|
||||||
|
contentContainer.style.display = 'none';
|
||||||
|
previousSlide.closest( '.scroll-page-content' ).parentNode.appendChild( contentContainer );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Wrap the slide in a page element and hide its overflow
|
||||||
|
// so that no page ever flows onto another
|
||||||
|
const page = document.createElement( 'div' );
|
||||||
|
page.className = 'scroll-page';
|
||||||
|
pageElements.push( page );
|
||||||
|
|
||||||
|
// Copy the presentation-wide background to each page
|
||||||
|
if( presentationBackground ) {
|
||||||
|
page.style.background = presentationBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stickyContainer = document.createElement( 'div' );
|
||||||
|
stickyContainer.className = 'scroll-page-sticky';
|
||||||
|
page.appendChild( stickyContainer );
|
||||||
|
|
||||||
|
contentContainer = document.createElement( 'div' );
|
||||||
|
contentContainer.className = 'scroll-page-content';
|
||||||
|
stickyContainer.appendChild( contentContainer );
|
||||||
|
}
|
||||||
|
|
||||||
|
contentContainer.appendChild( slide );
|
||||||
|
|
||||||
|
slide.classList.remove( 'past', 'future' );
|
||||||
|
slide.setAttribute( 'data-index-h', h );
|
||||||
|
slide.setAttribute( 'data-index-v', v );
|
||||||
|
|
||||||
|
if( slide.slideBackgroundElement ) {
|
||||||
|
slide.slideBackgroundElement.remove( 'past', 'future' );
|
||||||
|
contentContainer.insertBefore( slide.slideBackgroundElement, slide );
|
||||||
|
}
|
||||||
|
|
||||||
|
previousSlide = slide;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slide and slide background layout
|
||||||
|
horizontalSlides.forEach( ( horizontalSlide, h ) => {
|
||||||
|
|
||||||
|
if( this.Reveal.isVerticalStack( horizontalSlide ) ) {
|
||||||
|
horizontalSlide.querySelectorAll( 'section' ).forEach( ( verticalSlide, v ) => {
|
||||||
|
createPageElement( verticalSlide, h, v );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
createPageElement( horizontalSlide, h, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
}, this );
|
||||||
|
|
||||||
|
this.createProgressBar();
|
||||||
|
|
||||||
|
// Remove leftover stacks
|
||||||
|
queryAll( this.Reveal.getRevealElement(), '.stack' ).forEach( stack => stack.remove() );
|
||||||
|
|
||||||
|
// Add our newly created pages to the DOM
|
||||||
|
pageElements.forEach( page => pageContainer.appendChild( page ) );
|
||||||
|
|
||||||
|
// Re-run JS-based content layout after the slide is added to page DOM
|
||||||
|
this.Reveal.slideContent.layout( this.Reveal.getSlidesElement() );
|
||||||
|
|
||||||
|
this.Reveal.layout();
|
||||||
|
this.Reveal.setState( stateBeforeActivation );
|
||||||
|
|
||||||
|
this.activatedCallbacks.forEach( callback => callback() );
|
||||||
|
this.activatedCallbacks = [];
|
||||||
|
|
||||||
|
this.restoreScrollPosition();
|
||||||
|
|
||||||
|
this.viewportElement.classList.remove( 'loading-scroll-mode' );
|
||||||
|
this.viewportElement.addEventListener( 'scroll', this.onScroll, { passive: true } );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivates the scroll view and restores the standard slide-based
|
||||||
|
* presentation.
|
||||||
|
*/
|
||||||
|
deactivate() {
|
||||||
|
|
||||||
|
if( !this.active ) return;
|
||||||
|
|
||||||
|
const stateBeforeDeactivation = this.Reveal.getState();
|
||||||
|
|
||||||
|
this.active = false;
|
||||||
|
|
||||||
|
this.viewportElement.removeEventListener( 'scroll', this.onScroll );
|
||||||
|
this.viewportElement.classList.remove( 'reveal-scroll' );
|
||||||
|
|
||||||
|
this.removeProgressBar();
|
||||||
|
|
||||||
|
this.Reveal.getSlidesElement().innerHTML = this.slideHTMLBeforeActivation;
|
||||||
|
this.Reveal.sync();
|
||||||
|
this.Reveal.setState( stateBeforeDeactivation );
|
||||||
|
|
||||||
|
this.slideHTMLBeforeActivation = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle( override ) {
|
||||||
|
|
||||||
|
if( typeof override === 'boolean' ) {
|
||||||
|
override ? this.activate() : this.deactivate();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.isActive() ? this.deactivate() : this.activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the scroll view is currently active.
|
||||||
|
*/
|
||||||
|
isActive() {
|
||||||
|
|
||||||
|
return this.active;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the progress bar component.
|
||||||
|
*/
|
||||||
|
createProgressBar() {
|
||||||
|
|
||||||
|
this.progressBar = document.createElement( 'div' );
|
||||||
|
this.progressBar.className = 'scrollbar';
|
||||||
|
|
||||||
|
this.progressBarInner = document.createElement( 'div' );
|
||||||
|
this.progressBarInner.className = 'scrollbar-inner';
|
||||||
|
this.progressBar.appendChild( this.progressBarInner );
|
||||||
|
|
||||||
|
this.progressBarPlayhead = document.createElement( 'div' );
|
||||||
|
this.progressBarPlayhead.className = 'scrollbar-playhead';
|
||||||
|
this.progressBarInner.appendChild( this.progressBarPlayhead );
|
||||||
|
|
||||||
|
this.viewportElement.insertBefore( this.progressBar, this.viewportElement.firstChild );
|
||||||
|
|
||||||
|
const handleDocumentMouseMove = ( event ) => {
|
||||||
|
|
||||||
|
let progress = ( event.clientY - this.progressBarInner.getBoundingClientRect().top ) / this.progressBarHeight;
|
||||||
|
progress = Math.max( Math.min( progress, 1 ), 0 );
|
||||||
|
|
||||||
|
this.viewportElement.scrollTop = progress * ( this.viewportElement.scrollHeight - this.viewportElement.offsetHeight );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDocumentMouseUp = ( event ) => {
|
||||||
|
|
||||||
|
this.draggingProgressBar = false;
|
||||||
|
this.showProgressBar();
|
||||||
|
|
||||||
|
document.removeEventListener( 'mousemove', handleDocumentMouseMove );
|
||||||
|
document.removeEventListener( 'mouseup', handleDocumentMouseUp );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseDown = ( event ) => {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
this.draggingProgressBar = true;
|
||||||
|
|
||||||
|
document.addEventListener( 'mousemove', handleDocumentMouseMove );
|
||||||
|
document.addEventListener( 'mouseup', handleDocumentMouseUp );
|
||||||
|
|
||||||
|
handleDocumentMouseMove( event );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.progressBarInner.addEventListener( 'mousedown', handleMouseDown );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
removeProgressBar() {
|
||||||
|
|
||||||
|
if( this.progressBar ) {
|
||||||
|
this.progressBar.remove();
|
||||||
|
this.progressBar = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
layout() {
|
||||||
|
|
||||||
|
if( this.isActive() ) {
|
||||||
|
this.syncPages();
|
||||||
|
this.syncScrollPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates our pages to match the latest configuration and
|
||||||
|
* presentation size.
|
||||||
|
*/
|
||||||
|
syncPages() {
|
||||||
|
|
||||||
|
const config = this.Reveal.getConfig();
|
||||||
|
|
||||||
|
const slideSize = this.Reveal.getComputedSlideSize( window.innerWidth, window.innerHeight );
|
||||||
|
const scale = this.Reveal.getScale();
|
||||||
|
const useCompactLayout = config.scrollLayout === 'compact';
|
||||||
|
|
||||||
|
const viewportHeight = this.viewportElement.offsetHeight;
|
||||||
|
const compactHeight = slideSize.height * scale;
|
||||||
|
const pageHeight = useCompactLayout ? compactHeight : viewportHeight;
|
||||||
|
|
||||||
|
// The height that needs to be scrolled between scroll triggers
|
||||||
|
const scrollTriggerHeight = useCompactLayout ? compactHeight : viewportHeight;
|
||||||
|
|
||||||
|
this.viewportElement.style.setProperty( '--page-height', pageHeight + 'px' );
|
||||||
|
this.viewportElement.style.scrollSnapType = typeof config.scrollSnap === 'string' ? `y ${config.scrollSnap}` : '';
|
||||||
|
|
||||||
|
// This will hold all scroll triggers used to show/hide slides
|
||||||
|
this.slideTriggers = [];
|
||||||
|
|
||||||
|
const pageElements = Array.from( this.Reveal.getRevealElement().querySelectorAll( '.scroll-page' ) );
|
||||||
|
|
||||||
|
this.pages = pageElements.map( pageElement => {
|
||||||
|
const page = this.createPage({
|
||||||
|
pageElement,
|
||||||
|
slideElement: pageElement.querySelector( 'section' ),
|
||||||
|
stickyElement: pageElement.querySelector( '.scroll-page-sticky' ),
|
||||||
|
contentElement: pageElement.querySelector( '.scroll-page-content' ),
|
||||||
|
backgroundElement: pageElement.querySelector( '.slide-background' ),
|
||||||
|
autoAnimateElements: pageElement.querySelectorAll( '.scroll-auto-animate-page' ),
|
||||||
|
autoAnimatePages: []
|
||||||
|
});
|
||||||
|
|
||||||
|
page.pageElement.style.setProperty( '--slide-height', config.center === true ? 'auto' : slideSize.height + 'px' );
|
||||||
|
|
||||||
|
this.slideTriggers.push({
|
||||||
|
page: page,
|
||||||
|
activate: () => this.activatePage( page ),
|
||||||
|
deactivate: () => this.deactivatePage( page )
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create scroll triggers that show/hide fragments
|
||||||
|
this.createFragmentTriggersForPage( page );
|
||||||
|
|
||||||
|
// Create scroll triggers for triggering auto-animate steps
|
||||||
|
if( page.autoAnimateElements.length > 0 ) {
|
||||||
|
this.createAutoAnimateTriggersForPage( page );
|
||||||
|
}
|
||||||
|
|
||||||
|
let totalScrollTriggerCount = Math.max( page.scrollTriggers.length - 1, 0 );
|
||||||
|
|
||||||
|
// Each auto-animate step may include its own scroll triggers
|
||||||
|
// for fragments, ensure we count those as well
|
||||||
|
totalScrollTriggerCount += page.autoAnimatePages.reduce( ( total, page ) => {
|
||||||
|
return total + Math.max( page.scrollTriggers.length - 1, 0 );
|
||||||
|
}, page.autoAnimatePages.length );
|
||||||
|
|
||||||
|
// Clean up from previous renders
|
||||||
|
page.pageElement.querySelectorAll( '.scroll-snap-point' ).forEach( el => el.remove() );
|
||||||
|
|
||||||
|
// Create snap points for all scroll triggers
|
||||||
|
// - Can't be absolute in FF
|
||||||
|
// - Can't be 0-height in Safari
|
||||||
|
// - Can't use snap-align on parent in Safari because then
|
||||||
|
// inner triggers won't work
|
||||||
|
for( let i = 0; i < totalScrollTriggerCount + 1; i++ ) {
|
||||||
|
const triggerStick = document.createElement( 'div' );
|
||||||
|
triggerStick.className = 'scroll-snap-point';
|
||||||
|
triggerStick.style.height = scrollTriggerHeight + 'px';
|
||||||
|
triggerStick.style.scrollSnapAlign = useCompactLayout ? 'center' : 'start';
|
||||||
|
page.pageElement.appendChild( triggerStick );
|
||||||
|
|
||||||
|
if( i === 0 ) {
|
||||||
|
triggerStick.style.marginTop = -scrollTriggerHeight + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the compact layout, only slides with scroll triggers cover the
|
||||||
|
// full viewport height. This helps avoid empty gaps before or after
|
||||||
|
// a sticky slide.
|
||||||
|
if( useCompactLayout && page.scrollTriggers.length > 0 ) {
|
||||||
|
page.pageHeight = viewportHeight;
|
||||||
|
page.pageElement.style.setProperty( '--page-height', viewportHeight + 'px' );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
page.pageHeight = pageHeight;
|
||||||
|
page.pageElement.style.removeProperty( '--page-height' );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add scroll padding based on how many scroll triggers we have
|
||||||
|
page.scrollPadding = scrollTriggerHeight * totalScrollTriggerCount;
|
||||||
|
|
||||||
|
// The total height including scrollable space
|
||||||
|
page.totalHeight = page.pageHeight + page.scrollPadding;
|
||||||
|
|
||||||
|
// This is used to pad the height of our page in CSS
|
||||||
|
page.pageElement.style.setProperty( '--page-scroll-padding', page.scrollPadding + 'px' );
|
||||||
|
|
||||||
|
// If this is a sticky page, stick it to the vertical center
|
||||||
|
if( totalScrollTriggerCount > 0 ) {
|
||||||
|
page.stickyElement.style.position = 'sticky';
|
||||||
|
page.stickyElement.style.top = Math.max( ( viewportHeight - page.pageHeight ) / 2, 0 ) + 'px';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
page.stickyElement.style.position = 'relative';
|
||||||
|
page.pageElement.style.scrollSnapAlign = page.pageHeight < viewportHeight ? 'center' : 'start';
|
||||||
|
}
|
||||||
|
|
||||||
|
return page;
|
||||||
|
} );
|
||||||
|
|
||||||
|
this.setTriggerRanges();
|
||||||
|
|
||||||
|
/*
|
||||||
|
console.log(this.slideTriggers.map( t => {
|
||||||
|
return {
|
||||||
|
range: `${t.range[0].toFixed(2)}-${t.range[1].toFixed(2)}`,
|
||||||
|
triggers: t.page.scrollTriggers.map( t => {
|
||||||
|
return `${t.range[0].toFixed(2)}-${t.range[1].toFixed(2)}`
|
||||||
|
}).join( ', ' ),
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
*/
|
||||||
|
|
||||||
|
this.viewportElement.setAttribute( 'data-scrollbar', config.scrollProgress );
|
||||||
|
|
||||||
|
if( config.scrollProgress && this.totalScrollTriggerCount > 1 ) {
|
||||||
|
// Create the progress bar if it doesn't already exist
|
||||||
|
if( !this.progressBar ) this.createProgressBar();
|
||||||
|
|
||||||
|
this.syncProgressBar();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.removeProgressBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates and sets the scroll range for all of our scroll
|
||||||
|
* triggers.
|
||||||
|
*/
|
||||||
|
setTriggerRanges() {
|
||||||
|
|
||||||
|
// Calculate the total number of scroll triggers
|
||||||
|
this.totalScrollTriggerCount = this.slideTriggers.reduce( ( total, trigger ) => {
|
||||||
|
return total + Math.max( trigger.page.scrollTriggers.length, 1 );
|
||||||
|
}, 0 );
|
||||||
|
|
||||||
|
let rangeStart = 0;
|
||||||
|
|
||||||
|
// Calculate the scroll range of each scroll trigger on a scale
|
||||||
|
// of 0-1
|
||||||
|
this.slideTriggers.forEach( ( trigger, i ) => {
|
||||||
|
trigger.range = [
|
||||||
|
rangeStart,
|
||||||
|
rangeStart + Math.max( trigger.page.scrollTriggers.length, 1 ) / this.totalScrollTriggerCount
|
||||||
|
];
|
||||||
|
|
||||||
|
const scrollTriggerSegmentSize = ( trigger.range[1] - trigger.range[0] ) / trigger.page.scrollTriggers.length;
|
||||||
|
|
||||||
|
// Set the range for each inner scroll trigger
|
||||||
|
trigger.page.scrollTriggers.forEach( ( scrollTrigger, i ) => {
|
||||||
|
scrollTrigger.range = [
|
||||||
|
rangeStart + i * scrollTriggerSegmentSize,
|
||||||
|
rangeStart + ( i + 1 ) * scrollTriggerSegmentSize
|
||||||
|
];
|
||||||
|
} );
|
||||||
|
|
||||||
|
rangeStart = trigger.range[1];
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates one scroll trigger for each fragments in the given page.
|
||||||
|
*
|
||||||
|
* @param {*} page
|
||||||
|
*/
|
||||||
|
createFragmentTriggersForPage( page, slideElement ) {
|
||||||
|
|
||||||
|
slideElement = slideElement || page.slideElement;
|
||||||
|
|
||||||
|
// Each fragment 'group' is an array containing one or more
|
||||||
|
// fragments. Multiple fragments that appear at the same time
|
||||||
|
// are part of the same group.
|
||||||
|
const fragmentGroups = this.Reveal.fragments.sort( slideElement.querySelectorAll( '.fragment' ), true );
|
||||||
|
|
||||||
|
// Create scroll triggers that show/hide fragments
|
||||||
|
if( fragmentGroups.length ) {
|
||||||
|
page.fragments = this.Reveal.fragments.sort( slideElement.querySelectorAll( '.fragment:not(.disabled)' ) );
|
||||||
|
page.scrollTriggers.push(
|
||||||
|
// Trigger for the initial state with no fragments visible
|
||||||
|
{
|
||||||
|
activate: () => {
|
||||||
|
this.Reveal.fragments.update( -1, page.fragments, slideElement );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Triggers for each fragment group
|
||||||
|
...fragmentGroups.map( ( fragments, i ) => ({
|
||||||
|
activate: () => {
|
||||||
|
this.Reveal.fragments.update( i, page.fragments, slideElement );
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return page.scrollTriggers.length;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates scroll triggers for the auto-animate steps in the
|
||||||
|
* given page.
|
||||||
|
*
|
||||||
|
* @param {*} page
|
||||||
|
*/
|
||||||
|
createAutoAnimateTriggersForPage( page ) {
|
||||||
|
|
||||||
|
if( page.autoAnimateElements.length > 0 ) {
|
||||||
|
|
||||||
|
// Triggers for each subsequent auto-animate slide
|
||||||
|
this.slideTriggers.push( ...Array.from( page.autoAnimateElements ).map( ( autoAnimateElement, i ) => {
|
||||||
|
let autoAnimatePage = this.createPage({
|
||||||
|
slideElement: autoAnimateElement.querySelector( 'section' ),
|
||||||
|
contentElement: autoAnimateElement,
|
||||||
|
backgroundElement: autoAnimateElement.querySelector( '.slide-background' )
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create fragment scroll triggers for the auto-animate slide
|
||||||
|
this.createFragmentTriggersForPage( autoAnimatePage, autoAnimatePage.slideElement );
|
||||||
|
|
||||||
|
page.autoAnimatePages.push( autoAnimatePage );
|
||||||
|
|
||||||
|
// Return our slide trigger
|
||||||
|
return {
|
||||||
|
page: autoAnimatePage,
|
||||||
|
activate: () => this.activatePage( autoAnimatePage ),
|
||||||
|
deactivate: () => this.deactivatePage( autoAnimatePage )
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for creating a page definition and adding
|
||||||
|
* required fields. A "page" is a slide or auto-animate step.
|
||||||
|
*/
|
||||||
|
createPage( page ) {
|
||||||
|
|
||||||
|
page.scrollTriggers = [];
|
||||||
|
page.indexh = parseInt( page.slideElement.getAttribute( 'data-index-h' ), 10 );
|
||||||
|
page.indexv = parseInt( page.slideElement.getAttribute( 'data-index-v' ), 10 );
|
||||||
|
|
||||||
|
return page;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rerenders progress bar segments so that they match the current
|
||||||
|
* reveal.js config and size.
|
||||||
|
*/
|
||||||
|
syncProgressBar() {
|
||||||
|
|
||||||
|
this.progressBarInner.querySelectorAll( '.scrollbar-slide' ).forEach( slide => slide.remove() );
|
||||||
|
|
||||||
|
const scrollHeight = this.viewportElement.scrollHeight;
|
||||||
|
const viewportHeight = this.viewportElement.offsetHeight;
|
||||||
|
const viewportHeightFactor = viewportHeight / scrollHeight;
|
||||||
|
|
||||||
|
this.progressBarHeight = this.progressBarInner.offsetHeight;
|
||||||
|
this.playheadHeight = Math.max( viewportHeightFactor * this.progressBarHeight, MIN_PLAYHEAD_HEIGHT );
|
||||||
|
this.progressBarScrollableHeight = this.progressBarHeight - this.playheadHeight;
|
||||||
|
|
||||||
|
const progressSegmentHeight = viewportHeight / scrollHeight * this.progressBarHeight;
|
||||||
|
const spacing = Math.min( progressSegmentHeight / 8, MAX_PROGRESS_SPACING );
|
||||||
|
|
||||||
|
this.progressBarPlayhead.style.height = this.playheadHeight - spacing + 'px';
|
||||||
|
|
||||||
|
// Don't show individual segments if they're too small
|
||||||
|
if( progressSegmentHeight > MIN_PROGRESS_SEGMENT_HEIGHT ) {
|
||||||
|
|
||||||
|
this.slideTriggers.forEach( slideTrigger => {
|
||||||
|
|
||||||
|
const { page } = slideTrigger;
|
||||||
|
|
||||||
|
// Visual representation of a slide
|
||||||
|
page.progressBarSlide = document.createElement( 'div' );
|
||||||
|
page.progressBarSlide.className = 'scrollbar-slide';
|
||||||
|
page.progressBarSlide.style.top = slideTrigger.range[0] * this.progressBarHeight + 'px';
|
||||||
|
page.progressBarSlide.style.height = ( slideTrigger.range[1] - slideTrigger.range[0] ) * this.progressBarHeight - spacing + 'px';
|
||||||
|
page.progressBarSlide.classList.toggle( 'has-triggers', page.scrollTriggers.length > 0 );
|
||||||
|
this.progressBarInner.appendChild( page.progressBarSlide );
|
||||||
|
|
||||||
|
// Visual representations of each scroll trigger
|
||||||
|
page.scrollTriggerElements = page.scrollTriggers.map( ( trigger, i ) => {
|
||||||
|
|
||||||
|
const triggerElement = document.createElement( 'div' );
|
||||||
|
triggerElement.className = 'scrollbar-trigger';
|
||||||
|
triggerElement.style.top = ( trigger.range[0] - slideTrigger.range[0] ) * this.progressBarHeight + 'px';
|
||||||
|
triggerElement.style.height = ( trigger.range[1] - trigger.range[0] ) * this.progressBarHeight - spacing + 'px';
|
||||||
|
page.progressBarSlide.appendChild( triggerElement );
|
||||||
|
|
||||||
|
if( i === 0 ) triggerElement.style.display = 'none';
|
||||||
|
|
||||||
|
return triggerElement;
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
this.pages.forEach( page => page.progressBarSlide = null );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the current scroll position and updates our active
|
||||||
|
* trigger states accordingly.
|
||||||
|
*/
|
||||||
|
syncScrollPosition() {
|
||||||
|
|
||||||
|
const viewportHeight = this.viewportElement.offsetHeight;
|
||||||
|
const viewportHeightFactor = viewportHeight / this.viewportElement.scrollHeight;
|
||||||
|
|
||||||
|
const scrollTop = this.viewportElement.scrollTop;
|
||||||
|
const scrollHeight = this.viewportElement.scrollHeight - viewportHeight
|
||||||
|
const scrollProgress = Math.max( Math.min( scrollTop / scrollHeight, 1 ), 0 );
|
||||||
|
const scrollProgressMid = Math.max( Math.min( ( scrollTop + viewportHeight / 2 ) / this.viewportElement.scrollHeight, 1 ), 0 );
|
||||||
|
|
||||||
|
let activePage;
|
||||||
|
|
||||||
|
this.slideTriggers.forEach( ( trigger ) => {
|
||||||
|
const { page } = trigger;
|
||||||
|
|
||||||
|
const shouldPreload = scrollProgress >= trigger.range[0] - viewportHeightFactor*2 &&
|
||||||
|
scrollProgress <= trigger.range[1] + viewportHeightFactor*2;
|
||||||
|
|
||||||
|
// Load slides that are within the preload range
|
||||||
|
if( shouldPreload && !page.loaded ) {
|
||||||
|
page.loaded = true;
|
||||||
|
this.Reveal.slideContent.load( page.slideElement );
|
||||||
|
}
|
||||||
|
else if( page.loaded ) {
|
||||||
|
page.loaded = false;
|
||||||
|
this.Reveal.slideContent.unload( page.slideElement );
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're within this trigger range, activate it
|
||||||
|
if( scrollProgress >= trigger.range[0] && scrollProgress <= trigger.range[1] ) {
|
||||||
|
this.activateTrigger( trigger );
|
||||||
|
activePage = trigger.page;
|
||||||
|
}
|
||||||
|
// .. otherwise deactivate
|
||||||
|
else if( trigger.active ) {
|
||||||
|
this.deactivateTrigger( trigger );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Each page can have its own scroll triggers, check if any of those
|
||||||
|
// need to be activated/deactivated
|
||||||
|
if( activePage ) {
|
||||||
|
activePage.scrollTriggers.forEach( ( trigger ) => {
|
||||||
|
if( scrollProgressMid >= trigger.range[0] && scrollProgressMid <= trigger.range[1] ) {
|
||||||
|
this.activateTrigger( trigger );
|
||||||
|
}
|
||||||
|
else if( trigger.active ) {
|
||||||
|
this.deactivateTrigger( trigger );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update our visual progress indication
|
||||||
|
this.setProgressBarValue( scrollTop / ( this.viewportElement.scrollHeight - viewportHeight ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the progress bar playhead to the specified position.
|
||||||
|
*
|
||||||
|
* @param {number} progress 0-1
|
||||||
|
*/
|
||||||
|
setProgressBarValue( progress ) {
|
||||||
|
|
||||||
|
if( this.progressBar ) {
|
||||||
|
|
||||||
|
this.progressBarPlayhead.style.transform = `translateY(${progress * this.progressBarScrollableHeight}px)`;
|
||||||
|
|
||||||
|
this.getAllPages()
|
||||||
|
.filter( page => page.progressBarSlide )
|
||||||
|
.forEach( ( page ) => {
|
||||||
|
page.progressBarSlide.classList.toggle( 'active', page.active === true );
|
||||||
|
|
||||||
|
page.scrollTriggers.forEach( ( trigger, i ) => {
|
||||||
|
page.scrollTriggerElements[i].classList.toggle( 'active', page.active === true && trigger.active === true );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
this.showProgressBar();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the progress bar and, if configured, automatically hide
|
||||||
|
* it after a delay.
|
||||||
|
*/
|
||||||
|
showProgressBar() {
|
||||||
|
|
||||||
|
this.progressBar.classList.add( 'visible' );
|
||||||
|
|
||||||
|
clearTimeout( this.hideProgressBarTimeout );
|
||||||
|
|
||||||
|
if( this.Reveal.getConfig().scrollProgress === 'auto' && !this.draggingProgressBar ) {
|
||||||
|
|
||||||
|
this.hideProgressBarTimeout = setTimeout( () => {
|
||||||
|
if( this.progressBar ) {
|
||||||
|
this.progressBar.classList.remove( 'visible' );
|
||||||
|
}
|
||||||
|
}, HIDE_SCROLLBAR_TIMEOUT );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrolls the given slide element into view.
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} slideElement
|
||||||
|
*/
|
||||||
|
scrollToSlide( slideElement ) {
|
||||||
|
|
||||||
|
// If the scroll view isn't active yet, queue this action
|
||||||
|
if( !this.active ) {
|
||||||
|
this.activatedCallbacks.push( () => this.scrollToSlide( slideElement ) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Find the trigger for this slide
|
||||||
|
const trigger = this.getScrollTriggerBySlide( slideElement );
|
||||||
|
|
||||||
|
if( trigger ) {
|
||||||
|
// Use the trigger's range to calculate the scroll position
|
||||||
|
this.viewportElement.scrollTop = trigger.range[0] * ( this.viewportElement.scrollHeight - this.viewportElement.offsetHeight );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persists the current scroll position to session storage
|
||||||
|
* so that it can be restored.
|
||||||
|
*/
|
||||||
|
storeScrollPosition() {
|
||||||
|
|
||||||
|
clearTimeout( this.storeScrollPositionTimeout );
|
||||||
|
|
||||||
|
this.storeScrollPositionTimeout = setTimeout( () => {
|
||||||
|
sessionStorage.setItem( 'reveal-scroll-top', this.viewportElement.scrollTop );
|
||||||
|
sessionStorage.setItem( 'reveal-scroll-origin', location.origin + location.pathname );
|
||||||
|
|
||||||
|
this.storeScrollPositionTimeout = null;
|
||||||
|
}, 50 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the scroll position when a deck is reloader.
|
||||||
|
*/
|
||||||
|
restoreScrollPosition() {
|
||||||
|
|
||||||
|
const scrollPosition = sessionStorage.getItem( 'reveal-scroll-top' );
|
||||||
|
const scrollOrigin = sessionStorage.getItem( 'reveal-scroll-origin' );
|
||||||
|
|
||||||
|
if( scrollPosition && scrollOrigin === location.origin + location.pathname ) {
|
||||||
|
this.viewportElement.scrollTop = parseInt( scrollPosition, 10 );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activates the given page and starts its embedded content
|
||||||
|
* if there is any.
|
||||||
|
*
|
||||||
|
* @param {object} page
|
||||||
|
*/
|
||||||
|
activatePage( page ) {
|
||||||
|
|
||||||
|
if( !page.active ) {
|
||||||
|
|
||||||
|
page.active = true;
|
||||||
|
|
||||||
|
const { slideElement, backgroundElement, contentElement, indexh, indexv } = page;
|
||||||
|
|
||||||
|
contentElement.style.display = 'block';
|
||||||
|
|
||||||
|
slideElement.classList.add( 'present' );
|
||||||
|
|
||||||
|
if( backgroundElement ) {
|
||||||
|
backgroundElement.classList.add( 'present' );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Reveal.setCurrentScrollPage( slideElement, indexh, indexv );
|
||||||
|
this.Reveal.backgrounds.bubbleSlideContrastClassToElement( slideElement, this.viewportElement );
|
||||||
|
|
||||||
|
// If this page is part of an auto-animation there will be one
|
||||||
|
// content element per auto-animated page. We need to show the
|
||||||
|
// current page and hide all others.
|
||||||
|
Array.from( contentElement.parentNode.querySelectorAll( '.scroll-page-content' ) ).forEach( sibling => {
|
||||||
|
if( sibling !== contentElement ) {
|
||||||
|
sibling.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivates the page after it has been visible.
|
||||||
|
*
|
||||||
|
* @param {object} page
|
||||||
|
*/
|
||||||
|
deactivatePage( page ) {
|
||||||
|
|
||||||
|
if( page.active ) {
|
||||||
|
|
||||||
|
page.active = false;
|
||||||
|
page.slideElement.classList.remove( 'present' );
|
||||||
|
page.backgroundElement.classList.remove( 'present' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
activateTrigger( trigger ) {
|
||||||
|
|
||||||
|
if( !trigger.active ) {
|
||||||
|
trigger.active = true;
|
||||||
|
trigger.activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
deactivateTrigger( trigger ) {
|
||||||
|
|
||||||
|
if( trigger.active ) {
|
||||||
|
trigger.active = false;
|
||||||
|
|
||||||
|
if( trigger.deactivate ) {
|
||||||
|
trigger.deactivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a slide by its original h/v index (i.e. the indices the
|
||||||
|
* slide had before being linearized).
|
||||||
|
*
|
||||||
|
* @param {number} h
|
||||||
|
* @param {number} v
|
||||||
|
* @returns {HTMLElement}
|
||||||
|
*/
|
||||||
|
getSlideByIndices( h, v ) {
|
||||||
|
|
||||||
|
const page = this.getAllPages().find( page => {
|
||||||
|
return page.indexh === h && page.indexv === v;
|
||||||
|
} );
|
||||||
|
|
||||||
|
return page ? page.slideElement : null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a list of all scroll triggers for the given slide
|
||||||
|
* DOM element.
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} slide
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
getScrollTriggerBySlide( slide ) {
|
||||||
|
|
||||||
|
return this.slideTriggers.find( trigger => trigger.page.slideElement === slide );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of all pages in the scroll view. This includes
|
||||||
|
* both top-level slides and auto-animate steps.
|
||||||
|
*
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
getAllPages() {
|
||||||
|
|
||||||
|
return this.pages.flatMap( page => [page, ...(page.autoAnimatePages || [])] );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onScroll() {
|
||||||
|
|
||||||
|
this.syncScrollPosition();
|
||||||
|
this.storeScrollPosition();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get viewportElement() {
|
||||||
|
|
||||||
|
return this.Reveal.getViewportElement();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { HORIZONTAL_SLIDES_SELECTOR, VERTICAL_SLIDES_SELECTOR } from '../utils/constants.js'
|
import { extend, queryAll, closest, getMimeTypeFromFile, encodeRFC3986URI } from '../utils/util.js'
|
||||||
import { extend, queryAll, closest } from '../utils/util.js'
|
|
||||||
import { isMobile } from '../utils/device.js'
|
import { isMobile } from '../utils/device.js'
|
||||||
|
|
||||||
import fitty from 'fitty';
|
import fitty from 'fitty';
|
||||||
@@ -26,6 +25,10 @@ export default class SlideContent {
|
|||||||
*/
|
*/
|
||||||
shouldPreload( element ) {
|
shouldPreload( element ) {
|
||||||
|
|
||||||
|
if( this.Reveal.isScrollView() ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Prefer an explicit global preload setting
|
// Prefer an explicit global preload setting
|
||||||
let preload = this.Reveal.getConfig().preloadIframes;
|
let preload = this.Reveal.getConfig().preloadIframes;
|
||||||
|
|
||||||
@@ -102,10 +105,19 @@ export default class SlideContent {
|
|||||||
|
|
||||||
// Images
|
// Images
|
||||||
if( backgroundImage ) {
|
if( backgroundImage ) {
|
||||||
|
// base64
|
||||||
|
if( /^data:/.test( backgroundImage.trim() ) ) {
|
||||||
|
backgroundContent.style.backgroundImage = `url(${backgroundImage.trim()})`;
|
||||||
|
}
|
||||||
|
// URL(s)
|
||||||
|
else {
|
||||||
backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {
|
backgroundContent.style.backgroundImage = backgroundImage.split( ',' ).map( background => {
|
||||||
return `url(${encodeURI(background.trim())})`;
|
// Decode URL(s) that are already encoded first
|
||||||
|
let decoded = decodeURI(background.trim());
|
||||||
|
return `url(${encodeRFC3986URI(decoded)})`;
|
||||||
}).join( ',' );
|
}).join( ',' );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Videos
|
// Videos
|
||||||
else if ( backgroundVideo && !this.Reveal.isSpeakerNotes() ) {
|
else if ( backgroundVideo && !this.Reveal.isSpeakerNotes() ) {
|
||||||
let video = document.createElement( 'video' );
|
let video = document.createElement( 'video' );
|
||||||
@@ -130,7 +142,13 @@ export default class SlideContent {
|
|||||||
|
|
||||||
// Support comma separated lists of video sources
|
// Support comma separated lists of video sources
|
||||||
backgroundVideo.split( ',' ).forEach( source => {
|
backgroundVideo.split( ',' ).forEach( source => {
|
||||||
video.innerHTML += '<source src="'+ source +'">';
|
let type = getMimeTypeFromFile( source );
|
||||||
|
if( type ) {
|
||||||
|
video.innerHTML += `<source src="${source}" type="${type}">`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
video.innerHTML += `<source src="${source}">`;
|
||||||
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
backgroundContent.appendChild( video );
|
backgroundContent.appendChild( video );
|
||||||
@@ -174,15 +192,14 @@ export default class SlideContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies JS-dependent layout helpers for the given slide,
|
* Applies JS-dependent layout helpers for the scope.
|
||||||
* if there are any.
|
|
||||||
*/
|
*/
|
||||||
layout( slide ) {
|
layout( scopeElement ) {
|
||||||
|
|
||||||
// Autosize text with the r-fit-text class based on the
|
// Autosize text with the r-fit-text class based on the
|
||||||
// size of its container. This needs to happen after the
|
// size of its container. This needs to happen after the
|
||||||
// slide is visible in order to measure the text.
|
// slide is visible in order to measure the text.
|
||||||
Array.from( slide.querySelectorAll( '.r-fit-text' ) ).forEach( element => {
|
Array.from( scopeElement.querySelectorAll( '.r-fit-text' ) ).forEach( element => {
|
||||||
fitty( element, {
|
fitty( element, {
|
||||||
minSize: 24,
|
minSize: 24,
|
||||||
maxSize: this.Reveal.getConfig().height * 0.8,
|
maxSize: this.Reveal.getConfig().height * 0.8,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export default class SlideNumber {
|
|||||||
configure( config, oldConfig ) {
|
configure( config, oldConfig ) {
|
||||||
|
|
||||||
let slideNumberDisplay = 'none';
|
let slideNumberDisplay = 'none';
|
||||||
if( config.slideNumber && !this.Reveal.isPrintingPDF() ) {
|
if( config.slideNumber && !this.Reveal.isPrintView() ) {
|
||||||
if( config.showSlideNumber === 'all' ) {
|
if( config.showSlideNumber === 'all' ) {
|
||||||
slideNumberDisplay = 'block';
|
slideNumberDisplay = 'block';
|
||||||
}
|
}
|
||||||
@@ -123,4 +123,10 @@ export default class SlideNumber {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
|
||||||
|
this.element.remove();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
639
js/reveal.js
639
js/reveal.js
File diff suppressed because it is too large
Load Diff
@@ -29,9 +29,9 @@ export const colorToRgb = ( color ) => {
|
|||||||
if( hex6 && hex6[1] ) {
|
if( hex6 && hex6[1] ) {
|
||||||
hex6 = hex6[1];
|
hex6 = hex6[1];
|
||||||
return {
|
return {
|
||||||
r: parseInt( hex6.substr( 0, 2 ), 16 ),
|
r: parseInt( hex6.slice( 0, 2 ), 16 ),
|
||||||
g: parseInt( hex6.substr( 2, 2 ), 16 ),
|
g: parseInt( hex6.slice( 2, 4 ), 16 ),
|
||||||
b: parseInt( hex6.substr( 4, 2 ), 16 )
|
b: parseInt( hex6.slice( 4, 6 ), 16 )
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export const HORIZONTAL_SLIDES_SELECTOR = '.slides>section';
|
|||||||
export const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';
|
export const VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section';
|
||||||
|
|
||||||
// Methods that may not be invoked via the postMessage API
|
// Methods that may not be invoked via the postMessage API
|
||||||
export const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener/;
|
export const POST_MESSAGE_METHOD_BLACKLIST = /registerPlugin|registerKeyboardShortcut|addKeyBinding|addEventListener|showPreview/;
|
||||||
|
|
||||||
// Regex for retrieving the fragment style from a class attribute
|
// Regex for retrieving the fragment style from a class attribute
|
||||||
export const FRAGMENT_STYLE_REGEX = /fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;
|
export const FRAGMENT_STYLE_REGEX = /fade-(down|up|right|left|out|in-then-out|in-then-semi-out)|semi-fade-out|current-visible|shrink|grow/;
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const UA = navigator.userAgent;
|
const UA = navigator.userAgent;
|
||||||
const testElement = document.createElement( 'div' );
|
|
||||||
|
|
||||||
export const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||
|
export const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||
|
||||||
( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS
|
( navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 ); // iPadOS
|
||||||
@@ -7,9 +6,3 @@ export const isMobile = /(iphone|ipod|ipad|android)/gi.test( UA ) ||
|
|||||||
export const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA );
|
export const isChrome = /chrome/i.test( UA ) && !/edge/i.test( UA );
|
||||||
|
|
||||||
export const isAndroid = /android/gi.test( UA );
|
export const isAndroid = /android/gi.test( UA );
|
||||||
|
|
||||||
// Flags if we should use zoom instead of transform to scale
|
|
||||||
// up slides. Zoom produces crisper results but has a lot of
|
|
||||||
// xbrowser quirks so we only use it in whitelisted browsers.
|
|
||||||
export const supportsZoom = 'zoom' in testElement.style && !isMobile &&
|
|
||||||
( isChrome || /Version\/[\d\.]+.*Safari/.test( UA ) );
|
|
||||||
@@ -280,3 +280,34 @@ export const getRemainingHeight = ( element, height = 0 ) => {
|
|||||||
return height;
|
return height;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fileExtensionToMimeMap = {
|
||||||
|
'mp4': 'video/mp4',
|
||||||
|
'm4a': 'video/mp4',
|
||||||
|
'ogv': 'video/ogg',
|
||||||
|
'mpeg': 'video/mpeg',
|
||||||
|
'webm': 'video/webm'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Guess the MIME type for common file formats.
|
||||||
|
*/
|
||||||
|
export const getMimeTypeFromFile = ( filename='' ) => {
|
||||||
|
return fileExtensionToMimeMap[filename.split('.').pop()]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes a string for RFC3986-compliant URL format.
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI#encoding_for_rfc3986
|
||||||
|
*
|
||||||
|
* @param {string} url
|
||||||
|
*/
|
||||||
|
export const encodeRFC3986URI = ( url='' ) => {
|
||||||
|
return encodeURI(url)
|
||||||
|
.replace(/%5B/g, "[")
|
||||||
|
.replace(/%5D/g, "]")
|
||||||
|
.replace(
|
||||||
|
/[!'()*]/g,
|
||||||
|
(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
|
||||||
|
);
|
||||||
|
}
|
||||||
14927
package-lock.json
generated
14927
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
52
package.json
52
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "reveal.js",
|
"name": "reveal.js",
|
||||||
"version": "4.1.3",
|
"version": "5.0.2",
|
||||||
"description": "The HTML Presentation Framework",
|
"description": "The HTML Presentation Framework",
|
||||||
"homepage": "https://revealjs.com",
|
"homepage": "https://revealjs.com",
|
||||||
"subdomain": "revealjs",
|
"subdomain": "revealjs",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"url": "git://github.com/hakimel/reveal.js.git"
|
"url": "git://github.com/hakimel/reveal.js.git"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=18.0.0"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"reveal",
|
"reveal",
|
||||||
@@ -30,35 +30,39 @@
|
|||||||
"presentation"
|
"presentation"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.14.3",
|
"@babel/core": "^7.23.2",
|
||||||
"@babel/eslint-parser": "^7.14.3",
|
"@babel/eslint-parser": "^7.22.15",
|
||||||
"@babel/preset-env": "^7.14.2",
|
"@babel/preset-env": "^7.23.2",
|
||||||
"@rollup/plugin-babel": "^5.3.0",
|
"@rollup/plugin-babel": "^6.0.4",
|
||||||
"@rollup/plugin-commonjs": "^19.0.0",
|
"@rollup/plugin-commonjs": "^25.0.7",
|
||||||
"@rollup/plugin-node-resolve": "^13.0.0",
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||||
"babel-plugin-transform-html-import-to-string": "0.0.1",
|
"@rollup/plugin-terser": "^0.4.4",
|
||||||
|
"babel-plugin-transform-html-import-to-string": "2.0.0",
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"core-js": "^3.12.1",
|
"core-js": "^3.33.1",
|
||||||
"fitty": "^2.3.0",
|
"fitty": "^2.3.7",
|
||||||
"glob": "^7.1.7",
|
"glob": "^10.3.10",
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
"gulp-autoprefixer": "^5.0.0",
|
"gulp-autoprefixer": "^8.0.0",
|
||||||
"gulp-clean-css": "^4.2.0",
|
"gulp-clean-css": "^4.3.0",
|
||||||
"gulp-connect": "^5.7.0",
|
"gulp-connect": "^5.7.0",
|
||||||
"gulp-eslint": "^6.0.0",
|
"gulp-eslint": "^6.0.0",
|
||||||
"gulp-header": "^2.0.9",
|
"gulp-header": "^2.0.9",
|
||||||
"gulp-tap": "^2.0.0",
|
"gulp-tap": "^2.0.0",
|
||||||
"gulp-zip": "^4.2.0",
|
"gulp-zip": "^5.1.0",
|
||||||
"highlight.js": "^10.0.3",
|
"highlight.js": "^11.9.0",
|
||||||
"marked": "^2.0.3",
|
"marked": "^4.3.0",
|
||||||
"node-qunit-puppeteer": "^2.0.1",
|
"node-qunit-puppeteer": "^2.1.2",
|
||||||
"qunit": "^2.10.0",
|
"qunit": "^2.20.0",
|
||||||
"rollup": "^2.48.0",
|
"rollup": "^4.1.5",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"sass": "^1.69.5",
|
||||||
"sass": "^1.32.13",
|
"yargs": "^17.7.2"
|
||||||
"yargs": "^15.1.0"
|
|
||||||
},
|
},
|
||||||
"browserslist": "> 0.5%, IE 11, not dead",
|
"overrides": {
|
||||||
|
"chokidar": "3.5.3",
|
||||||
|
"glob-parent": "6.0.2"
|
||||||
|
},
|
||||||
|
"browserslist": "> 2%, not dead",
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,8 +1,8 @@
|
|||||||
import hljs from 'highlight.js'
|
import hljs from 'highlight.js';
|
||||||
|
|
||||||
|
/* highlightjs-line-numbers.js 2.8.0 | (C) 2018 Yauheni Pakala | MIT License | github.com/wcoder/highlightjs-line-numbers.js */
|
||||||
|
!function(r,o){"use strict";var e,i="hljs-ln",l="hljs-ln-line",h="hljs-ln-code",s="hljs-ln-numbers",c="hljs-ln-n",m="data-line-number",a=/\r\n|\r|\n/g;function u(e){for(var n=e.toString(),t=e.anchorNode;"TD"!==t.nodeName;)t=t.parentNode;for(var r=e.focusNode;"TD"!==r.nodeName;)r=r.parentNode;var o=parseInt(t.dataset.lineNumber),a=parseInt(r.dataset.lineNumber);if(o==a)return n;var i,l=t.textContent,s=r.textContent;for(a<o&&(i=o,o=a,a=i,i=l,l=s,s=i);0!==n.indexOf(l);)l=l.slice(1);for(;-1===n.lastIndexOf(s);)s=s.slice(0,-1);for(var c=l,u=function(e){for(var n=e;"TABLE"!==n.nodeName;)n=n.parentNode;return n}(t),d=o+1;d<a;++d){var f=p('.{0}[{1}="{2}"]',[h,m,d]);c+="\n"+u.querySelector(f).textContent}return c+="\n"+s}function n(e){try{var n=o.querySelectorAll("code.hljs,code.nohighlight");for(var t in n)n.hasOwnProperty(t)&&(n[t].classList.contains("nohljsln")||d(n[t],e))}catch(e){r.console.error("LineNumbers error: ",e)}}function d(e,n){if("object"==typeof e)e.innerHTML=f(e,n)}function f(e,n){var t,r,o=(t=e,{singleLine:function(e){return!!e.singleLine&&e.singleLine}(r=(r=n)||{}),startFrom:function(e,n){var t=1;isFinite(n.startFrom)&&(t=n.startFrom);var r=function(e,n){return e.hasAttribute(n)?e.getAttribute(n):null}(e,"data-ln-start-from");return null!==r&&(t=function(e,n){if(!e)return n;var t=Number(e);return isFinite(t)?t:n}(r,1)),t}(t,r)});return function e(n){var t=n.childNodes;for(var r in t){var o;t.hasOwnProperty(r)&&(o=t[r],0<(o.textContent.trim().match(a)||[]).length&&(0<o.childNodes.length?e(o):v(o.parentNode)))}}(e),function(e,n){var t=g(e);""===t[t.length-1].trim()&&t.pop();if(1<t.length||n.singleLine){for(var r="",o=0,a=t.length;o<a;o++)r+=p('<tr><td class="{0} {1}" {3}="{5}"><div class="{2}" {3}="{5}"></div></td><td class="{0} {4}" {3}="{5}">{6}</td></tr>',[l,s,c,m,h,o+n.startFrom,0<t[o].length?t[o]:" "]);return p('<table class="{0}">{1}</table>',[i,r])}return e}(e.innerHTML,o)}function v(e){var n=e.className;if(/hljs-/.test(n)){for(var t=g(e.innerHTML),r=0,o="";r<t.length;r++){o+=p('<span class="{0}">{1}</span>\n',[n,0<t[r].length?t[r]:" "])}e.innerHTML=o.trim()}}function g(e){return 0===e.length?[]:e.split(a)}function p(e,t){return e.replace(/\{(\d+)\}/g,function(e,n){return void 0!==t[n]?t[n]:e})}hljs?(hljs.initLineNumbersOnLoad=function(e){"interactive"===o.readyState||"complete"===o.readyState?n(e):r.addEventListener("DOMContentLoaded",function(){n(e)})},hljs.lineNumbersBlock=d,hljs.lineNumbersValue=function(e,n){if("string"!=typeof e)return;var t=document.createElement("code");return t.innerHTML=e,f(t,n)},(e=o.createElement("style")).type="text/css",e.innerHTML=p(".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}",[i,c,m]),o.getElementsByTagName("head")[0].appendChild(e)):r.console.error("highlight.js not detected!"),document.addEventListener("copy",function(e){var n,t=window.getSelection();!function(e){for(var n=e;n;){if(n.className&&-1!==n.className.indexOf("hljs-ln-code"))return 1;n=n.parentNode}}(t.anchorNode)||(n=-1!==window.navigator.userAgent.indexOf("Edge")?u(t):t.toString(),e.clipboardData.setData("text/plain",n),e.preventDefault())})}(window,document);
|
||||||
|
|
||||||
/* highlightjs-line-numbers.js 2.6.0 | (C) 2018 Yauheni Pakala | MIT License | github.com/wcoder/highlightjs-line-numbers.js */
|
|
||||||
/* Edited by Hakim for reveal.js; removed async timeout */
|
|
||||||
!function(n,e){"use strict";function t(){var n=e.createElement("style");n.type="text/css",n.innerHTML=g(".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}",[v,L,b]),e.getElementsByTagName("head")[0].appendChild(n)}function r(t){"interactive"===e.readyState||"complete"===e.readyState?i(t):n.addEventListener("DOMContentLoaded",function(){i(t)})}function i(t){try{var r=e.querySelectorAll("code.hljs,code.nohighlight");for(var i in r)r.hasOwnProperty(i)&&l(r[i],t)}catch(o){n.console.error("LineNumbers error: ",o)}}function l(n,e){"object"==typeof n&&f(function(){n.innerHTML=s(n,e)})}function o(n,e){if("string"==typeof n){var t=document.createElement("code");return t.innerHTML=n,s(t,e)}}function s(n,e){e=e||{singleLine:!1};var t=e.singleLine?0:1;return c(n),a(n.innerHTML,t)}function a(n,e){var t=u(n);if(""===t[t.length-1].trim()&&t.pop(),t.length>e){for(var r="",i=0,l=t.length;i<l;i++)r+=g('<tr><td class="{0}"><div class="{1} {2}" {3}="{5}"></div></td><td class="{4}"><div class="{1}">{6}</div></td></tr>',[j,m,L,b,p,i+1,t[i].length>0?t[i]:" "]);return g('<table class="{0}">{1}</table>',[v,r])}return n}function c(n){var e=n.childNodes;for(var t in e)if(e.hasOwnProperty(t)){var r=e[t];h(r.textContent)>0&&(r.childNodes.length>0?c(r):d(r.parentNode))}}function d(n){var e=n.className;if(/hljs-/.test(e)){for(var t=u(n.innerHTML),r=0,i="";r<t.length;r++){var l=t[r].length>0?t[r]:" ";i+=g('<span class="{0}">{1}</span>\n',[e,l])}n.innerHTML=i.trim()}}function u(n){return 0===n.length?[]:n.split(y)}function h(n){return(n.trim().match(y)||[]).length}function f(e){e()}function g(n,e){return n.replace(/\{(\d+)\}/g,function(n,t){return e[t]?e[t]:n})}var v="hljs-ln",m="hljs-ln-line",p="hljs-ln-code",j="hljs-ln-numbers",L="hljs-ln-n",b="data-line-number",y=/\r\n|\r|\n/g;hljs?(hljs.initLineNumbersOnLoad=r,hljs.lineNumbersBlock=l,hljs.lineNumbersValue=o,t()):n.console.error("highlight.js not detected!")}(window,document);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* reveal.js plugin that adds syntax highlight support.
|
* reveal.js plugin that adds syntax highlight support.
|
||||||
@@ -16,10 +16,10 @@ const Plugin = {
|
|||||||
HIGHLIGHT_LINE_DELIMITER: ',',
|
HIGHLIGHT_LINE_DELIMITER: ',',
|
||||||
HIGHLIGHT_LINE_RANGE_DELIMITER: '-',
|
HIGHLIGHT_LINE_RANGE_DELIMITER: '-',
|
||||||
|
|
||||||
hljs: hljs,
|
hljs,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Highlights code blocks withing the given deck.
|
* Highlights code blocks within the given deck.
|
||||||
*
|
*
|
||||||
* Note that this can be called multiple times if
|
* Note that this can be called multiple times if
|
||||||
* there are multiple presentations on one page.
|
* there are multiple presentations on one page.
|
||||||
@@ -30,6 +30,7 @@ const Plugin = {
|
|||||||
|
|
||||||
// Read the plugin config options and provide fallbacks
|
// Read the plugin config options and provide fallbacks
|
||||||
let config = reveal.getConfig().highlight || {};
|
let config = reveal.getConfig().highlight || {};
|
||||||
|
|
||||||
config.highlightOnLoad = typeof config.highlightOnLoad === 'boolean' ? config.highlightOnLoad : true;
|
config.highlightOnLoad = typeof config.highlightOnLoad === 'boolean' ? config.highlightOnLoad : true;
|
||||||
config.escapeHTML = typeof config.escapeHTML === 'boolean' ? config.escapeHTML : true;
|
config.escapeHTML = typeof config.escapeHTML === 'boolean' ? config.escapeHTML : true;
|
||||||
|
|
||||||
@@ -61,11 +62,19 @@ const Plugin = {
|
|||||||
hljs.highlightElement( event.currentTarget );
|
hljs.highlightElement( event.currentTarget );
|
||||||
}, false );
|
}, false );
|
||||||
|
|
||||||
if( config.highlightOnLoad ) {
|
} );
|
||||||
Plugin.highlightBlock( block );
|
|
||||||
|
// Triggers a callback function before we trigger highlighting
|
||||||
|
if( typeof config.beforeHighlight === 'function' ) {
|
||||||
|
config.beforeHighlight( hljs );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run initial highlighting for all code
|
||||||
|
if( config.highlightOnLoad ) {
|
||||||
|
Array.from( reveal.getRevealElement().querySelectorAll( 'pre code' ) ).forEach( block => {
|
||||||
|
Plugin.highlightBlock( block );
|
||||||
} );
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
// If we're printing to PDF, scroll the code highlights of
|
// If we're printing to PDF, scroll the code highlights of
|
||||||
// all blocks in the deck into view at once
|
// all blocks in the deck into view at once
|
||||||
@@ -97,7 +106,7 @@ const Plugin = {
|
|||||||
|
|
||||||
var scrollState = { currentBlock: block };
|
var scrollState = { currentBlock: block };
|
||||||
|
|
||||||
// If there is at least one highlight step, generate
|
// If there is more than one highlight step, generate
|
||||||
// fragments
|
// fragments
|
||||||
var highlightSteps = Plugin.deserializeHighlightSteps( block.getAttribute( 'data-line-numbers' ) );
|
var highlightSteps = Plugin.deserializeHighlightSteps( block.getAttribute( 'data-line-numbers' ) );
|
||||||
if( highlightSteps.length > 1 ) {
|
if( highlightSteps.length > 1 ) {
|
||||||
@@ -133,7 +142,7 @@ const Plugin = {
|
|||||||
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
block.removeAttribute( 'data-fragment-index' )
|
block.removeAttribute( 'data-fragment-index' );
|
||||||
block.setAttribute( 'data-line-numbers', Plugin.serializeHighlightSteps( [ highlightSteps[0] ] ) );
|
block.setAttribute( 'data-line-numbers', Plugin.serializeHighlightSteps( [ highlightSteps[0] ] ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -4,16 +4,19 @@
|
|||||||
* of external markdown documents.
|
* of external markdown documents.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import marked from 'marked'
|
import { marked } from 'marked';
|
||||||
|
|
||||||
const DEFAULT_SLIDE_SEPARATOR = '\r?\n---\r?\n',
|
const DEFAULT_SLIDE_SEPARATOR = '\r?\n---\r?\n',
|
||||||
DEFAULT_NOTES_SEPARATOR = 'notes?:',
|
DEFAULT_VERTICAL_SEPARATOR = null,
|
||||||
|
DEFAULT_NOTES_SEPARATOR = '^\s*notes?:',
|
||||||
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
|
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
|
||||||
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
|
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
|
||||||
|
|
||||||
const SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__';
|
const SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__';
|
||||||
|
|
||||||
const CODE_LINE_NUMBER_REGEX = /\[([\s\d,|-]*)\]/;
|
// match an optional line number offset and highlight line numbers
|
||||||
|
// [<line numbers>] or [<offset>: <line numbers>]
|
||||||
|
const CODE_LINE_NUMBER_REGEX = /\[\s*((\d*):)?\s*([\s\d,|-]*)\]/;
|
||||||
|
|
||||||
const HTML_ESCAPE_MAP = {
|
const HTML_ESCAPE_MAP = {
|
||||||
'&': '&',
|
'&': '&',
|
||||||
@@ -35,22 +38,22 @@ const Plugin = () => {
|
|||||||
function getMarkdownFromSlide( section ) {
|
function getMarkdownFromSlide( section ) {
|
||||||
|
|
||||||
// look for a <script> or <textarea data-template> wrapper
|
// look for a <script> or <textarea data-template> wrapper
|
||||||
var template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' );
|
const template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' );
|
||||||
|
|
||||||
// strip leading whitespace so it isn't evaluated as code
|
// strip leading whitespace so it isn't evaluated as code
|
||||||
var text = ( template || section ).textContent;
|
let text = ( template || section ).textContent;
|
||||||
|
|
||||||
// restore script end tags
|
// restore script end tags
|
||||||
text = text.replace( new RegExp( SCRIPT_END_PLACEHOLDER, 'g' ), '</script>' );
|
text = text.replace( new RegExp( SCRIPT_END_PLACEHOLDER, 'g' ), '</script>' );
|
||||||
|
|
||||||
var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
|
const leadingWs = text.match( /^\n?(\s*)/ )[1].length,
|
||||||
leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
|
leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
|
||||||
|
|
||||||
if( leadingTabs > 0 ) {
|
if( leadingTabs > 0 ) {
|
||||||
text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
|
text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}(.*)','g'), function(m, p1) { return '\n' + p1 ; } );
|
||||||
}
|
}
|
||||||
else if( leadingWs > 1 ) {
|
else if( leadingWs > 1 ) {
|
||||||
text = text.replace( new RegExp('\\n? {' + leadingWs + '}', 'g'), '\n' );
|
text = text.replace( new RegExp('\\n? {' + leadingWs + '}(.*)', 'g'), function(m, p1) { return '\n' + p1 ; } );
|
||||||
}
|
}
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
@@ -65,11 +68,11 @@ const Plugin = () => {
|
|||||||
*/
|
*/
|
||||||
function getForwardedAttributes( section ) {
|
function getForwardedAttributes( section ) {
|
||||||
|
|
||||||
var attributes = section.attributes;
|
const attributes = section.attributes;
|
||||||
var result = [];
|
const result = [];
|
||||||
|
|
||||||
for( var i = 0, len = attributes.length; i < len; i++ ) {
|
for( let i = 0, len = attributes.length; i < len; i++ ) {
|
||||||
var name = attributes[i].name,
|
const name = attributes[i].name,
|
||||||
value = attributes[i].value;
|
value = attributes[i].value;
|
||||||
|
|
||||||
// disregard attributes that are used for markdown loading/parsing
|
// disregard attributes that are used for markdown loading/parsing
|
||||||
@@ -92,10 +95,12 @@ const Plugin = () => {
|
|||||||
* values for what's not defined.
|
* values for what's not defined.
|
||||||
*/
|
*/
|
||||||
function getSlidifyOptions( options ) {
|
function getSlidifyOptions( options ) {
|
||||||
|
const markdownConfig = deck?.getConfig?.().markdown;
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
|
options.separator = options.separator || markdownConfig?.separator || DEFAULT_SLIDE_SEPARATOR;
|
||||||
options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
|
options.verticalSeparator = options.verticalSeparator || markdownConfig?.verticalSeparator || DEFAULT_VERTICAL_SEPARATOR;
|
||||||
|
options.notesSeparator = options.notesSeparator || markdownConfig?.notesSeparator || DEFAULT_NOTES_SEPARATOR;
|
||||||
options.attributes = options.attributes || '';
|
options.attributes = options.attributes || '';
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
@@ -109,7 +114,7 @@ const Plugin = () => {
|
|||||||
|
|
||||||
options = getSlidifyOptions( options );
|
options = getSlidifyOptions( options );
|
||||||
|
|
||||||
var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
|
const notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
|
||||||
|
|
||||||
if( notesMatch.length === 2 ) {
|
if( notesMatch.length === 2 ) {
|
||||||
content = notesMatch[0] + '<aside class="notes">' + marked(notesMatch[1].trim()) + '</aside>';
|
content = notesMatch[0] + '<aside class="notes">' + marked(notesMatch[1].trim()) + '</aside>';
|
||||||
@@ -131,10 +136,10 @@ const Plugin = () => {
|
|||||||
|
|
||||||
options = getSlidifyOptions( options );
|
options = getSlidifyOptions( options );
|
||||||
|
|
||||||
var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
|
const separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
|
||||||
horizontalSeparatorRegex = new RegExp( options.separator );
|
horizontalSeparatorRegex = new RegExp( options.separator );
|
||||||
|
|
||||||
var matches,
|
let matches,
|
||||||
lastIndex = 0,
|
lastIndex = 0,
|
||||||
isHorizontal,
|
isHorizontal,
|
||||||
wasHorizontal = true,
|
wasHorizontal = true,
|
||||||
@@ -143,7 +148,7 @@ const Plugin = () => {
|
|||||||
|
|
||||||
// iterate until all blocks between separators are stacked up
|
// iterate until all blocks between separators are stacked up
|
||||||
while( matches = separatorRegex.exec( markdown ) ) {
|
while( matches = separatorRegex.exec( markdown ) ) {
|
||||||
var notes = null;
|
const notes = null;
|
||||||
|
|
||||||
// determine direction (horizontal by default)
|
// determine direction (horizontal by default)
|
||||||
isHorizontal = horizontalSeparatorRegex.test( matches[0] );
|
isHorizontal = horizontalSeparatorRegex.test( matches[0] );
|
||||||
@@ -172,10 +177,10 @@ const Plugin = () => {
|
|||||||
// add the remaining slide
|
// add the remaining slide
|
||||||
( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
|
( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
|
||||||
|
|
||||||
var markdownSections = '';
|
let markdownSections = '';
|
||||||
|
|
||||||
// flatten the hierarchical stack, and insert <section data-markdown> tags
|
// flatten the hierarchical stack, and insert <section data-markdown> tags
|
||||||
for( var i = 0, len = sectionStack.length; i < len; i++ ) {
|
for( let i = 0, len = sectionStack.length; i < len; i++ ) {
|
||||||
// vertical
|
// vertical
|
||||||
if( sectionStack[i] instanceof Array ) {
|
if( sectionStack[i] instanceof Array ) {
|
||||||
markdownSections += '<section '+ options.attributes +'>';
|
markdownSections += '<section '+ options.attributes +'>';
|
||||||
@@ -204,7 +209,7 @@ const Plugin = () => {
|
|||||||
|
|
||||||
return new Promise( function( resolve ) {
|
return new Promise( function( resolve ) {
|
||||||
|
|
||||||
var externalPromises = [];
|
const externalPromises = [];
|
||||||
|
|
||||||
[].slice.call( scope.querySelectorAll( 'section[data-markdown]:not([data-markdown-parsed])') ).forEach( function( section, i ) {
|
[].slice.call( scope.querySelectorAll( 'section[data-markdown]:not([data-markdown-parsed])') ).forEach( function( section, i ) {
|
||||||
|
|
||||||
@@ -257,13 +262,13 @@ const Plugin = () => {
|
|||||||
|
|
||||||
return new Promise( function( resolve, reject ) {
|
return new Promise( function( resolve, reject ) {
|
||||||
|
|
||||||
var xhr = new XMLHttpRequest(),
|
const xhr = new XMLHttpRequest(),
|
||||||
url = section.getAttribute( 'data-markdown' );
|
url = section.getAttribute( 'data-markdown' );
|
||||||
|
|
||||||
var datacharset = section.getAttribute( 'data-charset' );
|
const datacharset = section.getAttribute( 'data-charset' );
|
||||||
|
|
||||||
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
|
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
|
||||||
if( datacharset != null && datacharset != '' ) {
|
if( datacharset !== null && datacharset !== '' ) {
|
||||||
xhr.overrideMimeType( 'text/html; charset=' + datacharset );
|
xhr.overrideMimeType( 'text/html; charset=' + datacharset );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,17 +313,17 @@ const Plugin = () => {
|
|||||||
*/
|
*/
|
||||||
function addAttributeInElement( node, elementTarget, separator ) {
|
function addAttributeInElement( node, elementTarget, separator ) {
|
||||||
|
|
||||||
var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
|
const markdownClassesInElementsRegex = new RegExp( separator, 'mg' );
|
||||||
var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"]+?)\"|(data-[^\"= ]+?)(?=[\" ])", 'mg' );
|
const markdownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"]+?)\"|(data-[^\"= ]+?)(?=[\" ])", 'mg' );
|
||||||
var nodeValue = node.nodeValue;
|
let nodeValue = node.nodeValue;
|
||||||
var matches,
|
let matches,
|
||||||
matchesClass;
|
matchesClass;
|
||||||
if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
|
if( matches = markdownClassesInElementsRegex.exec( nodeValue ) ) {
|
||||||
|
|
||||||
var classes = matches[1];
|
const classes = matches[1];
|
||||||
nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
|
nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( markdownClassesInElementsRegex.lastIndex );
|
||||||
node.nodeValue = nodeValue;
|
node.nodeValue = nodeValue;
|
||||||
while( matchesClass = mardownClassRegex.exec( classes ) ) {
|
while( matchesClass = markdownClassRegex.exec( classes ) ) {
|
||||||
if( matchesClass[2] ) {
|
if( matchesClass[2] ) {
|
||||||
elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
|
elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
|
||||||
} else {
|
} else {
|
||||||
@@ -336,34 +341,34 @@ const Plugin = () => {
|
|||||||
*/
|
*/
|
||||||
function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
|
function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
|
||||||
|
|
||||||
if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
|
if ( element !== null && element.childNodes !== undefined && element.childNodes.length > 0 ) {
|
||||||
var previousParentElement = element;
|
let previousParentElement = element;
|
||||||
for( var i = 0; i < element.childNodes.length; i++ ) {
|
for( let i = 0; i < element.childNodes.length; i++ ) {
|
||||||
var childElement = element.childNodes[i];
|
const childElement = element.childNodes[i];
|
||||||
if ( i > 0 ) {
|
if ( i > 0 ) {
|
||||||
var j = i - 1;
|
let j = i - 1;
|
||||||
while ( j >= 0 ) {
|
while ( j >= 0 ) {
|
||||||
var aPreviousChildElement = element.childNodes[j];
|
const aPreviousChildElement = element.childNodes[j];
|
||||||
if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
|
if ( typeof aPreviousChildElement.setAttribute === 'function' && aPreviousChildElement.tagName !== "BR" ) {
|
||||||
previousParentElement = aPreviousChildElement;
|
previousParentElement = aPreviousChildElement;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
j = j - 1;
|
j = j - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var parentSection = section;
|
let parentSection = section;
|
||||||
if( childElement.nodeName == "section" ) {
|
if( childElement.nodeName === "section" ) {
|
||||||
parentSection = childElement ;
|
parentSection = childElement ;
|
||||||
previousParentElement = childElement ;
|
previousParentElement = childElement ;
|
||||||
}
|
}
|
||||||
if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
|
if ( typeof childElement.setAttribute === 'function' || childElement.nodeType === Node.COMMENT_NODE ) {
|
||||||
addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
|
addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( element.nodeType == Node.COMMENT_NODE ) {
|
if ( element.nodeType === Node.COMMENT_NODE ) {
|
||||||
if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
|
if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) === false ) {
|
||||||
addAttributeInElement( element, section, separatorSectionAttributes );
|
addAttributeInElement( element, section, separatorSectionAttributes );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -375,14 +380,14 @@ const Plugin = () => {
|
|||||||
*/
|
*/
|
||||||
function convertSlides() {
|
function convertSlides() {
|
||||||
|
|
||||||
var sections = deck.getRevealElement().querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
|
const sections = deck.getRevealElement().querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
|
||||||
|
|
||||||
[].slice.call( sections ).forEach( function( section ) {
|
[].slice.call( sections ).forEach( function( section ) {
|
||||||
|
|
||||||
section.setAttribute( 'data-markdown-parsed', true )
|
section.setAttribute( 'data-markdown-parsed', true )
|
||||||
|
|
||||||
var notes = section.querySelector( 'aside.notes' );
|
const notes = section.querySelector( 'aside.notes' );
|
||||||
var markdown = getMarkdownFromSlide( section );
|
const markdown = getMarkdownFromSlide( section );
|
||||||
|
|
||||||
section.innerHTML = marked( markdown );
|
section.innerHTML = marked( markdown );
|
||||||
addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
|
addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
|
||||||
@@ -429,14 +434,23 @@ const Plugin = () => {
|
|||||||
renderer.code = ( code, language ) => {
|
renderer.code = ( code, language ) => {
|
||||||
|
|
||||||
// Off by default
|
// Off by default
|
||||||
|
let lineNumberOffset = '';
|
||||||
let lineNumbers = '';
|
let lineNumbers = '';
|
||||||
|
|
||||||
// Users can opt in to show line numbers and highlight
|
// Users can opt in to show line numbers and highlight
|
||||||
// specific lines.
|
// specific lines.
|
||||||
// ```javascript [] show line numbers
|
// ```javascript [] show line numbers
|
||||||
// ```javascript [1,4-8] highlights lines 1 and 4-8
|
// ```javascript [1,4-8] highlights lines 1 and 4-8
|
||||||
|
// optional line number offset:
|
||||||
|
// ```javascript [25: 1,4-8] start line numbering at 25,
|
||||||
|
// highlights lines 1 (numbered as 25) and 4-8 (numbered as 28-32)
|
||||||
if( CODE_LINE_NUMBER_REGEX.test( language ) ) {
|
if( CODE_LINE_NUMBER_REGEX.test( language ) ) {
|
||||||
lineNumbers = language.match( CODE_LINE_NUMBER_REGEX )[1].trim();
|
let lineNumberOffsetMatch = language.match( CODE_LINE_NUMBER_REGEX )[2];
|
||||||
|
if (lineNumberOffsetMatch){
|
||||||
|
lineNumberOffset = `data-ln-start-from="${lineNumberOffsetMatch.trim()}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
lineNumbers = language.match( CODE_LINE_NUMBER_REGEX )[3].trim();
|
||||||
lineNumbers = `data-line-numbers="${lineNumbers}"`;
|
lineNumbers = `data-line-numbers="${lineNumbers}"`;
|
||||||
language = language.replace( CODE_LINE_NUMBER_REGEX, '' ).trim();
|
language = language.replace( CODE_LINE_NUMBER_REGEX, '' ).trim();
|
||||||
}
|
}
|
||||||
@@ -446,7 +460,9 @@ const Plugin = () => {
|
|||||||
// highlight.js is able to read it
|
// highlight.js is able to read it
|
||||||
code = escapeForHTML( code );
|
code = escapeForHTML( code );
|
||||||
|
|
||||||
return `<pre><code ${lineNumbers} class="${language}">${code}</code></pre>`;
|
// return `<pre><code ${lineNumbers} class="${language}">${code}</code></pre>`;
|
||||||
|
|
||||||
|
return `<pre><code ${lineNumbers} ${lineNumberOffset} class="${language}">${code}</code></pre>`;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
96
plugin/math/katex.js
Executable file
96
plugin/math/katex.js
Executable file
@@ -0,0 +1,96 @@
|
|||||||
|
/**
|
||||||
|
* A plugin which enables rendering of math equations inside
|
||||||
|
* of reveal.js slides. Essentially a thin wrapper for KaTeX.
|
||||||
|
*
|
||||||
|
* @author Hakim El Hattab
|
||||||
|
* @author Gerhard Burger
|
||||||
|
*/
|
||||||
|
export const KaTeX = () => {
|
||||||
|
let deck;
|
||||||
|
|
||||||
|
let defaultOptions = {
|
||||||
|
version: 'latest',
|
||||||
|
delimiters: [
|
||||||
|
{left: '$$', right: '$$', display: true}, // Note: $$ has to come before $
|
||||||
|
{left: '$', right: '$', display: false},
|
||||||
|
{left: '\\(', right: '\\)', display: false},
|
||||||
|
{left: '\\[', right: '\\]', display: true}
|
||||||
|
],
|
||||||
|
ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre']
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadCss = src => {
|
||||||
|
let link = document.createElement('link');
|
||||||
|
link.rel = 'stylesheet';
|
||||||
|
link.href = src;
|
||||||
|
document.head.appendChild(link);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a JavaScript file and returns a Promise for when it is loaded
|
||||||
|
* Credits: https://aaronsmith.online/easily-load-an-external-script-using-javascript/
|
||||||
|
*/
|
||||||
|
const loadScript = src => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const script = document.createElement('script')
|
||||||
|
script.type = 'text/javascript'
|
||||||
|
script.onload = resolve
|
||||||
|
script.onerror = reject
|
||||||
|
script.src = src
|
||||||
|
document.head.append(script)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
async function loadScripts(urls) {
|
||||||
|
for(const url of urls) {
|
||||||
|
await loadScript(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: 'katex',
|
||||||
|
|
||||||
|
init: function (reveal) {
|
||||||
|
|
||||||
|
deck = reveal;
|
||||||
|
|
||||||
|
let revealOptions = deck.getConfig().katex || {};
|
||||||
|
|
||||||
|
let options = {...defaultOptions, ...revealOptions};
|
||||||
|
const {local, version, extensions, ...katexOptions} = options;
|
||||||
|
|
||||||
|
let baseUrl = options.local || 'https://cdn.jsdelivr.net/npm/katex';
|
||||||
|
let versionString = options.local ? '' : '@' + options.version;
|
||||||
|
|
||||||
|
let cssUrl = baseUrl + versionString + '/dist/katex.min.css';
|
||||||
|
let katexUrl = baseUrl + versionString + '/dist/katex.min.js';
|
||||||
|
let mhchemUrl = baseUrl + versionString + '/dist/contrib/mhchem.min.js'
|
||||||
|
let karUrl = baseUrl + versionString + '/dist/contrib/auto-render.min.js';
|
||||||
|
|
||||||
|
let katexScripts = [katexUrl];
|
||||||
|
if(options.extensions && options.extensions.includes("mhchem")) {
|
||||||
|
katexScripts.push(mhchemUrl);
|
||||||
|
}
|
||||||
|
katexScripts.push(karUrl);
|
||||||
|
|
||||||
|
const renderMath = () => {
|
||||||
|
renderMathInElement(reveal.getSlidesElement(), katexOptions);
|
||||||
|
deck.layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadCss(cssUrl);
|
||||||
|
|
||||||
|
// For some reason dynamically loading with defer attribute doesn't result in the expected behavior, the below code does
|
||||||
|
loadScripts(katexScripts).then(() => {
|
||||||
|
if( deck.isReady() ) {
|
||||||
|
renderMath();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deck.on( 'ready', renderMath.bind( this ) );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -1 +1,6 @@
|
|||||||
function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?e(Object(a),!0).forEach((function(e){n(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):e(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function n(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}export default function(){var e,n={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"math",init:function(r){var a=(e=r).getConfig().math||{},o=t(t({},n),a),c=(o.mathjax||"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js")+"?config="+(o.config||"TeX-AMS_HTML-full");o.tex2jax=t(t({},n.tex2jax),a.tex2jax),o.mathjax=o.config=null,function(e,t){var n=this,r=document.querySelector("head"),a=document.createElement("script");a.type="text/javascript",a.src=e;var o=function(){"function"==typeof t&&(t.call(),t=null)};a.onload=o,a.onreadystatechange=function(){"loaded"===n.readyState&&o()},r.appendChild(a)}(c,(function(){MathJax.Hub.Config(o),MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.getRevealElement()]),MathJax.Hub.Queue(e.layout),e.on("slidechanged",(function(e){MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.currentSlide])}))}))}}}
|
const t=()=>{let t,e={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"mathjax2",init:function(a){t=a;let n=t.getConfig().mathjax2||t.getConfig().math||{},i={...e,...n},s=(i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js")+"?config="+(i.config||"TeX-AMS_HTML-full");i.tex2jax={...e.tex2jax,...n.tex2jax},i.mathjax=i.config=null,function(t,e){let a=document.querySelector("head"),n=document.createElement("script");n.type="text/javascript",n.src=t;let i=()=>{"function"==typeof e&&(e.call(),e=null)};n.onload=i,n.onreadystatechange=()=>{"loaded"===this.readyState&&i()},a.appendChild(n)}(s,(function(){MathJax.Hub.Config(i),MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.getRevealElement()]),MathJax.Hub.Queue(t.layout),t.on("slidechanged",(function(t){MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.currentSlide])}))}))}}},e=t;
|
||||||
|
/*!
|
||||||
|
* This plugin is a wrapper for the MathJax2,
|
||||||
|
* MathJax3 and KaTeX typesetter plugins.
|
||||||
|
*/
|
||||||
|
var a=Plugin=Object.assign(e(),{KaTeX:()=>{let t,e={version:"latest",delimiters:[{left:"$$",right:"$$",display:!0},{left:"$",right:"$",display:!1},{left:"\\(",right:"\\)",display:!1},{left:"\\[",right:"\\]",display:!0}],ignoredTags:["script","noscript","style","textarea","pre"]};const a=t=>new Promise(((e,a)=>{const n=document.createElement("script");n.type="text/javascript",n.onload=e,n.onerror=a,n.src=t,document.head.append(n)}));return{id:"katex",init:function(n){t=n;let i=t.getConfig().katex||{},s={...e,...i};const{local:l,version:o,extensions:r,...c}=s;let d=s.local||"https://cdn.jsdelivr.net/npm/katex",p=s.local?"":"@"+s.version,u=d+p+"/dist/katex.min.css",h=d+p+"/dist/contrib/mhchem.min.js",x=d+p+"/dist/contrib/auto-render.min.js",m=[d+p+"/dist/katex.min.js"];s.extensions&&s.extensions.includes("mhchem")&&m.push(h),m.push(x);const f=()=>{renderMathInElement(n.getSlidesElement(),c),t.layout()};(t=>{let e=document.createElement("link");e.rel="stylesheet",e.href=t,document.head.appendChild(e)})(u),async function(t){for(const e of t)await a(e)}(m).then((()=>{t.isReady()?f():t.on("ready",f.bind(this))}))}}},MathJax2:t,MathJax3:()=>{let t,e={tex:{inlineMath:[["$","$"],["\\(","\\)"]]},options:{skipHtmlTags:["script","noscript","style","textarea","pre"]},startup:{ready:()=>{MathJax.startup.defaultReady(),MathJax.startup.promise.then((()=>{Reveal.layout()}))}}};return{id:"mathjax3",init:function(a){t=a;let n=t.getConfig().mathjax3||{},i={...e,...n};i.tex={...e.tex,...n.tex},i.options={...e.options,...n.options},i.startup={...e.startup,...n.startup};let s=i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js";i.mathjax=null,window.MathJax=i,function(t,e){let a=document.createElement("script");a.type="text/javascript",a.id="MathJax-script",a.src=t,a.async=!0,a.onload=()=>{"function"==typeof e&&(e.call(),e=null)},document.head.appendChild(a)}(s,(function(){Reveal.addEventListener("slidechanged",(function(t){MathJax.typeset()}))}))}}}});export{a as default};
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealMath=t()}(this,(function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?e(Object(a),!0).forEach((function(e){n(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):e(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function n(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}return function(){var e,n={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"math",init:function(r){var a=(e=r).getConfig().math||{},o=t(t({},n),a),i=(o.mathjax||"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js")+"?config="+(o.config||"TeX-AMS_HTML-full");o.tex2jax=t(t({},n.tex2jax),a.tex2jax),o.mathjax=o.config=null,function(e,t){var n=this,r=document.querySelector("head"),a=document.createElement("script");a.type="text/javascript",a.src=e;var o=function(){"function"==typeof t&&(t.call(),t=null)};a.onload=o,a.onreadystatechange=function(){"loaded"===n.readyState&&o()},r.appendChild(a)}(i,(function(){MathJax.Hub.Config(o),MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.getRevealElement()]),MathJax.Hub.Queue(e.layout),e.on("slidechanged",(function(e){MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.currentSlide])}))}))}}}}));
|
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).RevealMath=e()}(this,(function(){"use strict";const t=()=>{let t,e={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"mathjax2",init:function(n){t=n;let a=t.getConfig().mathjax2||t.getConfig().math||{},i={...e,...a},s=(i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js")+"?config="+(i.config||"TeX-AMS_HTML-full");i.tex2jax={...e.tex2jax,...a.tex2jax},i.mathjax=i.config=null,function(t,e){let n=document.querySelector("head"),a=document.createElement("script");a.type="text/javascript",a.src=t;let i=()=>{"function"==typeof e&&(e.call(),e=null)};a.onload=i,a.onreadystatechange=()=>{"loaded"===this.readyState&&i()},n.appendChild(a)}(s,(function(){MathJax.Hub.Config(i),MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.getRevealElement()]),MathJax.Hub.Queue(t.layout),t.on("slidechanged",(function(t){MathJax.Hub.Queue(["Typeset",MathJax.Hub,t.currentSlide])}))}))}}},e=t;return Plugin=Object.assign(e(),{KaTeX:()=>{let t,e={version:"latest",delimiters:[{left:"$$",right:"$$",display:!0},{left:"$",right:"$",display:!1},{left:"\\(",right:"\\)",display:!1},{left:"\\[",right:"\\]",display:!0}],ignoredTags:["script","noscript","style","textarea","pre"]};const n=t=>new Promise(((e,n)=>{const a=document.createElement("script");a.type="text/javascript",a.onload=e,a.onerror=n,a.src=t,document.head.append(a)}));return{id:"katex",init:function(a){t=a;let i=t.getConfig().katex||{},s={...e,...i};const{local:o,version:l,extensions:r,...c}=s;let d=s.local||"https://cdn.jsdelivr.net/npm/katex",u=s.local?"":"@"+s.version,p=d+u+"/dist/katex.min.css",h=d+u+"/dist/contrib/mhchem.min.js",x=d+u+"/dist/contrib/auto-render.min.js",m=[d+u+"/dist/katex.min.js"];s.extensions&&s.extensions.includes("mhchem")&&m.push(h),m.push(x);const f=()=>{renderMathInElement(a.getSlidesElement(),c),t.layout()};(t=>{let e=document.createElement("link");e.rel="stylesheet",e.href=t,document.head.appendChild(e)})(p),async function(t){for(const e of t)await n(e)}(m).then((()=>{t.isReady()?f():t.on("ready",f.bind(this))}))}}},MathJax2:t,MathJax3:()=>{let t,e={tex:{inlineMath:[["$","$"],["\\(","\\)"]]},options:{skipHtmlTags:["script","noscript","style","textarea","pre"]},startup:{ready:()=>{MathJax.startup.defaultReady(),MathJax.startup.promise.then((()=>{Reveal.layout()}))}}};return{id:"mathjax3",init:function(n){t=n;let a=t.getConfig().mathjax3||{},i={...e,...a};i.tex={...e.tex,...a.tex},i.options={...e.options,...a.options},i.startup={...e.startup,...a.startup};let s=i.mathjax||"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js";i.mathjax=null,window.MathJax=i,function(t,e){let n=document.createElement("script");n.type="text/javascript",n.id="MathJax-script",n.src=t,n.async=!0,n.onload=()=>{"function"==typeof e&&(e.call(),e=null)},document.head.appendChild(n)}(s,(function(){Reveal.addEventListener("slidechanged",(function(t){MathJax.typeset()}))}))}}}})}));
|
||||||
|
|||||||
89
plugin/math/mathjax2.js
Normal file
89
plugin/math/mathjax2.js
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* A plugin which enables rendering of math equations inside
|
||||||
|
* of reveal.js slides. Essentially a thin wrapper for MathJax.
|
||||||
|
*
|
||||||
|
* @author Hakim El Hattab
|
||||||
|
*/
|
||||||
|
export const MathJax2 = () => {
|
||||||
|
|
||||||
|
// The reveal.js instance this plugin is attached to
|
||||||
|
let deck;
|
||||||
|
|
||||||
|
let defaultOptions = {
|
||||||
|
messageStyle: 'none',
|
||||||
|
tex2jax: {
|
||||||
|
inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ],
|
||||||
|
skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
|
||||||
|
},
|
||||||
|
skipStartupTypeset: true
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadScript( url, callback ) {
|
||||||
|
|
||||||
|
let head = document.querySelector( 'head' );
|
||||||
|
let script = document.createElement( 'script' );
|
||||||
|
script.type = 'text/javascript';
|
||||||
|
script.src = url;
|
||||||
|
|
||||||
|
// Wrapper for callback to make sure it only fires once
|
||||||
|
let finish = () => {
|
||||||
|
if( typeof callback === 'function' ) {
|
||||||
|
callback.call();
|
||||||
|
callback = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
script.onload = finish;
|
||||||
|
|
||||||
|
// IE
|
||||||
|
script.onreadystatechange = () => {
|
||||||
|
if ( this.readyState === 'loaded' ) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal browsers
|
||||||
|
head.appendChild( script );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: 'mathjax2',
|
||||||
|
|
||||||
|
init: function( reveal ) {
|
||||||
|
|
||||||
|
deck = reveal;
|
||||||
|
|
||||||
|
let revealOptions = deck.getConfig().mathjax2 || deck.getConfig().math || {};
|
||||||
|
|
||||||
|
let options = { ...defaultOptions, ...revealOptions };
|
||||||
|
let mathjax = options.mathjax || 'https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js';
|
||||||
|
let config = options.config || 'TeX-AMS_HTML-full';
|
||||||
|
let url = mathjax + '?config=' + config;
|
||||||
|
|
||||||
|
options.tex2jax = { ...defaultOptions.tex2jax, ...revealOptions.tex2jax };
|
||||||
|
|
||||||
|
options.mathjax = options.config = null;
|
||||||
|
|
||||||
|
loadScript( url, function() {
|
||||||
|
|
||||||
|
MathJax.Hub.Config( options );
|
||||||
|
|
||||||
|
// Typeset followed by an immediate reveal.js layout since
|
||||||
|
// the typesetting process could affect slide height
|
||||||
|
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, deck.getRevealElement() ] );
|
||||||
|
MathJax.Hub.Queue( deck.layout );
|
||||||
|
|
||||||
|
// Reprocess equations in slides when they turn visible
|
||||||
|
deck.on( 'slidechanged', function( event ) {
|
||||||
|
|
||||||
|
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
77
plugin/math/mathjax3.js
Normal file
77
plugin/math/mathjax3.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* A plugin which enables rendering of math equations inside
|
||||||
|
* of reveal.js slides. Essentially a thin wrapper for MathJax 3
|
||||||
|
*
|
||||||
|
* @author Hakim El Hattab
|
||||||
|
* @author Gerhard Burger
|
||||||
|
*/
|
||||||
|
export const MathJax3 = () => {
|
||||||
|
|
||||||
|
// The reveal.js instance this plugin is attached to
|
||||||
|
let deck;
|
||||||
|
|
||||||
|
let defaultOptions = {
|
||||||
|
tex: {
|
||||||
|
inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
skipHtmlTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
|
||||||
|
},
|
||||||
|
startup: {
|
||||||
|
ready: () => {
|
||||||
|
MathJax.startup.defaultReady();
|
||||||
|
MathJax.startup.promise.then(() => {
|
||||||
|
Reveal.layout();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadScript( url, callback ) {
|
||||||
|
|
||||||
|
let script = document.createElement( 'script' );
|
||||||
|
script.type = "text/javascript"
|
||||||
|
script.id = "MathJax-script"
|
||||||
|
script.src = url;
|
||||||
|
script.async = true
|
||||||
|
|
||||||
|
// Wrapper for callback to make sure it only fires once
|
||||||
|
script.onload = () => {
|
||||||
|
if (typeof callback === 'function') {
|
||||||
|
callback.call();
|
||||||
|
callback = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.head.appendChild( script );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: 'mathjax3',
|
||||||
|
init: function(reveal) {
|
||||||
|
|
||||||
|
deck = reveal;
|
||||||
|
|
||||||
|
let revealOptions = deck.getConfig().mathjax3 || {};
|
||||||
|
let options = {...defaultOptions, ...revealOptions};
|
||||||
|
options.tex = {...defaultOptions.tex, ...revealOptions.tex}
|
||||||
|
options.options = {...defaultOptions.options, ...revealOptions.options}
|
||||||
|
options.startup = {...defaultOptions.startup, ...revealOptions.startup}
|
||||||
|
|
||||||
|
let url = options.mathjax || 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js';
|
||||||
|
options.mathjax = null;
|
||||||
|
|
||||||
|
window.MathJax = options;
|
||||||
|
|
||||||
|
loadScript( url, function() {
|
||||||
|
// Reprocess equations in slides when they turn visible
|
||||||
|
Reveal.addEventListener( 'slidechanged', function( event ) {
|
||||||
|
MathJax.typeset();
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
104
plugin/math/plugin.js
Executable file → Normal file
104
plugin/math/plugin.js
Executable file → Normal file
@@ -1,91 +1,15 @@
|
|||||||
/**
|
import {KaTeX} from "./katex";
|
||||||
* A plugin which enables rendering of math equations inside
|
import {MathJax2} from "./mathjax2";
|
||||||
* of reveal.js slides. Essentially a thin wrapper for MathJax.
|
import {MathJax3} from "./mathjax3";
|
||||||
*
|
|
||||||
* @author Hakim El Hattab
|
const defaultTypesetter = MathJax2;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* This plugin is a wrapper for the MathJax2,
|
||||||
|
* MathJax3 and KaTeX typesetter plugins.
|
||||||
*/
|
*/
|
||||||
const Plugin = () => {
|
export default Plugin = Object.assign( defaultTypesetter(), {
|
||||||
|
KaTeX,
|
||||||
// The reveal.js instance this plugin is attached to
|
MathJax2,
|
||||||
let deck;
|
MathJax3
|
||||||
|
} );
|
||||||
let defaultOptions = {
|
|
||||||
messageStyle: 'none',
|
|
||||||
tex2jax: {
|
|
||||||
inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ],
|
|
||||||
skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
|
|
||||||
},
|
|
||||||
skipStartupTypeset: true
|
|
||||||
};
|
|
||||||
|
|
||||||
function loadScript( url, callback ) {
|
|
||||||
|
|
||||||
let head = document.querySelector( 'head' );
|
|
||||||
let script = document.createElement( 'script' );
|
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.src = url;
|
|
||||||
|
|
||||||
// Wrapper for callback to make sure it only fires once
|
|
||||||
let finish = () => {
|
|
||||||
if( typeof callback === 'function' ) {
|
|
||||||
callback.call();
|
|
||||||
callback = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
script.onload = finish;
|
|
||||||
|
|
||||||
// IE
|
|
||||||
script.onreadystatechange = () => {
|
|
||||||
if ( this.readyState === 'loaded' ) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normal browsers
|
|
||||||
head.appendChild( script );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: 'math',
|
|
||||||
|
|
||||||
init: function( reveal ) {
|
|
||||||
|
|
||||||
deck = reveal;
|
|
||||||
|
|
||||||
let revealOptions = deck.getConfig().math || {};
|
|
||||||
|
|
||||||
let options = { ...defaultOptions, ...revealOptions };
|
|
||||||
let mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js';
|
|
||||||
let config = options.config || 'TeX-AMS_HTML-full';
|
|
||||||
let url = mathjax + '?config=' + config;
|
|
||||||
|
|
||||||
options.tex2jax = { ...defaultOptions.tex2jax, ...revealOptions.tex2jax };
|
|
||||||
|
|
||||||
options.mathjax = options.config = null;
|
|
||||||
|
|
||||||
loadScript( url, function() {
|
|
||||||
|
|
||||||
MathJax.Hub.Config( options );
|
|
||||||
|
|
||||||
// Typeset followed by an immediate reveal.js layout since
|
|
||||||
// the typesetting process could affect slide height
|
|
||||||
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, deck.getRevealElement() ] );
|
|
||||||
MathJax.Hub.Queue( deck.layout );
|
|
||||||
|
|
||||||
// Reprocess equations in slides when they turn visible
|
|
||||||
deck.on( 'slidechanged', function( event ) {
|
|
||||||
|
|
||||||
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Plugin;
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
import speakerViewHTML from './speaker-view.html';
|
import speakerViewHTML from './speaker-view.html'
|
||||||
|
|
||||||
import marked from 'marked';
|
import { marked } from 'marked';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles opening of and synchronization with the reveal.js
|
* Handles opening of and synchronization with the reveal.js
|
||||||
@@ -15,24 +15,48 @@ import marked from 'marked';
|
|||||||
*/
|
*/
|
||||||
const Plugin = () => {
|
const Plugin = () => {
|
||||||
|
|
||||||
let popup = null;
|
let connectInterval;
|
||||||
|
let speakerWindow = null;
|
||||||
let deck;
|
let deck;
|
||||||
|
|
||||||
function openNotes() {
|
/**
|
||||||
|
* Opens a new speaker view window.
|
||||||
|
*/
|
||||||
|
function openSpeakerWindow() {
|
||||||
|
|
||||||
if (popup && !popup.closed) {
|
// If a window is already open, focus it
|
||||||
popup.focus();
|
if( speakerWindow && !speakerWindow.closed ) {
|
||||||
|
speakerWindow.focus();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
speakerWindow = window.open( 'about:blank', 'reveal.js - Notes', 'width=1100,height=700' );
|
||||||
|
speakerWindow.marked = marked;
|
||||||
|
speakerWindow.document.write( speakerViewHTML );
|
||||||
|
|
||||||
|
if( !speakerWindow ) {
|
||||||
|
alert( 'Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.' );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
popup = window.open( 'about:blank', 'reveal.js - Notes', 'width=1100,height=700' );
|
connect();
|
||||||
popup.marked = marked;
|
}
|
||||||
popup.document.write( speakerViewHTML );
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reconnect with an existing speaker view window.
|
||||||
|
*/
|
||||||
|
function reconnectSpeakerWindow( reconnectWindow ) {
|
||||||
|
|
||||||
|
if( speakerWindow && !speakerWindow.closed ) {
|
||||||
|
speakerWindow.focus();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
speakerWindow = reconnectWindow;
|
||||||
|
window.addEventListener( 'message', onPostMessage );
|
||||||
|
onConnected();
|
||||||
|
}
|
||||||
|
|
||||||
if( !popup ) {
|
|
||||||
alert( 'Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.' );
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,26 +66,24 @@ const Plugin = () => {
|
|||||||
* file system.
|
* file system.
|
||||||
*/
|
*/
|
||||||
function connect() {
|
function connect() {
|
||||||
|
|
||||||
|
const presentationURL = deck.getConfig().url;
|
||||||
|
|
||||||
|
const url = typeof presentationURL === 'string' ? presentationURL :
|
||||||
|
window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search;
|
||||||
|
|
||||||
// Keep trying to connect until we get a 'connected' message back
|
// Keep trying to connect until we get a 'connected' message back
|
||||||
let connectInterval = setInterval( function() {
|
connectInterval = setInterval( function() {
|
||||||
popup.postMessage( JSON.stringify( {
|
speakerWindow.postMessage( JSON.stringify( {
|
||||||
namespace: 'reveal-notes',
|
namespace: 'reveal-notes',
|
||||||
type: 'connect',
|
type: 'connect',
|
||||||
url: window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search,
|
state: deck.getState(),
|
||||||
state: deck.getState()
|
url
|
||||||
} ), '*' );
|
} ), '*' );
|
||||||
}, 500 );
|
}, 500 );
|
||||||
|
|
||||||
window.addEventListener( 'message', function( event ) {
|
window.addEventListener( 'message', onPostMessage );
|
||||||
let data = JSON.parse( event.data );
|
|
||||||
if( data && data.namespace === 'reveal-notes' && data.type === 'connected' ) {
|
|
||||||
clearInterval( connectInterval );
|
|
||||||
onConnected();
|
|
||||||
}
|
|
||||||
if( data && data.namespace === 'reveal-notes' && data.type === 'call' ) {
|
|
||||||
callRevealApi( data.methodName, data.arguments, data.callId );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,22 +93,22 @@ const Plugin = () => {
|
|||||||
function callRevealApi( methodName, methodArguments, callId ) {
|
function callRevealApi( methodName, methodArguments, callId ) {
|
||||||
|
|
||||||
let result = deck[methodName].apply( deck, methodArguments );
|
let result = deck[methodName].apply( deck, methodArguments );
|
||||||
popup.postMessage( JSON.stringify( {
|
speakerWindow.postMessage( JSON.stringify( {
|
||||||
namespace: 'reveal-notes',
|
namespace: 'reveal-notes',
|
||||||
type: 'return',
|
type: 'return',
|
||||||
result: result,
|
result,
|
||||||
callId: callId
|
callId
|
||||||
} ), '*' );
|
} ), '*' );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Posts the current slide data to the notes window
|
* Posts the current slide data to the notes window.
|
||||||
*/
|
*/
|
||||||
function post( event ) {
|
function post( event ) {
|
||||||
|
|
||||||
let slideElement = deck.getCurrentSlide(),
|
let slideElement = deck.getCurrentSlide(),
|
||||||
notesElement = slideElement.querySelector( 'aside.notes' ),
|
notesElements = slideElement.querySelectorAll( 'aside.notes' ),
|
||||||
fragmentElement = slideElement.querySelector( '.current-fragment' );
|
fragmentElement = slideElement.querySelector( '.current-fragment' );
|
||||||
|
|
||||||
let messageData = {
|
let messageData = {
|
||||||
@@ -108,24 +130,66 @@ const Plugin = () => {
|
|||||||
if( fragmentElement ) {
|
if( fragmentElement ) {
|
||||||
let fragmentNotes = fragmentElement.querySelector( 'aside.notes' );
|
let fragmentNotes = fragmentElement.querySelector( 'aside.notes' );
|
||||||
if( fragmentNotes ) {
|
if( fragmentNotes ) {
|
||||||
notesElement = fragmentNotes;
|
messageData.notes = fragmentNotes.innerHTML;
|
||||||
|
messageData.markdown = typeof fragmentNotes.getAttribute( 'data-markdown' ) === 'string';
|
||||||
|
|
||||||
|
// Ignore other slide notes
|
||||||
|
notesElements = null;
|
||||||
}
|
}
|
||||||
else if( fragmentElement.hasAttribute( 'data-notes' ) ) {
|
else if( fragmentElement.hasAttribute( 'data-notes' ) ) {
|
||||||
messageData.notes = fragmentElement.getAttribute( 'data-notes' );
|
messageData.notes = fragmentElement.getAttribute( 'data-notes' );
|
||||||
messageData.whitespace = 'pre-wrap';
|
messageData.whitespace = 'pre-wrap';
|
||||||
|
|
||||||
// In case there are slide notes
|
// In case there are slide notes
|
||||||
notesElement = null;
|
notesElements = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for notes defined in an aside element
|
// Look for notes defined in an aside element
|
||||||
if( notesElement ) {
|
if( notesElements && notesElements.length ) {
|
||||||
messageData.notes = notesElement.innerHTML;
|
// Ignore notes inside of fragments since those are shown
|
||||||
messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string';
|
// individually when stepping through fragments
|
||||||
|
notesElements = Array.from( notesElements ).filter( notesElement => notesElement.closest( '.fragment' ) === null );
|
||||||
|
|
||||||
|
messageData.notes = notesElements.map( notesElement => notesElement.innerHTML ).join( '\n' );
|
||||||
|
messageData.markdown = notesElements[0] && typeof notesElements[0].getAttribute( 'data-markdown' ) === 'string';
|
||||||
}
|
}
|
||||||
|
|
||||||
popup.postMessage( JSON.stringify( messageData ), '*' );
|
speakerWindow.postMessage( JSON.stringify( messageData ), '*' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given event is from the same origin as the
|
||||||
|
* current window.
|
||||||
|
*/
|
||||||
|
function isSameOriginEvent( event ) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
return window.location.origin === event.source.location.origin;
|
||||||
|
}
|
||||||
|
catch ( error ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPostMessage( event ) {
|
||||||
|
|
||||||
|
// Only allow same-origin messages
|
||||||
|
// (added 12/5/22 as a XSS safeguard)
|
||||||
|
if( isSameOriginEvent( event ) ) {
|
||||||
|
|
||||||
|
let data = JSON.parse( event.data );
|
||||||
|
if( data && data.namespace === 'reveal-notes' && data.type === 'connected' ) {
|
||||||
|
clearInterval( connectInterval );
|
||||||
|
onConnected();
|
||||||
|
}
|
||||||
|
else if( data && data.namespace === 'reveal-notes' && data.type === 'call' ) {
|
||||||
|
callRevealApi( data.methodName, data.arguments, data.callId );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,10 +213,6 @@ const Plugin = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connect();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: 'notes',
|
id: 'notes',
|
||||||
|
|
||||||
@@ -164,19 +224,40 @@ const Plugin = () => {
|
|||||||
|
|
||||||
// If the there's a 'notes' query set, open directly
|
// If the there's a 'notes' query set, open directly
|
||||||
if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
|
if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
|
||||||
openNotes();
|
openSpeakerWindow();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Keep listening for speaker view hearbeats. If we receive a
|
||||||
|
// heartbeat from an orphaned window, reconnect it. This ensures
|
||||||
|
// that we remain connected to the notes even if the presentation
|
||||||
|
// is reloaded.
|
||||||
|
window.addEventListener( 'message', event => {
|
||||||
|
|
||||||
|
if( !speakerWindow && typeof event.data === 'string' ) {
|
||||||
|
let data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
data = JSON.parse( event.data );
|
||||||
|
}
|
||||||
|
catch( error ) {}
|
||||||
|
|
||||||
|
if( data && data.namespace === 'reveal-notes' && data.type === 'heartbeat' ) {
|
||||||
|
reconnectSpeakerWindow( event.source );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the notes when the 's' key is hit
|
// Open the notes when the 's' key is hit
|
||||||
deck.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() {
|
deck.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() {
|
||||||
openNotes();
|
openSpeakerWindow();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
open: openNotes
|
open: openSpeakerWindow
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
<!--
|
||||||
|
NOTE: You need to build the notes plugin after making changes to this file.
|
||||||
|
-->
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
@@ -347,7 +350,9 @@
|
|||||||
layoutDropdown,
|
layoutDropdown,
|
||||||
pendingCalls = {},
|
pendingCalls = {},
|
||||||
lastRevealApiCallId = 0,
|
lastRevealApiCallId = 0,
|
||||||
connected = false;
|
connected = false
|
||||||
|
|
||||||
|
var connectionStatus = document.querySelector( '#connection-status' );
|
||||||
|
|
||||||
var SPEAKER_LAYOUTS = {
|
var SPEAKER_LAYOUTS = {
|
||||||
'default': 'Default',
|
'default': 'Default',
|
||||||
@@ -358,7 +363,20 @@
|
|||||||
|
|
||||||
setupLayout();
|
setupLayout();
|
||||||
|
|
||||||
var connectionStatus = document.querySelector( '#connection-status' );
|
let openerOrigin;
|
||||||
|
|
||||||
|
try {
|
||||||
|
openerOrigin = window.opener.location.origin;
|
||||||
|
}
|
||||||
|
catch ( error ) { console.warn( error ) }
|
||||||
|
|
||||||
|
// In order to prevent XSS, the speaker view will only run if its
|
||||||
|
// opener has the same origin as itself
|
||||||
|
if( window.location.origin !== openerOrigin ) {
|
||||||
|
connectionStatus.innerHTML = 'Cross origin error.<br>The speaker window can only be opened from the same origin.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var connectionTimeout = setTimeout( function() {
|
var connectionTimeout = setTimeout( function() {
|
||||||
connectionStatus.innerHTML = 'Error connecting to main window.<br>Please try closing and reopening the speaker view.';
|
connectionStatus.innerHTML = 'Error connecting to main window.<br>Please try closing and reopening the speaker view.';
|
||||||
}, 5000 );
|
}, 5000 );
|
||||||
@@ -395,13 +413,21 @@
|
|||||||
}
|
}
|
||||||
else if( /slidechanged|fragmentshown|fragmenthidden|paused|resumed/.test( data.eventName ) && currentState !== JSON.stringify( data.state ) ) {
|
else if( /slidechanged|fragmentshown|fragmenthidden|paused|resumed/.test( data.eventName ) && currentState !== JSON.stringify( data.state ) ) {
|
||||||
|
|
||||||
window.opener.postMessage( JSON.stringify({ method: 'setState', args: [ data.state ]} ), '*' );
|
dispatchStateToMainWindow( data.state );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the presentation in the main window to match the state
|
||||||
|
* of the presentation in the notes window.
|
||||||
|
*/
|
||||||
|
const dispatchStateToMainWindow = debounce(( state ) => {
|
||||||
|
window.opener.postMessage( JSON.stringify({ method: 'setState', args: [ state ]} ), '*' );
|
||||||
|
}, 500);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously calls the Reveal.js API of the main frame.
|
* Asynchronously calls the Reveal.js API of the main frame.
|
||||||
*/
|
*/
|
||||||
@@ -432,6 +458,7 @@
|
|||||||
setupKeyboard();
|
setupKeyboard();
|
||||||
setupNotes();
|
setupNotes();
|
||||||
setupTimer();
|
setupTimer();
|
||||||
|
setupHeartbeat();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -506,8 +533,8 @@
|
|||||||
|
|
||||||
var urlSeparator = /\?/.test(data.url) ? '&' : '?';
|
var urlSeparator = /\?/.test(data.url) ? '&' : '?';
|
||||||
var hash = '#/' + data.state.indexh + '/' + data.state.indexv;
|
var hash = '#/' + data.state.indexh + '/' + data.state.indexv;
|
||||||
var currentURL = data.url + urlSeparator + params + '&postMessageEvents=true' + hash;
|
var currentURL = data.url + urlSeparator + params + '&scrollActivationWidth=false&postMessageEvents=true' + hash;
|
||||||
var upcomingURL = data.url + urlSeparator + params + '&controls=false' + hash;
|
var upcomingURL = data.url + urlSeparator + params + '&scrollActivationWidth=false&controls=false' + hash;
|
||||||
|
|
||||||
currentSlide = document.createElement( 'iframe' );
|
currentSlide = document.createElement( 'iframe' );
|
||||||
currentSlide.setAttribute( 'width', 1280 );
|
currentSlide.setAttribute( 'width', 1280 );
|
||||||
@@ -533,6 +560,18 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We send out a heartbeat at all times to ensure we can
|
||||||
|
* reconnect with the main presentation window after reloads.
|
||||||
|
*/
|
||||||
|
function setupHeartbeat() {
|
||||||
|
|
||||||
|
setInterval( () => {
|
||||||
|
window.opener.postMessage( JSON.stringify({ namespace: 'reveal-notes', type: 'heartbeat'} ), '*' );
|
||||||
|
}, 1000 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function getTimings( callback ) {
|
function getTimings( callback ) {
|
||||||
|
|
||||||
callRevealApi( 'getSlidesAttributes', [], function ( slideAttributes ) {
|
callRevealApi( 'getSlidesAttributes', [], function ( slideAttributes ) {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -25,6 +25,12 @@ const Plugin = {
|
|||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: () => {
|
||||||
|
|
||||||
|
zoom.reset();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -52,19 +58,11 @@ var zoom = (function(){
|
|||||||
panUpdateInterval = -1;
|
panUpdateInterval = -1;
|
||||||
|
|
||||||
// Check for transform support so that we can fallback otherwise
|
// Check for transform support so that we can fallback otherwise
|
||||||
var supportsTransforms = 'WebkitTransform' in document.body.style ||
|
var supportsTransforms = 'transform' in document.body.style;
|
||||||
'MozTransform' in document.body.style ||
|
|
||||||
'msTransform' in document.body.style ||
|
|
||||||
'OTransform' in document.body.style ||
|
|
||||||
'transform' in document.body.style;
|
|
||||||
|
|
||||||
if( supportsTransforms ) {
|
if( supportsTransforms ) {
|
||||||
// The easing that will be applied when we zoom in/out
|
// The easing that will be applied when we zoom in/out
|
||||||
document.body.style.transition = 'transform 0.8s ease';
|
document.body.style.transition = 'transform 0.8s ease';
|
||||||
document.body.style.OTransition = '-o-transform 0.8s ease';
|
|
||||||
document.body.style.msTransition = '-ms-transform 0.8s ease';
|
|
||||||
document.body.style.MozTransition = '-moz-transform 0.8s ease';
|
|
||||||
document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom out if the user hits escape
|
// Zoom out if the user hits escape
|
||||||
@@ -105,10 +103,6 @@ var zoom = (function(){
|
|||||||
// Reset
|
// Reset
|
||||||
if( scale === 1 ) {
|
if( scale === 1 ) {
|
||||||
document.body.style.transform = '';
|
document.body.style.transform = '';
|
||||||
document.body.style.OTransform = '';
|
|
||||||
document.body.style.msTransform = '';
|
|
||||||
document.body.style.MozTransform = '';
|
|
||||||
document.body.style.WebkitTransform = '';
|
|
||||||
}
|
}
|
||||||
// Scale
|
// Scale
|
||||||
else {
|
else {
|
||||||
@@ -116,16 +110,7 @@ var zoom = (function(){
|
|||||||
transform = 'translate('+ -rect.x +'px,'+ -rect.y +'px) scale('+ scale +')';
|
transform = 'translate('+ -rect.x +'px,'+ -rect.y +'px) scale('+ scale +')';
|
||||||
|
|
||||||
document.body.style.transformOrigin = origin;
|
document.body.style.transformOrigin = origin;
|
||||||
document.body.style.OTransformOrigin = origin;
|
|
||||||
document.body.style.msTransformOrigin = origin;
|
|
||||||
document.body.style.MozTransformOrigin = origin;
|
|
||||||
document.body.style.WebkitTransformOrigin = origin;
|
|
||||||
|
|
||||||
document.body.style.transform = transform;
|
document.body.style.transform = transform;
|
||||||
document.body.style.OTransform = transform;
|
|
||||||
document.body.style.msTransform = transform;
|
|
||||||
document.body.style.MozTransform = transform;
|
|
||||||
document.body.style.WebkitTransform = transform;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
/*!
|
/*!
|
||||||
* reveal.js Zoom plugin
|
* reveal.js Zoom plugin
|
||||||
*/
|
*/
|
||||||
var e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(o){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;o[i]&&!e.isOverview()&&(o.preventDefault(),t.to({x:o.clientX,y:o.clientY,scale:d,pan:!1}))}))}},t=function(){var e=1,o=0,n=0,i=-1,d=-1,s="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style;function r(t,o){var n=y();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,s)if(1===o)document.body.style.transform="",document.body.style.OTransform="",document.body.style.msTransform="",document.body.style.MozTransform="",document.body.style.WebkitTransform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.OTransformOrigin=i,document.body.style.msTransformOrigin=i,document.body.style.MozTransformOrigin=i,document.body.style.WebkitTransformOrigin=i,document.body.style.transform=d,document.body.style.OTransform=d,document.body.style.msTransform=d,document.body.style.MozTransform=d,document.body.style.WebkitTransform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function m(){var t=.12*window.innerWidth,i=.12*window.innerHeight,d=y();n<i?window.scroll(d.x,d.y-14/e*(1-n/i)):n>window.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),o<t?window.scroll(d.x-14/e*(1-o/t),d.y):o>window.innerWidth-t&&window.scroll(d.x+(1-(window.innerWidth-o)/t)*(14/e),d.y)}function y(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return s&&(document.body.style.transition="transform 0.8s ease",document.body.style.OTransition="-o-transform 0.8s ease",document.body.style.msTransition="-ms-transform 0.8s ease",document.body.style.MozTransition="-moz-transform 0.8s ease",document.body.style.WebkitTransition="-webkit-transform 0.8s ease"),document.addEventListener("keyup",(function(o){1!==e&&27===o.keyCode&&t.out()})),document.addEventListener("mousemove",(function(t){1!==e&&(o=t.clientX,n=t.clientY)})),{to:function(o){if(1!==e)t.out();else{if(o.x=o.x||0,o.y=o.y||0,o.element){var n=o.element.getBoundingClientRect();o.x=n.left-20,o.y=n.top-20,o.width=n.width+40,o.height=n.height+40}void 0!==o.width&&void 0!==o.height&&(o.scale=Math.max(Math.min(window.innerWidth/o.width,window.innerHeight/o.height),1)),o.scale>1&&(o.x*=o.scale,o.y*=o.scale,r(o,o.scale),!1!==o.pan&&(i=setTimeout((function(){d=setInterval(m,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),r({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();export default function(){return e}
|
const e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(t){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;t[i]&&!e.isOverview()&&(t.preventDefault(),o.to({x:t.clientX,y:t.clientY,scale:d,pan:!1}))}))},destroy:()=>{o.reset()}};var t=()=>e,o=function(){var e=1,t=0,n=0,i=-1,d=-1,l="transform"in document.body.style;function s(t,o){var n=r();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,l)if(1===o)document.body.style.transform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.transform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function c(){var o=.12*window.innerWidth,i=.12*window.innerHeight,d=r();n<i?window.scroll(d.x,d.y-14/e*(1-n/i)):n>window.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),t<o?window.scroll(d.x-14/e*(1-t/o),d.y):t>window.innerWidth-o&&window.scroll(d.x+(1-(window.innerWidth-t)/o)*(14/e),d.y)}function r(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return l&&(document.body.style.transition="transform 0.8s ease"),document.addEventListener("keyup",(function(t){1!==e&&27===t.keyCode&&o.out()})),document.addEventListener("mousemove",(function(o){1!==e&&(t=o.clientX,n=o.clientY)})),{to:function(t){if(1!==e)o.out();else{if(t.x=t.x||0,t.y=t.y||0,t.element){var n=t.element.getBoundingClientRect();t.x=n.left-20,t.y=n.top-20,t.width=n.width+40,t.height=n.height+40}void 0!==t.width&&void 0!==t.height&&(t.scale=Math.max(Math.min(window.innerWidth/t.width,window.innerHeight/t.height),1)),t.scale>1&&(t.x*=t.scale,t.y*=t.scale,s(t,t.scale),!1!==t.pan&&(i=setTimeout((function(){d=setInterval(c,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),s({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();
|
||||||
|
/*!
|
||||||
|
* zoom.js 0.3 (modified for use with reveal.js)
|
||||||
|
* http://lab.hakim.se/zoom-js
|
||||||
|
* MIT licensed
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011-2014 Hakim El Hattab, http://hakim.se
|
||||||
|
*/export{t as default};
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealZoom=o()}(this,(function(){"use strict";
|
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealZoom=t()}(this,(function(){"use strict";
|
||||||
/*!
|
/*!
|
||||||
* reveal.js Zoom plugin
|
* reveal.js Zoom plugin
|
||||||
*/var e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(t){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;t[i]&&!e.isOverview()&&(t.preventDefault(),o.to({x:t.clientX,y:t.clientY,scale:d,pan:!1}))}))}},o=function(){var e=1,t=0,n=0,i=-1,d=-1,s="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style;function r(o,t){var n=l();if(o.width=o.width||1,o.height=o.height||1,o.x-=(window.innerWidth-o.width*t)/2,o.y-=(window.innerHeight-o.height*t)/2,s)if(1===t)document.body.style.transform="",document.body.style.OTransform="",document.body.style.msTransform="",document.body.style.MozTransform="",document.body.style.WebkitTransform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-o.x+"px,"+-o.y+"px) scale("+t+")";document.body.style.transformOrigin=i,document.body.style.OTransformOrigin=i,document.body.style.msTransformOrigin=i,document.body.style.MozTransformOrigin=i,document.body.style.WebkitTransformOrigin=i,document.body.style.transform=d,document.body.style.OTransform=d,document.body.style.msTransform=d,document.body.style.MozTransform=d,document.body.style.WebkitTransform=d}else 1===t?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+o.x)/t+"px",document.body.style.top=-(n.y+o.y)/t+"px",document.body.style.width=100*t+"%",document.body.style.height=100*t+"%",document.body.style.zoom=t);e=t,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function m(){var o=.12*window.innerWidth,i=.12*window.innerHeight,d=l();n<i?window.scroll(d.x,d.y-14/e*(1-n/i)):n>window.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),t<o?window.scroll(d.x-14/e*(1-t/o),d.y):t>window.innerWidth-o&&window.scroll(d.x+(1-(window.innerWidth-t)/o)*(14/e),d.y)}function l(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return s&&(document.body.style.transition="transform 0.8s ease",document.body.style.OTransition="-o-transform 0.8s ease",document.body.style.msTransition="-ms-transform 0.8s ease",document.body.style.MozTransition="-moz-transform 0.8s ease",document.body.style.WebkitTransition="-webkit-transform 0.8s ease"),document.addEventListener("keyup",(function(t){1!==e&&27===t.keyCode&&o.out()})),document.addEventListener("mousemove",(function(o){1!==e&&(t=o.clientX,n=o.clientY)})),{to:function(t){if(1!==e)o.out();else{if(t.x=t.x||0,t.y=t.y||0,t.element){var n=t.element.getBoundingClientRect();t.x=n.left-20,t.y=n.top-20,t.width=n.width+40,t.height=n.height+40}void 0!==t.width&&void 0!==t.height&&(t.scale=Math.max(Math.min(window.innerWidth/t.width,window.innerHeight/t.height),1)),t.scale>1&&(t.x*=t.scale,t.y*=t.scale,r(t,t.scale),!1!==t.pan&&(i=setTimeout((function(){d=setInterval(m,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),r({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();return function(){return e}}));
|
*/const e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(o){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;o[i]&&!e.isOverview()&&(o.preventDefault(),t.to({x:o.clientX,y:o.clientY,scale:d,pan:!1}))}))},destroy:()=>{t.reset()}};var t=function(){var e=1,o=0,n=0,i=-1,d=-1,l="transform"in document.body.style;function s(t,o){var n=r();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,l)if(1===o)document.body.style.transform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.transform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function c(){var t=.12*window.innerWidth,i=.12*window.innerHeight,d=r();n<i?window.scroll(d.x,d.y-14/e*(1-n/i)):n>window.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),o<t?window.scroll(d.x-14/e*(1-o/t),d.y):o>window.innerWidth-t&&window.scroll(d.x+(1-(window.innerWidth-o)/t)*(14/e),d.y)}function r(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return l&&(document.body.style.transition="transform 0.8s ease"),document.addEventListener("keyup",(function(o){1!==e&&27===o.keyCode&&t.out()})),document.addEventListener("mousemove",(function(t){1!==e&&(o=t.clientX,n=t.clientY)})),{to:function(o){if(1!==e)t.out();else{if(o.x=o.x||0,o.y=o.y||0,o.element){var n=o.element.getBoundingClientRect();o.x=n.left-20,o.y=n.top-20,o.width=n.width+40,o.height=n.height+40}void 0!==o.width&&void 0!==o.height&&(o.scale=Math.max(Math.min(window.innerWidth/o.width,window.innerHeight/o.height),1)),o.scale>1&&(o.x*=o.scale,o.y*=o.scale,s(o,o.scale),!1!==o.pan&&(i=setTimeout((function(){d=setInterval(c,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),s({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();
|
||||||
|
/*!
|
||||||
|
* zoom.js 0.3 (modified for use with reveal.js)
|
||||||
|
* http://lab.hakim.se/zoom-js
|
||||||
|
* MIT licensed
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011-2014 Hakim El Hattab, http://hakim.se
|
||||||
|
*/return()=>e}));
|
||||||
|
|||||||
@@ -23,19 +23,19 @@
|
|||||||
<section data-auto-animate>
|
<section data-auto-animate>
|
||||||
<h1>h1</h1>
|
<h1>h1</h1>
|
||||||
<h2>h2</h2>
|
<h2>h2</h2>
|
||||||
<h3 style="position: absolute; left: 0;">h3</h2>
|
<h3 style="position: absolute; left: 0;">h3</h3>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-auto-animate>
|
<section data-auto-animate>
|
||||||
<h1 data-auto-animate-duration="0.1">h1</h1>
|
<h1 data-auto-animate-duration="0.1">h1</h1>
|
||||||
<h2 style="opacity: 0;">h2</h2>
|
<h2 style="opacity: 0;">h2</h2>
|
||||||
<h3 style="position: absolute; left: 100px;">h3</h2>
|
<h3 style="position: absolute; left: 100px;">h3</h3>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-auto-animate data-auto-animate-duration="0.1">
|
<section data-auto-animate data-auto-animate-duration="0.1">
|
||||||
<h1>h1</h1>
|
<h1>h1</h1>
|
||||||
<h2>h2</h2>
|
<h2>h2</h2>
|
||||||
<h3>h3</h2>
|
<h3>h3</h3>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
@@ -65,6 +65,7 @@
|
|||||||
<script src="../dist/reveal.js"></script>
|
<script src="../dist/reveal.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
QUnit.config.testTimeout = 30000;
|
||||||
QUnit.config.reorder = false;
|
QUnit.config.reorder = false;
|
||||||
|
|
||||||
const slides = Array.prototype.map.call( document.querySelectorAll( '.slides section' ), slide => {
|
const slides = Array.prototype.map.call( document.querySelectorAll( '.slides section' ), slide => {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user