forked from observablehq/plot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add examples grid (observablehq#1834)
- Loading branch information
1 parent
1676a64
commit 900412d
Showing
5 changed files
with
206 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
<script setup> | ||
import * as d3 from "d3"; | ||
import {ref, shallowRef, onMounted, onUnmounted} from "vue"; | ||
import {data} from "./gallery.data.js"; | ||
let observer; | ||
let pointerframe; | ||
let clientX; | ||
const n = 60; // maximum number of examples to show | ||
const slice = d3.shuffler(d3.randomLcg(d3.utcDay()))(data.slice()).slice(0, n); | ||
const sample = shallowRef(slice.slice(0, 55)); // initial guess | ||
const container = ref(); | ||
const xn = ref(10); // number of rows | ||
const yn = ref(5); // number of columns | ||
const x = ref(0.5); // normalized horizontal pointer position | ||
// Some browsers trigger pointermove more frequently than desirable, so we | ||
// debounce events for a smooth transitions. | ||
function onpointermove(event) { | ||
if (!pointerframe) pointerframe = requestAnimationFrame(afterpointermove); | ||
clientX = event.clientX; | ||
} | ||
function afterpointermove() { | ||
pointerframe = null; | ||
x.value = clientX / document.body.clientWidth; | ||
} | ||
onMounted(() => { | ||
observer = new ResizeObserver(() => { | ||
const w = parseFloat(getComputedStyle(container.value).getPropertyValue("--grid-width")); | ||
xn.value = Math.ceil(document.body.clientWidth / w) + 3; // overflow columns | ||
yn.value = Math.min(Math.round(640 / w + 2), Math.floor(n / xn.value)); // 640 is grid height | ||
sample.value = slice.slice(0, yn.value * xn.value); | ||
}); | ||
observer.observe(document.body); | ||
addEventListener("pointermove", onpointermove); | ||
}); | ||
onUnmounted(() => { | ||
observer.disconnect(); | ||
removeEventListener("pointermove", onpointermove); | ||
}); | ||
</script> | ||
|
||
<template> | ||
<div :class="$style.examples" ref="container" :style="`transform: translate(${60 - x * 10}vw, 33%);`"> | ||
<div v-for="(d, i) in sample" :style="`--delay: ${((i % xn) / xn + (d3.randomLcg(1 / i)()) - 0.4) * 1}s;`"> | ||
<a :href="`https://observablehq.com/${d.path}${d.path.includes('?') ? '&' : '?'}intent=fork`" :title="[d.title, d.author].filter(Boolean).join('\n')" target="_blank" :style="`--x: ${(i % xn) - xn / 2 + (Math.floor(i / xn) % 2) * 0.5}; --y: ${Math.floor(i / xn) - yn / 2};`"> | ||
<img :src="`https://static.observableusercontent.com/thumbnail/${d.thumbnail}.jpg`" width="640" height="400" /> | ||
</a> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<style module> | ||
.examples { | ||
position: relative; | ||
height: 640px; | ||
transition: transform 150ms ease-out; | ||
filter: drop-shadow(0 4px 8px rgba(0,0,0,0.2)); | ||
--grid-width: 140px; | ||
} | ||
@media (min-width: 640px) { | ||
.examples { | ||
--grid-width: 160px; | ||
} | ||
} | ||
@media (min-width: 960px) { | ||
.examples { | ||
--grid-width: 200px; | ||
} | ||
} | ||
/* The drop-shadow should not be affected by the hexagon clip-path. */ | ||
.examples div { | ||
position: relative; | ||
transition: filter 250ms ease-out; | ||
animation: fade-in 350ms cubic-bezier(0.215, 0.610, 0.355, 1.000) var(--delay) backwards; | ||
} | ||
.examples div:hover { | ||
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.4)); | ||
z-index: 3; | ||
} | ||
.examples a { | ||
position: absolute; | ||
--transform: perspective(75em) rotateX(30deg) rotateZ(-7deg) translate(calc(var(--x) * 100%), calc(var(--y) * 86.67%)) scale(1.145); | ||
transform: var(--transform); | ||
animation: drop-in 350ms cubic-bezier(0.215, 0.610, 0.355, 1.000) var(--delay) backwards; | ||
transition: transform 250ms ease-out; | ||
clip-path: polygon(50.0% 100.0%, 93.3% 75.0%, 93.3% 25.0%, 50.0% 0.0%, 6.7% 25.0%, 6.7% 75.0%); | ||
} | ||
.examples a:hover { | ||
transform: var(--transform) translateZ(10px) scale(1.1); | ||
} | ||
.examples img { | ||
aspect-ratio: 1; | ||
object-fit: cover; | ||
width: var(--grid-width); | ||
} | ||
@keyframes fade-in { | ||
from { | ||
filter: blur(20px); | ||
opacity: 0; | ||
} | ||
to { | ||
filter: none; | ||
opacity: 1; | ||
} | ||
} | ||
@keyframes drop-in { | ||
from { | ||
transform: var(--transform) translateY(-100px) translateZ(400px); | ||
} | ||
to { | ||
transform: var(--transform); | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import {Runtime} from "@observablehq/runtime"; | ||
|
||
export default { | ||
async load() { | ||
const runtime = new Runtime(); | ||
const module = runtime.module((await import("https://api.observablehq.com/@observablehq/plot-gallery.js?v=4")).default); | ||
const data = []; | ||
module.define("md", () => String.raw); | ||
module.redefine("previews", () => (chunk) => data.push(...chunk)); | ||
const values = []; | ||
for (const output of module._resolve("previews")._outputs) { | ||
if (output._name) { | ||
values.push(module.value(output._name)); | ||
} | ||
} | ||
await Promise.all(values); | ||
return data; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -521,6 +521,30 @@ | |
"@nodelib/fs.scandir" "2.1.5" | ||
fastq "^1.6.0" | ||
|
||
"@observablehq/inspector@^5.0.0": | ||
version "5.0.0" | ||
resolved "https://registry.yarnpkg.com/@observablehq/inspector/-/inspector-5.0.0.tgz#7dec08d4fa20dfb79977ce62f7cc4a814b44e595" | ||
integrity sha512-Vvg/TQdsZTUaeYbH0IKxYEz37FbRO6kdowoz2PrHLQif54NC1CjEihEjg+ZMSBn587GQxTFABu0CGkFZgtR1UQ== | ||
dependencies: | ||
isoformat "^0.2.0" | ||
|
||
"@observablehq/runtime@^5.7.3": | ||
version "5.9.1" | ||
resolved "https://registry.yarnpkg.com/@observablehq/runtime/-/runtime-5.9.1.tgz#fd79f9cce8a165e123021ca2f72fe54e61f16d12" | ||
integrity sha512-ACNFixkIFVihIaWrDGXxgjxVj4/cHx26kdfGDVpEX1mEVqgP1SnfQMoJyZoqG23txs+uUcyr8LG37NkMEsNpdw== | ||
dependencies: | ||
"@observablehq/inspector" "^5.0.0" | ||
"@observablehq/stdlib" "^5.0.0" | ||
|
||
"@observablehq/stdlib@^5.0.0": | ||
version "5.8.1" | ||
resolved "https://registry.yarnpkg.com/@observablehq/stdlib/-/stdlib-5.8.1.tgz#50002b0d2a021890052d6f96700d86d15ca18c7d" | ||
integrity sha512-ng6QQSzFbPQnMMeCUhUl/EPzpyrwfmGsujztGdPXS1ZYrLoAc9co4rhUC5Vv6dBh8E4yzZkxwNyTs73bLN4alQ== | ||
dependencies: | ||
d3-array "^3.2.0" | ||
d3-dsv "^3.0.1" | ||
d3-require "^1.3.0" | ||
|
||
"@one-ini/[email protected]": | ||
version "0.1.1" | ||
resolved "https://registry.yarnpkg.com/@one-ini/wasm/-/wasm-0.1.1.tgz#6013659736c9dbfccc96e8a9c2b3de317df39323" | ||
|
@@ -1434,7 +1458,7 @@ d3-delaunay@6: | |
d3-dispatch "1 - 3" | ||
d3-selection "3" | ||
|
||
"d3-dsv@1 - 3", d3-dsv@3: | ||
"d3-dsv@1 - 3", d3-dsv@3, d3-dsv@^3.0.1: | ||
version "3.0.1" | ||
resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-3.0.1.tgz#c63af978f4d6a0d084a52a673922be2160789b73" | ||
integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q== | ||
|
@@ -1517,6 +1541,11 @@ d3-random@3: | |
resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-3.0.1.tgz#d4926378d333d9c0bfd1e6fa0194d30aebaa20f4" | ||
integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ== | ||
|
||
d3-require@^1.3.0: | ||
version "1.3.0" | ||
resolved "https://registry.yarnpkg.com/d3-require/-/d3-require-1.3.0.tgz#2b97f5e2ebcb64ac0c63c11f30056aea1c74f0ec" | ||
integrity sha512-XaNc2azaAwXhGjmCMtxlD+AowpMfLimVsAoTMpqrvb8CWoA4QqyV12mc4Ue6KSoDvfuS831tsumfhDYxGd4FGA== | ||
|
||
d3-scale-chromatic@3: | ||
version "3.0.0" | ||
resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz#15b4ceb8ca2bb0dcb6d1a641ee03d59c3b62376a" | ||
|