move all sidenote logic to Sidenote component
This commit is contained in:
parent
4658511759
commit
3413b7ae7e
@ -2,53 +2,18 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { formatDate } from './datefmt.js';
|
||||
import { makeSlug } from '$lib/slug.js';
|
||||
|
||||
import Link from './Link.svelte';
|
||||
export { Link as a };
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export let title, date;
|
||||
|
||||
// deal with sidenote collisions
|
||||
function tileNotes() {
|
||||
const minNoteGap = 15;
|
||||
// let sidenotes = Array.from(document.getElementsByClassName('sidenote'));
|
||||
let notes = document.querySelectorAll('.sidenote');
|
||||
if (window.getComputedStyle(notes[0]).position === 'fixed') {
|
||||
// fixed position means we are in mobile territory, so
|
||||
// get rid of the overflow stuff and then exit
|
||||
for (let note of notes) {
|
||||
note.style.top = '';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let labels = document.querySelectorAll('label.counter');
|
||||
var prev = 0;
|
||||
for (var i=0; i < notes.length; i++) {
|
||||
let labelTop = labels[i].getBoundingClientRect().y + window.scrollY;
|
||||
let noteHeight = notes[i].getBoundingClientRect().height;
|
||||
if (labelTop < prev + minNoteGap) {
|
||||
// there is a collision
|
||||
notes[i].style.top = `${prev + minNoteGap}px`;
|
||||
prev = prev + minNoteGap + noteHeight;
|
||||
}
|
||||
else {
|
||||
// no collision
|
||||
notes[i].style.top = `${labelTop}px`;
|
||||
prev = labelTop + noteHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
tileNotes();
|
||||
window.addEventListener('resize', tileNotes);
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{title}</title>
|
||||
<link rel="stylesheet" href="/prism-dracula.css" />
|
||||
</svelte:head>
|
||||
|
||||
<div id="post">
|
||||
|
@ -87,12 +87,63 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
let id = Math.random().toString().slice(2);
|
||||
<script context="module">
|
||||
import { browser } from '$app/env';
|
||||
var sidenotes = {};
|
||||
|
||||
function tileNotes() {
|
||||
// find and fix collisions between sidenotes
|
||||
const minNoteGap = 15;
|
||||
var prevBottom = 0;
|
||||
Object.values(sidenotes).forEach(s => {
|
||||
if (window.getComputedStyle(s.note).position === 'fixed') {
|
||||
// fixed position means we are in mobile territory,
|
||||
// so get rid of the overflow stuff
|
||||
s.note.style.top = '';
|
||||
return;
|
||||
}
|
||||
|
||||
let labelTop = s.label.getBoundingClientRect().y + window.scrollY;
|
||||
let noteHeight = s.note.getBoundingClientRect().height;
|
||||
if (labelTop < prevBottom + minNoteGap) {
|
||||
// there is a collision
|
||||
s.note.style.top = `${prevBottom + minNoteGap}px`;
|
||||
prevBottom = prevBottom + minNoteGap + noteHeight;
|
||||
}
|
||||
else {
|
||||
// no collision, but these don't quite match otherwise
|
||||
s.note.style.top = `${labelTop}px`;
|
||||
prevBottom = labelTop + noteHeight;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (browser) {
|
||||
window.addEventListener('resize', tileNotes);
|
||||
}
|
||||
</script>
|
||||
|
||||
<label for={id} class="counter"></label>
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
const id = Math.random().toString().slice(2);
|
||||
sidenotes[id] = {mounted: false};
|
||||
let label;
|
||||
let note;
|
||||
|
||||
onMount(async () => {
|
||||
sidenotes[id] = {mounted: true, label, note};
|
||||
if (Object.values(sidenotes).every(n => n.mounted)) {
|
||||
// all sidenotes have been mounted, now we can fix the collisions
|
||||
tileNotes();
|
||||
}
|
||||
|
||||
return () => sidenotes[id].mounted = false;
|
||||
});
|
||||
</script>
|
||||
|
||||
<label bind:this={label} for={id} class="counter"></label>
|
||||
<input type="checkbox" class="sidenote-toggle" {id}/>
|
||||
<span class="sidenote">
|
||||
<span bind:this={note} class="sidenote">
|
||||
<slot></slot>
|
||||
</span>
|
Loading…
x
Reference in New Issue
Block a user