reveal.js-appearance 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +45 -11
- package/package.json +64 -17
- package/plugin/appearance/appearance.css +113 -201
- package/plugin/appearance/appearance.esm.js +621 -407
- package/plugin/appearance/appearance.js +621 -407
- package/css/demo.css +0 -187
- package/demo-markdown.html +0 -62
- package/demo.html +0 -391
- package/img/1.jpg +0 -0
- package/img/2.jpg +0 -0
- package/img/3.jpg +0 -0
- package/img/4.jpg +0 -0
- package/img/5.jpg +0 -0
- package/markdown.md +0 -156
- package/plugin/appearance/plugin-src.js +0 -451
- package/screenshot.png +0 -0
package/markdown.md
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
# Appearance <!-- .element: class="animate__flipInX slow" -->
|
|
2
|
-
### for Reveal.js <!-- .element: class="animate__flipInX slow" -->
|
|
3
|
-
|
|
4
|
-
Using Markdown <!-- .element: class="animate__flipInX slow" -->
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Why?
|
|
9
|
-
|
|
10
|
-
----
|
|
11
|
-
|
|
12
|
-
In Powerpoint you can make slides with items that appear automatically and sequentially with effects. Appearance is a plugin for Reveal.js that does the same.
|
|
13
|
-
|
|
14
|
-
Appearance is easy to set up. It uses [Animate.css](https://animate.style) by Daniel Eden for the animations, with some changes to allow for a non-animated state.
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## Examples
|
|
19
|
-
Let's check out what Appearance does:
|
|
20
|
-
|
|
21
|
-
----
|
|
22
|
-
|
|
23
|
-
## Let text appear
|
|
24
|
-
|
|
25
|
-
* Add it to any text element <!-- .element: class="animate__bounceInLeft" -->
|
|
26
|
-
* Like list items, or headers. <!-- .element: class="animate__bounceInLeft" -->
|
|
27
|
-
* It adds some impact. <!-- .element: class="animate__bounceInLeft" -->
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
```html []
|
|
31
|
-
* Add it to any text element <!-- .element: class="animate__bounceInLeft" -->
|
|
32
|
-
* Like list items, or headers. <!-- .element: class="animate__bounceInLeft" -->
|
|
33
|
-
* It adds some impact. <!-- .element: class="animate__bounceInLeft" -->
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
----
|
|
37
|
-
|
|
38
|
-
## Let images appear
|
|
39
|
-
|
|
40
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
41
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
42
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
43
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
44
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
45
|
-
|
|
46
|
-
```html []
|
|
47
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
48
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
49
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
50
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
51
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
----
|
|
55
|
-
|
|
56
|
-
## Inside fragments
|
|
57
|
-
|
|
58
|
-
Like this *(click next)<!-- .element: class="animate__fadeInDown animate__faster" -->*:
|
|
59
|
-
<!-- .element: class="animate__fadeInDown" -->
|
|
60
|
-
|
|
61
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
62
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
63
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
64
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
65
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
66
|
-
<!-- .element: class="fragment" -->
|
|
67
|
-
|
|
68
|
-
```html []
|
|
69
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
70
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
71
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
72
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
73
|
-
 <!-- .element: class="animate__flipInX demoimg" -->
|
|
74
|
-
<!-- .element: class="fragment" -->
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## Auto-appear
|
|
80
|
-
You can simplify the addition of animation classes:
|
|
81
|
-
|
|
82
|
-
----
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
Sometimes (for example with Markdown), adding classes to elements is a chore.
|
|
86
|
-
|
|
87
|
-
Appearance can automatically add animation classes to specific elements (tags or other selectors) in the presentation (with the option `autoappear`) or per slide (with `data-autoappear`).
|
|
88
|
-
|
|
89
|
-
----
|
|
90
|
-
|
|
91
|
-
### Global auto-appear mode
|
|
92
|
-
* This is list item 1
|
|
93
|
-
* This is list item 2
|
|
94
|
-
|
|
95
|
-
```html []
|
|
96
|
-
### Global auto-appear mode
|
|
97
|
-
* This is list item 1
|
|
98
|
-
* This is list item 2
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
```html []
|
|
102
|
-
<script>
|
|
103
|
-
//...
|
|
104
|
-
appearance: {
|
|
105
|
-
autoappear: true,
|
|
106
|
-
autoelements: {'ul li': 'animate__fadeInLeft'}
|
|
107
|
-
},
|
|
108
|
-
plugins: [ RevealMarkdown, Appearance ]
|
|
109
|
-
</script>
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
This shows how to globally set elements to appear.<!-- .element: class="small" -->
|
|
113
|
-
|
|
114
|
-
----
|
|
115
|
-
|
|
116
|
-
### Local auto-appear
|
|
117
|
-
<!-- .slide: data-autoappear="true" -->
|
|
118
|
-
* This is list item 1
|
|
119
|
-
* This is list item 2
|
|
120
|
-
|
|
121
|
-
```html []
|
|
122
|
-
<!-- .slide: data-autoappear="true" -->
|
|
123
|
-
### Local auto-appear
|
|
124
|
-
* This is list item 1
|
|
125
|
-
* This is list item 2
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
```html []
|
|
129
|
-
<script>
|
|
130
|
-
//...
|
|
131
|
-
appearance: {
|
|
132
|
-
autoappear: false,
|
|
133
|
-
autoelements: {'ul li': 'animate__fadeInLeft'}
|
|
134
|
-
},
|
|
135
|
-
plugins: [ RevealMarkdown, Appearance ]
|
|
136
|
-
</script>
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
Local auto-appear uses a data-attribute per slide.<!-- .element: class="small" -->
|
|
140
|
-
|
|
141
|
-
----
|
|
142
|
-
|
|
143
|
-
<!-- .slide: data-autoappear="{'ul li':'animate__fadeInRight','h3':['animate__fadeInDown, animate__slow','100ms']}" -->
|
|
144
|
-
### Local auto-appear, specified
|
|
145
|
-
|
|
146
|
-
You can also add a JSON object to the slide’s auto-appear data-attribute, with specific elements, their animations class/classes and optional delay.<!-- .element: class="small" -->
|
|
147
|
-
|
|
148
|
-
* This is list item 1
|
|
149
|
-
* This is list item 2
|
|
150
|
-
|
|
151
|
-
```html []
|
|
152
|
-
<!-- .slide: data-autoappear="{'ul li':'animate__fadeInRight','h3':['animate__fadeInDown, animate__slow','100ms']}" -->
|
|
153
|
-
### Local auto-appear, specified
|
|
154
|
-
* This is list item 1
|
|
155
|
-
* This is list item 2
|
|
156
|
-
```
|
|
@@ -1,451 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const Plugin = () => {
|
|
3
|
-
|
|
4
|
-
// Scope support polyfill
|
|
5
|
-
try{document.querySelector(":scope *")}catch(t){!function(t){let e=/:scope(?![\w-])/gi,r=u(t.querySelector);t.querySelector=function(t){return r.apply(this,arguments)};let c=u(t.querySelectorAll);if(t.querySelectorAll=function(t){return c.apply(this,arguments)},t.matches){let n=u(t.matches);t.matches=function(t){return n.apply(this,arguments)}}if(t.closest){let o=u(t.closest);t.closest=function(t){return o.apply(this,arguments)}}function u(t){return function(r){if(r&&e.test(r)){let c="q"+Math.floor(9e6*Math.random())+1e6;arguments[0]=r.replace(e,"["+c+"]"),this.setAttribute(c,"");let n=t.apply(this,arguments);return this.removeAttribute(c),n}return t.apply(this,arguments)}}}(Element.prototype)}
|
|
6
|
-
|
|
7
|
-
const loadStyle = function(url, type, callback) {
|
|
8
|
-
let head = document.querySelector('head');
|
|
9
|
-
let style;
|
|
10
|
-
style = document.createElement('link');
|
|
11
|
-
style.rel = 'stylesheet';
|
|
12
|
-
style.href = url;
|
|
13
|
-
|
|
14
|
-
let finish = function () {
|
|
15
|
-
if (typeof callback === 'function') {
|
|
16
|
-
callback.call();
|
|
17
|
-
callback = null;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
style.onload = finish;
|
|
22
|
-
|
|
23
|
-
style.onreadystatechange = function () {
|
|
24
|
-
if (this.readyState === 'loaded') {
|
|
25
|
-
finish();
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
head.appendChild(style);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const isJSON = str => {
|
|
32
|
-
try {
|
|
33
|
-
return (JSON.parse(str) && !!str);
|
|
34
|
-
} catch (e) {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const isObj = (test) => {
|
|
40
|
-
while ( Object.prototype.toString.call(test) === '[object Object]')
|
|
41
|
-
if ((test = Object.getPrototypeOf(test)) === null)
|
|
42
|
-
return true
|
|
43
|
-
return false
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const selectionArray = function (container, selectors) {
|
|
47
|
-
let selections = container.querySelectorAll(selectors);
|
|
48
|
-
let selectionarray = Array.prototype.slice.call(selections);
|
|
49
|
-
return selectionarray;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const isStack = function (section) {
|
|
53
|
-
let isStack = false;
|
|
54
|
-
for (let i = 0; i < section.childNodes.length; i++) {
|
|
55
|
-
if (section.childNodes[i].tagName == "SECTION") {
|
|
56
|
-
isStack = true
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return isStack;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
function copyDataAttributes(source, target, not) {
|
|
64
|
-
[...source.attributes].filter( attr => attr.nodeName.indexOf('data') > -1).forEach( attr => {
|
|
65
|
-
if ((not && attr.nodeName !== not) || !not) {
|
|
66
|
-
target.setAttribute(attr.nodeName, attr.nodeValue)
|
|
67
|
-
}
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const appear = function (deck, options) {
|
|
73
|
-
|
|
74
|
-
let baseclass = 'animate__animated';
|
|
75
|
-
let viewport = (deck.getRevealElement()).tagName == "BODY" ? document : deck.getRevealElement();
|
|
76
|
-
let appearanceSelector = options.compatibility ? `.${options.compatibilitybaseclass}` : `.${baseclass}`;
|
|
77
|
-
let fragmentSelector = ".fragment";
|
|
78
|
-
|
|
79
|
-
let speedClasses = ['slower', 'slow', 'fast', 'faster'];
|
|
80
|
-
speedClasses.push(...speedClasses.map(speed => `animate__${speed}`));
|
|
81
|
-
|
|
82
|
-
const generator = document.querySelector('[name=generator]');
|
|
83
|
-
|
|
84
|
-
const sections = selectionArray(viewport, "section");
|
|
85
|
-
const regularSections = sections.filter( section => !isStack(section) && section.dataset.visibility != "hidden");
|
|
86
|
-
|
|
87
|
-
const fragments = deck.getRevealElement().querySelectorAll(fragmentSelector);
|
|
88
|
-
let animatecss = '[class^="animate__"],[class*=" animate__"]'
|
|
89
|
-
|
|
90
|
-
const debugLog = function(text) {
|
|
91
|
-
if (options.debug) console.log(text);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const assignAutoClass = (section, str, kind) => {
|
|
95
|
-
|
|
96
|
-
let index = [...section.parentElement.children].filter(s => s.tagName=="SECTION").indexOf(section) + 1;
|
|
97
|
-
|
|
98
|
-
let warning = kind == 'global' ? `JSON Parse error, please try to correct the global "autoelements" option.` : `JSON Parse error, please try to correct the "data-autoappear" attribute on section ${index}`;
|
|
99
|
-
|
|
100
|
-
if (typeof str === "string") str = str.replace(/[“”]/g,'"').replace(/[‘’]/g,"'");
|
|
101
|
-
|
|
102
|
-
let strJSON = isJSON(str) ? str : typeof str === "object" ? JSON.stringify(str, null, 2) : str.trim().replace(/'/g, '"').charAt(0) === "{" ? str.trim().replace(/'/g, '"') : `{${str.trim().replace(/'/g, '"')}}`;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (!isJSON(strJSON)) {
|
|
106
|
-
console.log(warning);
|
|
107
|
-
} else {
|
|
108
|
-
let elementsToAnimate = JSON.parse(strJSON);
|
|
109
|
-
|
|
110
|
-
for (const [element, assignables] of Object.entries(elementsToAnimate)) {
|
|
111
|
-
|
|
112
|
-
let elementsInSection = section.querySelectorAll(element);
|
|
113
|
-
|
|
114
|
-
elementsInSection.forEach(elementInSection => {
|
|
115
|
-
|
|
116
|
-
if (!elementInSection.classList.contains(baseclass) || elementInSection.dataset["autoappear"]) {
|
|
117
|
-
|
|
118
|
-
elementInSection.dataset["autoappear"] = true;
|
|
119
|
-
|
|
120
|
-
let newClasses = [], newDelay = null, speedClass = false;
|
|
121
|
-
|
|
122
|
-
if (Array.isArray(assignables)) {
|
|
123
|
-
newClasses = assignables[0].split(/[ ,]+/);
|
|
124
|
-
newDelay = assignables[1];
|
|
125
|
-
} else if (typeof assignables == "string"){
|
|
126
|
-
newClasses = assignables.split(/[ ,]+/);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
speedClasses.forEach(speed => {
|
|
130
|
-
if (elementInSection.classList.contains(speed)) {
|
|
131
|
-
speedClass = speed;
|
|
132
|
-
}
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
let classesToRemove = [];
|
|
136
|
-
elementInSection.classList.forEach(currentClass => {
|
|
137
|
-
if (String(currentClass).includes("animate__")) {
|
|
138
|
-
classesToRemove.push(currentClass);
|
|
139
|
-
}
|
|
140
|
-
})
|
|
141
|
-
classesToRemove.forEach(currentClass => {elementInSection.classList.remove(currentClass)});
|
|
142
|
-
|
|
143
|
-
newClasses.forEach(newClass => {
|
|
144
|
-
if (speedClasses.includes(newClass)) {
|
|
145
|
-
// There is a speed class from JSON to be assigned
|
|
146
|
-
if (speedClass) { speedClass = newClass }
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
newClasses.forEach(newClass => {
|
|
151
|
-
elementInSection.classList.add(newClass);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
if (speedClass) {
|
|
155
|
-
elementInSection.classList.add(speedClass);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (newDelay) {
|
|
162
|
-
elementInSection.dataset.delay = newDelay;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
elementInSection.classList.add(baseclass);
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
const findAppearancesIn = function (container, includeClass, excludeClass) {
|
|
176
|
-
if (!isStack(container)) {
|
|
177
|
-
let appearances = selectionArray(container, `:scope ${includeClass}`);
|
|
178
|
-
|
|
179
|
-
appearances.forEach(appearance => {
|
|
180
|
-
|
|
181
|
-
let convertListItem = (appearance) => {
|
|
182
|
-
let from = appearance, to = appearance.parentNode;
|
|
183
|
-
if (!to) return
|
|
184
|
-
for (let sibling of to.children) {
|
|
185
|
-
if (sibling !== appearance) { if (sibling.dataset.appearParent) return }
|
|
186
|
-
}
|
|
187
|
-
to.classList = from.classList;
|
|
188
|
-
copyDataAttributes(from, to, "data-appear-parent");
|
|
189
|
-
to.innerHTML = from.innerHTML;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Conversion of list items with Appearance classes to the parent, needs manual attribute
|
|
193
|
-
// Relates to Quarto wrapping list content in a span.
|
|
194
|
-
if (appearance.hasAttribute("data-appear-parent")) {
|
|
195
|
-
convertListItem(appearance);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Automatic conversion of list items which directly contain spans.
|
|
199
|
-
// Relates to Quarto wrapping list content in a span.
|
|
200
|
-
if (options.appearparents) {
|
|
201
|
-
if (appearance.parentNode && appearance.parentNode.tagName) {
|
|
202
|
-
if (appearance.tagName == "SPAN" && appearance.parentNode.tagName == "LI") {
|
|
203
|
-
let spanLength = String(appearance.outerHTML).length;
|
|
204
|
-
let liContentLength = String(appearance.parentNode.innerHTML).length;
|
|
205
|
-
if (spanLength == liContentLength) {
|
|
206
|
-
convertListItem(appearance);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
appearances = selectionArray(container, `:scope ${includeClass}`);
|
|
216
|
-
let excludes = selectionArray(container, `:scope ${excludeClass} ${includeClass}`);
|
|
217
|
-
let delay = 0;
|
|
218
|
-
|
|
219
|
-
appearances.filter(function (appearance, index) {
|
|
220
|
-
if ( !(excludes.indexOf(appearance) > -1 ) ) {
|
|
221
|
-
if ((index == 0 && appearance.dataset.delay) || index !=0) {
|
|
222
|
-
|
|
223
|
-
let elementDelay = options.delay;
|
|
224
|
-
if (appearance.dataset && appearance.dataset.delay) {
|
|
225
|
-
elementDelay = parseInt(appearance.dataset.delay);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
delay = delay + elementDelay;
|
|
229
|
-
|
|
230
|
-
// Allow fragments to be Appearance items
|
|
231
|
-
if (appearance.classList.contains("fragment")) {
|
|
232
|
-
delay = 0;
|
|
233
|
-
if (appearance.querySelectorAll(`.${baseclass}`)) {
|
|
234
|
-
let firstNestedAppearance = appearance.querySelectorAll(`.${baseclass}`)[0];
|
|
235
|
-
|
|
236
|
-
if (firstNestedAppearance) {
|
|
237
|
-
let elementDelay = options.delay;
|
|
238
|
-
if (firstNestedAppearance.dataset && firstNestedAppearance.dataset.delay) {
|
|
239
|
-
elementDelay = parseInt(firstNestedAppearance.dataset.delay);
|
|
240
|
-
}
|
|
241
|
-
firstNestedAppearance.dataset.delay = elementDelay
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
appearance.style.setProperty('animation-delay', delay + "ms");
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
})
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const autoAdd = function () {
|
|
253
|
-
|
|
254
|
-
regularSections.forEach(section => {
|
|
255
|
-
|
|
256
|
-
if (section.hasAttribute("data-autoappear")) {
|
|
257
|
-
|
|
258
|
-
let sectDataAppear = section.dataset.autoappear;
|
|
259
|
-
|
|
260
|
-
if (sectDataAppear == "auto" || sectDataAppear == "" || sectDataAppear.length < 1 || sectDataAppear == "true") {
|
|
261
|
-
// This section should get the global autoappear classes on its objects
|
|
262
|
-
if (options.autoelements) {
|
|
263
|
-
if (!options.autoelements) {
|
|
264
|
-
return console.log(`Please add some elements in the option "autoelements"`);
|
|
265
|
-
}
|
|
266
|
-
assignAutoClass(section, options.autoelements, 'global')
|
|
267
|
-
}
|
|
268
|
-
} else if (sectDataAppear.length > 0) {
|
|
269
|
-
// This section should get the local data-autoappear classes on its objects
|
|
270
|
-
assignAutoClass(section, sectDataAppear, 'local');
|
|
271
|
-
//section.removeAttribute("data-autoappear");
|
|
272
|
-
}
|
|
273
|
-
} else {
|
|
274
|
-
|
|
275
|
-
if (options.autoappear) {
|
|
276
|
-
if (!options.autoelements) {
|
|
277
|
-
return console.log(`Please add some elements in the option "autoelements"`);
|
|
278
|
-
}
|
|
279
|
-
// This section should get the global autoappear classes on its objects
|
|
280
|
-
assignAutoClass(section, options.autoelements, 'global')
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
if (options.compatibility) {
|
|
288
|
-
animatecss = '.backInDown, .backInLeft, .backInRight, .backInUp, .bounceIn, .bounceInDown, .bounceInLeft, .bounceInRight, .bounceInUp, .fadeIn, .fadeInDown, .fadeInDownBig, .fadeInLeft, .fadeInLeftBig, .fadeInRight, .fadeInRightBig, .fadeInUp, .fadeInUpBig, .fadeInTopLeft, .fadeInTopRight, .fadeInBottomLeft, .fadeInBottomRight, .flipInX, .flipInY, .lightSpeedInRight, .lightSpeedInLeft, .rotateIn, .rotateInDownLeft, .rotateInDownRight, .rotateInUpLeft, .rotateInUpRight, .jackInTheBox, .rollIn, .zoomIn, .zoomInDown, .zoomInLeft, .zoomInRight, .zoomInUp, .slideInDown, .slideInLeft, .slideInRight, .slideInUp, .skidLeft, .skidLeftBig, .skidRight, .skidRightBig, .shrinkIn, .shrinkInBlur';
|
|
289
|
-
baseclass = options.compatibilitybaseclass
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
let allappearances = deck.getRevealElement().querySelectorAll(animatecss);
|
|
295
|
-
|
|
296
|
-
allappearances.forEach(appearance => {
|
|
297
|
-
if (!appearance.classList.contains(baseclass)) {
|
|
298
|
-
appearance.classList.add(baseclass);
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
autoAdd();
|
|
303
|
-
|
|
304
|
-
sections.forEach(section => {
|
|
305
|
-
findAppearancesIn(section, appearanceSelector, fragmentSelector);
|
|
306
|
-
})
|
|
307
|
-
|
|
308
|
-
fragments.forEach(fragment => {
|
|
309
|
-
findAppearancesIn(fragment, appearanceSelector, fragmentSelector);
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
const fromTo = function (event) {
|
|
313
|
-
let slides = {}
|
|
314
|
-
slides.from = event.fromSlide ? event.fromSlide : event.previousSlide ? event.previousSlide : null;
|
|
315
|
-
slides.to = event.toSlide ? event.toSlide : event.currentSlide ? event.currentSlide : null;
|
|
316
|
-
return slides
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const showHideSlide = function(event) {
|
|
320
|
-
|
|
321
|
-
let etype = event.type;
|
|
322
|
-
let slides = fromTo(event);
|
|
323
|
-
debugLog(etype);
|
|
324
|
-
|
|
325
|
-
if (slides.to?.dataset.appearevent == "auto") {slides.to.dataset.appearevent = "autoanimate"}
|
|
326
|
-
if (options.appearevent == "auto") {options.appearevent = "autoanimate"}
|
|
327
|
-
|
|
328
|
-
if (etype == "ready") {
|
|
329
|
-
slides.to.dataset.appearanceCanStart = true;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
if (slides.to) {
|
|
333
|
-
|
|
334
|
-
let appearevent = slides.to.dataset.appearevent ? slides.to.dataset.appearevent : options.appearevent;
|
|
335
|
-
|
|
336
|
-
if (etype == appearevent || (etype == "slidetransitionend" && appearevent == "autoanimate")) {
|
|
337
|
-
slides.to.dataset.appearanceCanStart = true;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
if (etype == "slidetransitionend") {
|
|
341
|
-
if (options.hideagain) {
|
|
342
|
-
if (slides.from) {
|
|
343
|
-
if (slides.from.dataset.appearanceCanStart) {
|
|
344
|
-
delete slides.from.dataset.appearanceCanStart;
|
|
345
|
-
}
|
|
346
|
-
let fromFragments = slides.from.querySelectorAll(`.fragment.visible`);
|
|
347
|
-
if (fromFragments) {
|
|
348
|
-
fromFragments.forEach(fragment => {
|
|
349
|
-
fragment.classList.remove('visible');
|
|
350
|
-
})
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
if (event.type == 'slidechanged' && document.body.dataset.exitoverview) {
|
|
357
|
-
if (options.hideagain) {
|
|
358
|
-
delete slides.from?.dataset.appearanceCanStart;
|
|
359
|
-
}
|
|
360
|
-
slides.to.dataset.appearanceCanStart = true;
|
|
361
|
-
|
|
362
|
-
} else if (event.type == 'overviewhidden' ) {
|
|
363
|
-
|
|
364
|
-
document.body.dataset.exitoverview = true;
|
|
365
|
-
|
|
366
|
-
setTimeout(function () {
|
|
367
|
-
document.body.removeAttribute('data-exitoverview')
|
|
368
|
-
}, 500)
|
|
369
|
-
|
|
370
|
-
if (event.currentSlide ) {
|
|
371
|
-
if (options.hideagain) {
|
|
372
|
-
delete slides.from?.dataset.appearanceCanStart;
|
|
373
|
-
}
|
|
374
|
-
slides.to.dataset.appearanceCanStart = true;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
const eventnames = ['ready', 'slidechanged', 'slidetransitionend', 'autoanimate', 'overviewhidden'];
|
|
381
|
-
eventnames.forEach( (eventname) => deck.on( eventname, event => { showHideSlide(event) } ) )
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
const init = function (deck) {
|
|
385
|
-
|
|
386
|
-
let es5Filename = "appearance.js"
|
|
387
|
-
|
|
388
|
-
let defaultOptions = {
|
|
389
|
-
baseclass: 'animate__animated',
|
|
390
|
-
hideagain: true,
|
|
391
|
-
delay: 300,
|
|
392
|
-
debug: false,
|
|
393
|
-
appearevent: 'slidetransitionend',
|
|
394
|
-
autoappear: false,
|
|
395
|
-
autoelements: false,
|
|
396
|
-
appearparents: false,
|
|
397
|
-
csspath: '',
|
|
398
|
-
animatecsspath: {
|
|
399
|
-
link : 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css',
|
|
400
|
-
compat : 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.compat.css',
|
|
401
|
-
},
|
|
402
|
-
compatibility: false,
|
|
403
|
-
compatibilitybaseclass: 'animated'
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
const defaults = function (options, defaultOptions) {
|
|
407
|
-
for ( let i in defaultOptions ) {
|
|
408
|
-
if ( !options.hasOwnProperty( i ) ) {
|
|
409
|
-
options[i] = defaultOptions[i];
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
let options = deck.getConfig().appearance || {};
|
|
415
|
-
defaults(options, defaultOptions);
|
|
416
|
-
|
|
417
|
-
function pluginPath() {
|
|
418
|
-
let path;
|
|
419
|
-
let pluginScript = document.querySelector(`script[src$="${es5Filename}"]`);
|
|
420
|
-
if (pluginScript) {
|
|
421
|
-
path = pluginScript.getAttribute("src").slice(0, -1 * (es5Filename.length));
|
|
422
|
-
} else {
|
|
423
|
-
path = import.meta.url.slice(0, import.meta.url.lastIndexOf('/') + 1);
|
|
424
|
-
}
|
|
425
|
-
return path;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
let AppearanceStylePath = options.csspath.appearance ? options.csspath.appearance : null || `${pluginPath()}appearance.css` || 'plugin/appearance/appearance.css'
|
|
429
|
-
let AnimateCSSPath = !options.compatibility ? options.animatecsspath.link : options.animatecsspath.compat;
|
|
430
|
-
|
|
431
|
-
if (options.debug) {
|
|
432
|
-
console.log(`Plugin path = ${pluginPath()}`);
|
|
433
|
-
console.log(`Compatibility mode: ${options.compatibility}`)
|
|
434
|
-
console.log(`Appearance CSS path = ${AppearanceStylePath}`);
|
|
435
|
-
console.log(`AnimateCSS CSS path = ${AnimateCSSPath}`);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
loadStyle(AnimateCSSPath, 'stylesheet', function () {
|
|
439
|
-
loadStyle(AppearanceStylePath, 'stylesheet');
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
appear(deck, options);
|
|
443
|
-
};
|
|
444
|
-
|
|
445
|
-
return {
|
|
446
|
-
id: 'appearance',
|
|
447
|
-
init: init
|
|
448
|
-
};
|
|
449
|
-
};
|
|
450
|
-
|
|
451
|
-
export default Plugin;
|
package/screenshot.png
DELETED
|
Binary file
|