mirror of
https://github.com/wassname/template.git
synced 2026-06-27 17:50:45 +08:00
First work on d-figure
This commit is contained in:
@@ -67,6 +67,30 @@
|
||||
print(a, end=' ')
|
||||
a, b = b, a+b
|
||||
</d-code>
|
||||
<d-figure id="last-figure"></d-figure>
|
||||
<script>
|
||||
const figure = document.querySelector("d-figure#last-figure");
|
||||
figure.addEventListener("init", function() {
|
||||
const initTag = document.createElement("span");
|
||||
initTag.textContent = "initialized!"
|
||||
figure.appendChild(initTag);
|
||||
});
|
||||
figure.addEventListener("almostonscreen", function() {
|
||||
const initTag = figure.querySelector("span");
|
||||
initTag.textContent = "almostonscreen"
|
||||
console.log('almostonscreen')
|
||||
});
|
||||
figure.addEventListener("onscreen", function() {
|
||||
const initTag = figure.querySelector("span");
|
||||
initTag.textContent = "onscreen"
|
||||
console.log('onscreen')
|
||||
});
|
||||
figure.addEventListener("offscreen", function() {
|
||||
const initTag = figure.querySelector("span");
|
||||
initTag.textContent = "offscreen!"
|
||||
console.log('offscreen')
|
||||
});
|
||||
</script>
|
||||
<p>That's it for the example article!</p>
|
||||
<aside>Some text.</aside>
|
||||
</d-article>
|
||||
|
||||
+2
-1
@@ -17,11 +17,12 @@ import { DMath } from './components/d-math';
|
||||
import { References } from './components/d-references';
|
||||
import { Title } from './components/d-title';
|
||||
import { TOC } from './components/d-toc';
|
||||
import { Figure } from './components/d-figure';
|
||||
|
||||
const components = [
|
||||
Abstract, Acknowledgements, Appendix, Article, Bibliography,
|
||||
Byline, Cite, Code, Footnote, FootnoteList, FrontMatter, DMath,
|
||||
References, Title, TOC,
|
||||
References, Title, TOC, Figure,
|
||||
];
|
||||
|
||||
/* Distill website specific components */
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
`Figure
|
||||
|
||||
d-figure provides a state-machine of visibility events:
|
||||
|
||||
scroll out of view
|
||||
+----------------+
|
||||
*do work here* | |
|
||||
+------+ +----------------+ +-+---------+ +-v---------+
|
||||
| init +----> almostonscreen +----> onscreen | | offscreen |
|
||||
+------+ +----------------+ +---------^-+ +---------+-+
|
||||
| |
|
||||
+----------------+
|
||||
scroll into view
|
||||
|
||||
TODO:
|
||||
* default styling
|
||||
* get rid of init state?
|
||||
* shadow dom?
|
||||
* resizing/default size?
|
||||
* offer centerscreen event?
|
||||
* polyfills
|
||||
|
||||
`
|
||||
|
||||
const intersectionMargin = 1000;
|
||||
|
||||
export class Figure extends HTMLElement {
|
||||
|
||||
static get is() { return 'd-figure'; }
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// keep track of communicated state
|
||||
this._init = false;
|
||||
this._onscreen = false;
|
||||
this._offscreen = true;
|
||||
|
||||
// we use two separate observers:
|
||||
// one with an extra 1000px margin to warn if the viewpoint gets close,
|
||||
// and one for the actual on/off screen events
|
||||
this._marginObserver = new IntersectionObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
if (entry.isIntersecting && !this._almostonscreen) {
|
||||
this.almostonscreen();
|
||||
this._marginObserver.disconnect();
|
||||
}
|
||||
}
|
||||
}, {
|
||||
root: null, // listen on entire viewport
|
||||
rootMargin: intersectionMargin + 'px 0px ' + intersectionMargin + 'px 0px',
|
||||
threshold: 1.0,
|
||||
});
|
||||
this._directObserver = new IntersectionObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
if (entry.isIntersecting) {
|
||||
if (!this._almostonscreen) { this.almostonscreen(); }
|
||||
if (this._offscreen) { this.onscreen(); }
|
||||
} else {
|
||||
if (this._onscreen) { this.offscreen(); }
|
||||
}
|
||||
}
|
||||
}, {
|
||||
root: null, // listen on entire viewport
|
||||
rootMargin: '0px',
|
||||
threshold: [0, 1.0],
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this._marginObserver.observe(this);
|
||||
this._directObserver.observe(this);
|
||||
this.init();
|
||||
}
|
||||
|
||||
|
||||
/* Override addEventListener
|
||||
* We want to notify elements that register late as well.
|
||||
*/
|
||||
|
||||
addEventListener(eventName, callback) {
|
||||
super.addEventListener(eventName, callback);
|
||||
// if we had already dispatched something while presumingly no one was listening, we do so again
|
||||
if (this._init && eventName === 'init') {
|
||||
this.init();
|
||||
}
|
||||
if (this._almostonscreen && eventName === 'almostonscreen') {
|
||||
this.almostonscreen();
|
||||
}
|
||||
if (this._onscreen && eventName === 'onscreen') {
|
||||
this.onscreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Custom Events */
|
||||
|
||||
init() {
|
||||
this._init = true;
|
||||
const event = new CustomEvent('init');
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
almostonscreen() {
|
||||
this._almostonscreen = true;
|
||||
const event = new CustomEvent('almostonscreen');
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
onscreen() {
|
||||
this._onscreen = true;
|
||||
this._offscreen = false;
|
||||
const event = new CustomEvent('onscreen');
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
offscreen() {
|
||||
this._onscreen = false;
|
||||
this._offscreen = true;
|
||||
const event = new CustomEvent('offscreen');
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user