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 { onMount } from 'svelte';
|
||||||
import { formatDate } from './datefmt.js';
|
import { formatDate } from './datefmt.js';
|
||||||
import { makeSlug } from '$lib/slug.js';
|
import { makeSlug } from '$lib/slug.js';
|
||||||
|
|
||||||
import Link from './Link.svelte';
|
import Link from './Link.svelte';
|
||||||
export { Link as a };
|
export { Link as a };
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export let title, date;
|
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>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
|
<link rel="stylesheet" href="/prism-dracula.css" />
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div id="post">
|
<div id="post">
|
||||||
|
@ -87,12 +87,63 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script context="module">
|
||||||
let id = Math.random().toString().slice(2);
|
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>
|
</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}/>
|
<input type="checkbox" class="sidenote-toggle" {id}/>
|
||||||
<span class="sidenote">
|
<span bind:this={note} class="sidenote">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</span>
|
</span>
|
Loading…
x
Reference in New Issue
Block a user