Skip to content

Commit c3dfd13

Browse files
committed
Add fixes for sketch thumbnails and layouts
1 parent b368edc commit c3dfd13

25 files changed

Lines changed: 146 additions & 22 deletions

src/api/OpenProcessing.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,33 @@ export const getSketch = memoize(async (
8181
return payload as OpenProcessingSketchResponse;
8282
});
8383

84+
export const getSketchSize = memoize(async (id: string) => {
85+
const sketch = await getSketch(id)
86+
if (sketch.mode !== 'p5js') {
87+
return { width: undefined, height: undefined };
88+
}
89+
90+
const response = await fetch(`${openProcessingEndpoint}sketch/${id}/code`);
91+
const payload = await response.json();
92+
93+
for (const tab of payload) {
94+
if (!tab.code) continue;
95+
const match = /createCanvas\(\s*(\w+),\s*(\w+)\s*(?:,\s*(?:P2D|WEBGL)\s*)?\)/m.exec(tab.code);
96+
if (match) {
97+
if (match[1] === 'windowWidth' && match[2] === 'windowHeight') {
98+
return { width: undefined, height: undefined };
99+
}
100+
101+
const width = parseFloat(match[1]);
102+
const height = parseFloat(match[2]);
103+
if (width && height) {
104+
return { width, height };
105+
}
106+
}
107+
}
108+
return { width: undefined, height: undefined };
109+
});
110+
84111
export const makeSketchLinkUrl = (id: string) =>
85112
`https://openprocessing.org/sketch/${id}`;
86113

@@ -90,6 +117,17 @@ export const makeSketchEmbedUrl = (id: string) =>
90117
export const makeThumbnailUrl = (id: string) =>
91118
`https://openprocessing-usercontent.s3.amazonaws.com/thumbnails/visualThumbnail${id}@2x.jpg`;
92119

120+
export const getSketchThumbnailSource = async (id: string) => {
121+
const manualThumbs = import.meta.glob<ImageMetadata>('../content/sketches/images/*', { import: 'default' })
122+
const key = `../content/sketches/images/${id}.png`;
123+
if (manualThumbs[key]) {
124+
const img = await manualThumbs[key]()
125+
return img;
126+
}
127+
128+
return makeThumbnailUrl(id)
129+
}
130+
93131
/**
94132
* The size of the thumbnails generated by OpenProcessing in px
95133
*/

src/components/GridItem/Sketch.astro

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
---
22
import Image from "@components/Image/index.astro";
33
import {
4-
makeThumbnailUrl,
4+
getSketchThumbnailSource,
55
thumbnailDimensions,
66
type OpenProcessingCurationResponse,
77
} from "@/src/api/OpenProcessing";
88
99
interface Props {
1010
item: OpenProcessingCurationResponse[number];
11+
scale?: number;
1112
lazyLoad?: boolean;
1213
}
1314
14-
const { item, lazyLoad } = Astro.props;
15+
const { item, lazyLoad, scale = 1 } = Astro.props;
16+
const imgSrc = await getSketchThumbnailSource(item.visualID)
17+
const width = Math.min(thumbnailDimensions * scale, 1500);
18+
const height = Math.min(
19+
(imgSrc.width && imgSrc.height ? imgSrc.height / imgSrc.width : 1) * thumbnailDimensions * scale,
20+
1000,
21+
);
1522
---
1623

1724
<a
@@ -24,10 +31,10 @@ const { item, lazyLoad } = Astro.props;
2431
// doesn't include that information
2532
}
2633
<Image
27-
src={makeThumbnailUrl(item.visualID)}
34+
src={imgSrc}
2835
alt="Screenshot of sketch"
29-
width={thumbnailDimensions}
30-
height={thumbnailDimensions}
36+
width={width}
37+
height={scale}
3138
loading={lazyLoad ? "lazy" : "eager"}
3239
/>
3340
<p

src/components/PageHeader/ItemPage.astro

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,20 @@ import { Icon } from "../Icon";
33
44
interface Props {
55
title: string;
6+
titleAuthor?: string
67
subtitle?: string;
78
topic: {
89
name: string;
910
url: string;
1011
};
1112
}
1213
13-
const { title, topic, subtitle } = Astro.props;
14+
const { title, topic, subtitle, titleAuthor } = Astro.props;
15+
let fullTitle = title;
16+
if (titleAuthor) {
17+
fullTitle += '\n';
18+
fullTitle += titleAuthor;
19+
}
1420
---
1521

1622
<div class="px-5 md:px-lg pt-5xl lg:pt-3xl pb-sm">
@@ -24,6 +30,6 @@ const { title, topic, subtitle } = Astro.props;
2430
>
2531
<span>{title}</span>
2632
</div>
27-
<h1 class="whitespace-pre-line my-sm">{title}</h1>
33+
<h1 class="whitespace-pre-line my-sm">{fullTitle}</h1>
2834
{subtitle && <p class="text-h3">{subtitle}</p>}
2935
</div>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { useLayoutEffect, useRef, useState } from "preact/hooks";
2+
3+
export const ScalingIframe = ({
4+
width,
5+
...props
6+
}: {
7+
width: number;
8+
[key: string]: any;
9+
}) => {
10+
const iframeRef = useRef<HTMLIFrameElement | null>(null);
11+
const [scale, setScale] = useState(1);
12+
useLayoutEffect(() => {
13+
const fitToParent = () => {
14+
const iframe = iframeRef.current;
15+
// Two parents up to get out of the astro island
16+
const parent = iframe?.parentElement?.parentElement;
17+
if (!iframe || !parent) return;
18+
19+
const parentWidth = parent.getBoundingClientRect().width;
20+
setScale(parentWidth / width);
21+
};
22+
fitToParent();
23+
window.addEventListener("resize", fitToParent);
24+
return () => window.removeEventListener("resize", fitToParent);
25+
}, [width]);
26+
27+
return (
28+
<iframe
29+
width={width}
30+
{...props}
31+
style={{ transform: `scale(${scale.toFixed(4)})`, transformOrigin: 'top left' }}
32+
ref={iframeRef}
33+
/>
34+
);
35+
};
3.13 MB
Loading
947 KB
Loading
679 KB
Loading
2.15 MB
Loading
104 KB
Loading
433 KB
Loading

0 commit comments

Comments
 (0)