From c703a9337b9d4d535c0b503f91684a2fbff89e93 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Tue, 6 Dec 2022 18:36:04 -0400 Subject: sticky cover art (a little wip) --- src/misc-templates.js | 31 ++++++-- src/page/album-commentary.js | 7 +- src/page/album.js | 11 ++- src/page/artist.js | 7 +- src/page/flash.js | 7 +- src/page/group.js | 7 +- src/page/listing.js | 5 +- src/page/news.js | 7 +- src/page/track.js | 11 ++- src/static/client.js | 21 +++++- src/static/site2.css | 167 +++++++++++++++++++++++++++++-------------- src/upd8.js | 5 +- 12 files changed, 202 insertions(+), 84 deletions(-) diff --git a/src/misc-templates.js b/src/misc-templates.js index 755ad64..10422a2 100644 --- a/src/misc-templates.js +++ b/src/misc-templates.js @@ -281,7 +281,7 @@ function unbound_generateCoverLink({ id: 'cover-art', link: true, square: true, - reveal: getRevealStringFromTags(tags, {language}), + reveal: getRevealStringFromTags(tags), }), wikiInfo.enableArtTagUI && @@ -722,14 +722,37 @@ function unbound_generateNavigationLinks(current, { // Sticky heading, ooooo -function unbound_generateStickyHeadingContainer(headingContent, { +function unbound_generateStickyHeadingContainer({ + getRevealStringFromTags, html, + img, + + coverSrc, + coverAlt, + coverTags, + title, }) { return html.tag('div', {class: 'content-sticky-heading-container'}, [ - html.tag('h1', headingContent), - html.tag('h2', {class: 'content-sticky-subheading'}), + html.tag('div', {class: 'content-sticky-heading-row'}, [ + html.tag('h1', title), + + coverSrc && + html.tag('div', {class: 'content-sticky-heading-cover-container'}, + html.tag('div', {class: 'content-sticky-heading-cover'}, + img({ + src: coverSrc, + alt: coverAlt, + thumb: 'small', + link: false, + square: true, + reveal: getRevealStringFromTags(coverTags), + }))), + ]), + + html.tag('div', {class: 'content-sticky-subheading-row'}, + html.tag('h2', {class: 'content-sticky-subheading'})), ]); } diff --git a/src/page/album-commentary.js b/src/page/album-commentary.js index 9004002..b67dab0 100644 --- a/src/page/album-commentary.js +++ b/src/page/album-commentary.js @@ -36,10 +36,11 @@ export function write(album) { main: { content: html.tag('div', {class: 'long-content'}, [ - generateStickyHeadingContainer( - language.$('albumCommentaryPage.title', { + generateStickyHeadingContainer({ + title: language.$('albumCommentaryPage.title', { album: link.album(album), - })), + }), + }), html.tag('p', language.$('albumCommentaryPage.infoLine', { diff --git a/src/page/album.js b/src/page/album.js index f2c35a1..834f52d 100644 --- a/src/page/album.js +++ b/src/page/album.js @@ -154,15 +154,20 @@ export function write(album, {wikiData}) { main: { content: [ + generateStickyHeadingContainer({ + title: language.$('albumPage.title', {album: album.name}), + + coverSrc: cover, + coverAlt: language.$('misc.alt.albumCover'), + coverTags: album.artTags, + }), + cover && generateCoverLink({ src: cover, alt: language.$('misc.alt.albumCover'), tags: album.artTags, }), - generateStickyHeadingContainer( - language.$('albumPage.title', {album: album.name})), - html.tag('p', { [html.onlyIfContent]: true, diff --git a/src/page/artist.js b/src/page/artist.js index b62b32b..235fe11 100644 --- a/src/page/artist.js +++ b/src/page/artist.js @@ -347,10 +347,11 @@ export function write(artist, {wikiData}) { alt: language.$('misc.alt.artistAvatar'), }), - generateStickyHeadingContainer( - language.$('artistPage.title', { + generateStickyHeadingContainer({ + title: language.$('artistPage.title', { artist: name, - })), + }), + }), ...html.fragment( contextNotes && [ diff --git a/src/page/flash.js b/src/page/flash.js index d968d00..8cffdcd 100644 --- a/src/page/flash.js +++ b/src/page/flash.js @@ -45,10 +45,11 @@ export function write(flash, {wikiData}) { alt: language.$('misc.alt.flashArt'), }), - generateStickyHeadingContainer( - language.$('flashPage.title', { + generateStickyHeadingContainer({ + title: language.$('flashPage.title', { flash: flash.name, - })), + }), + }), html.tag('p', language.$('releaseInfo.released', { diff --git a/src/page/group.js b/src/page/group.js index c4c376b..429097f 100644 --- a/src/page/group.js +++ b/src/page/group.js @@ -47,10 +47,11 @@ export function write(group, {wikiData}) { main: { content: [ - generateStickyHeadingContainer( - language.$('groupInfoPage.title', { + generateStickyHeadingContainer({ + title: language.$('groupInfoPage.title', { group: group.name - })), + }), + }), !empty(group.urls) && html.tag('p', diff --git a/src/page/listing.js b/src/page/listing.js index fc643b1..dce3852 100644 --- a/src/page/listing.js +++ b/src/page/listing.js @@ -46,8 +46,9 @@ export function write(listing, {wikiData}) { main: { content: [ - generateStickyHeadingContainer( - language.$(titleKey)), + generateStickyHeadingContainer({ + title: language.$(titleKey), + }), ...html.fragment( listing.html && diff --git a/src/page/news.js b/src/page/news.js index 78e25f4..5312371 100644 --- a/src/page/news.js +++ b/src/page/news.js @@ -25,10 +25,11 @@ export function write(entry, {wikiData}) { main: { content: html.tag('div', {class: 'long-content'}, [ - generateStickyHeadingContainer( - language.$('newsEntryPage.title', { + generateStickyHeadingContainer({ + title: language.$('newsEntryPage.title', { entry: entry.name, - })), + }), + }), html.tag('p', language.$('newsEntryPage.published', { diff --git a/src/page/track.js b/src/page/track.js index 09c472a..c283aa3 100644 --- a/src/page/track.js +++ b/src/page/track.js @@ -224,15 +224,20 @@ export function write(track, {wikiData}) { main: { content: [ + generateStickyHeadingContainer({ + title: language.$('trackPage.title', {track: track.name}), + + coverSrc: cover, + coverAlt: language.$('misc.alt.trackCover'), + coverTags: track.artTags, + }), + cover && generateCoverLink({ src: cover, alt: language.$('misc.alt.trackCover'), tags: track.artTags, }), - generateStickyHeadingContainer( - language.$('trackPage.title', {track: track.name})), - html.tag('p', { [html.onlyIfContent]: true, diff --git a/src/static/client.js b/src/static/client.js index ebe8604..dcb3922 100644 --- a/src/static/client.js +++ b/src/static/client.js @@ -449,14 +449,20 @@ if (localStorage.tryInfoCards) { const stickyHeadingInfo = Array.from(document.querySelectorAll('.content-sticky-heading-container')) .map(stickyContainer => { const {parentElement: contentContainer} = stickyContainer; - const stickySubheading = stickyContainer.querySelector('.content-sticky-subheading'); + const stickySubheadingRow = stickyContainer.querySelector('.content-sticky-subheading-row'); + const stickySubheading = stickySubheadingRow.querySelector('h2'); + const stickyCoverContainer = stickyContainer.querySelector('.content-sticky-heading-cover-container'); const contentHeadings = Array.from(contentContainer.querySelectorAll('.content-heading')); + const contentCover = contentContainer.querySelector('#cover-art-container'); return { contentContainer, + contentCover, contentHeadings, stickyContainer, + stickyCoverContainer, stickySubheading, + stickySubheadingRow, state: { displayedHeading: null, }, @@ -471,13 +477,22 @@ const topOfViewInside = (el, scroll = window.scrollY) => ( function updateStickyHeading() { for (const { contentContainer, + contentCover, contentHeadings, stickyContainer, + stickyCoverContainer, stickySubheading, + stickySubheadingRow, state, } of stickyHeadingInfo) { let closestHeading = null; + if (contentCover.getBoundingClientRect().bottom < 0) { + stickyCoverContainer.classList.add('visible'); + } else { + stickyCoverContainer.classList.remove('visible'); + } + if (topOfViewInside(contentContainer)) { if (stickySubheading.childNodes.length === 0) { //   to ensure correct basic line height @@ -517,9 +532,9 @@ function updateStickyHeading() { } } - stickySubheading.classList.add('visible'); + stickySubheadingRow.classList.add('visible'); } else { - stickySubheading.classList.remove('visible'); + stickySubheadingRow.classList.remove('visible'); } state.displayedHeading = closestHeading; diff --git a/src/static/site2.css b/src/static/site2.css index 05d6cce..3acd849 100644 --- a/src/static/site2.css +++ b/src/static/site2.css @@ -165,6 +165,7 @@ body::before { } #content { + position: relative; --content-padding: 20px; box-sizing: border-box; padding: var(--content-padding); @@ -188,16 +189,9 @@ body::before { margin: 5px 12%; } -#cover-art-container { - float: right; - width: 40%; - max-width: 400px; - margin: -5px 0 10px 10px; -} - /* Layout - Wide (most computers) */ -@media not all and (max-width: 900px) { +@media (min-width: 900px) { #secondary-nav:not(.no-hide) { display: none; } @@ -210,15 +204,40 @@ body::before { * if so desired. */ -@media not all and (min-width: 900px), (max-width: 800px) { - body { - background: blue !important; +@media (min-width: 600px) and (max-width: 899.98px) { +} + +/* Layout - Wide or Medium */ + +@media (min-width: 600px) { + .content-sticky-heading-container { + /* Safari doesn't always play nicely with position: sticky, + * this seems to fix images sometimes displaying above the + * position: absolute subheading (h2) child + * + * See also: https://stackoverflow.com/questions/50224855/ + */ + transform: translate3d(0, 0, 0); + z-index: 1; + } + + /* Cover art floats to the right. It's positioned in HTML beneath the + * heading, so pull it up a little to "float" on top. + */ + #cover-art-container { + float: right; + width: 40%; + max-width: 400px; + margin: -60px 0 10px 10px; + + position: relative; + z-index: 2; } } /* Layout - Medium or Thin */ -@media (max-width: 900px) { +@media (max-width: 899.98px) { .sidebar-column:not(.no-hide) { display: none; } @@ -255,8 +274,7 @@ body::before { } #cover-art-container { - float: none; - margin: 0 0 40px 0; + margin: 25px 0 5px 0; width: 100%; max-width: unset; } @@ -571,6 +589,9 @@ a:hover { #cover-art-container { font-size: 0.8em; +} + +#cover-art { box-shadow: 0 0 3px 3px rgba(0, 0, 0, 0.25); } @@ -1099,12 +1120,16 @@ img { top: 0; } -#content .content-sticky-heading-container h1, +.content-sticky-heading-container { + margin: calc(-1 * var(--content-padding)); + margin-bottom: calc(0.5 * var(--content-padding)); +} + +.content-sticky-heading-row, #content:not(.no-sticky-heading) > h1:first-of-type /* , .sidebar:not(.no-sticky-heading) h1:first-of-type */ { - margin: calc(-1 * var(--content-padding)); - margin-bottom: calc(0.5 * var(--content-padding)); + box-sizing: border-box; padding: calc(1.25 * var(--content-padding)) 20px @@ -1118,34 +1143,66 @@ img { backdrop-filter: blur(6px); } -#content .content-sticky-heading-container { - position: sticky; +.content-sticky-heading-row { + width: 100%; + margin: 0; +} + +.content-sticky-heading-row, +.content-sticky-subheading-row { + display: grid; + grid-template-areas: + "title cover"; + grid-template-columns: 1fr min(40%, 400px); +} + +.content-sticky-heading-row h1 { + margin: 0; +} + +.content-sticky-heading-cover-container { + position: relative; + height: 0; + margin: -15px 0px -5px -5px; +} + +.content-sticky-heading-cover { + position: absolute; top: 0; + width: 80px; + right: 10px; + box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.25); + transition: transform 0.35s, opacity 0.25s; +} - /* Safari doesn't always play nicely with position: sticky, - * this seems to fix images sometimes displaying above the - * position: absolute subheading (h2) child - * - * See also: https://stackoverflow.com/questions/50224855/ - */ - transform: translate3d(0, 0, 0); - z-index: 1; +.content-sticky-heading-cover-container:not(.visible) .content-sticky-heading-cover { + opacity: 0; + transform: translateX(40px); } -#content .content-sticky-heading-container h1 { - margin-bottom: 0; +.content-sticky-heading-cover .image-container { + border-width: 1px; + padding: 2px; } -#content .content-sticky-heading-container h2 { +.content-sticky-heading-cover img { + display: block; + width: 100%; + height: 100%; +} + +.content-sticky-heading-container { + position: sticky; + top: 0; +} + +.content-sticky-subheading-row { position: absolute; - margin: 0 calc(-1 * var(--content-padding)); width: 100%; + box-sizing: border-box; padding: 10px 40px 5px 20px; - - font-size: 0.9em; - font-weight: normal; - font-style: oblique; - color: #eee; + margin-top: 0; + z-index: -1; background: var(--bg-black-color); border-bottom: 1px dotted rgba(220, 220, 220, 0.4); @@ -1156,30 +1213,39 @@ img { transition: margin-top 0.35s, opacity 0.25s; } -#content .content-sticky-heading-container h2:not(.visible) { +.content-sticky-subheading-row h2 { + margin: 0; + + font-size: 0.9em; + font-weight: normal; + font-style: oblique; + color: #eee; +} + +.content-sticky-subheading-row:not(.visible) { margin-top: -20px; opacity: 0; } -#content .content-sticky-heading-container h2.visible { +.content-sticky-heading-container h2.visible { margin-top: 0; opacity: 1; } -#content:not(.no-sticky-heading) > h1:first-of-type { - z-index: 1; +.content-sticky-heading-row { box-shadow: inset 0 10px 10px -5px var(--shadow-color), 0 4px 4px rgba(0, 0, 0, 0.8); } -#content .content-sticky-heading-container h1 { +.content-sticky-heading-container h2.visible { box-shadow: inset 0 10px 10px -5px var(--shadow-color), 0 4px 4px rgba(0, 0, 0, 0.8); } -#content .content-sticky-heading-container h2.visible { +#content:not(.no-sticky-heading) > h1:first-of-type { + z-index: 1; box-shadow: inset 0 10px 10px -5px var(--shadow-color), 0 4px 4px rgba(0, 0, 0, 0.8); @@ -1191,17 +1257,6 @@ img { padding-left: 40%; } -#cover-art-container { - z-index: 2; - position: relative; -} - -.sidebar:not(.no-sticky-heading) h1:first-of-type { - box-shadow: - inset 0 8px 8px -6px var(--shadow-color), - 0 4px 4px rgba(0, 0, 0, 0.8); -} - #content, .sidebar { contain: paint; } @@ -1224,6 +1279,12 @@ img { .sidebar-multiple.sticky-column { align-self: flex-start; } + +.sidebar:not(.no-sticky-heading) h1:first-of-type { + box-shadow: + inset 0 8px 8px -6px var(--shadow-color), + 0 4px 4px rgba(0, 0, 0, 0.8); +} */ /* important easter egg mode */ diff --git a/src/upd8.js b/src/upd8.js index 518e5f1..bc574c6 100755 --- a/src/upd8.js +++ b/src/upd8.js @@ -151,7 +151,7 @@ import FileSizePreloader from './file-size-preloader.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const CACHEBUST = 12; +const CACHEBUST = 13; let COMMIT; try { @@ -2456,7 +2456,10 @@ async function main() { }); bound.generateStickyHeadingContainer = bindOpts(generateStickyHeadingContainer, { + [bindOpts.bindIndex]: 0, + getRevealStringFromTags: bound.getRevealStringFromTags, html, + img, }); bound.generateChronologyLinks = bindOpts(generateChronologyLinks, { -- cgit 1.3.0-6-gf8a5