Skip to content

Commit

Permalink
Improve images
Browse files Browse the repository at this point in the history
  • Loading branch information
Hamish Williams committed Apr 17, 2022
1 parent b8a10ec commit 8438d6f
Show file tree
Hide file tree
Showing 18 changed files with 6,797 additions and 5,764 deletions.
1 change: 1 addition & 0 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const decorators = [
<style>{tokenStyles}</style>
<div id="story-root" className="storyRoot">
<Story />
<div id="portal-root" />
</div>
</ThemeProvider>
);
Expand Down
12,234 changes: 6,604 additions & 5,630 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
"author": "Hamish Williams <hello@hamishw.com>",
"devDependencies": {
"@mapbox/rehype-prism": "^0.8.0",
"@storybook/addon-a11y": "^6.4.20",
"@storybook/addon-actions": "^6.4.20",
"@storybook/addon-controls": "^6.4.20",
"@storybook/addon-postcss": "^2.0.0",
"@storybook/addon-toolbars": "^6.4.20",
"@storybook/builder-webpack5": "^6.4.21",
"@storybook/manager-webpack5": "^6.4.21",
"@storybook/react": "^6.4.20",
"@storybook/addon-a11y": "^6.4.22",
"@storybook/addon-actions": "^6.4.22",
"@storybook/addon-controls": "^6.4.22",
"@storybook/addon-toolbars": "^6.4.22",
"@storybook/builder-webpack5": "^6.4.22",
"@storybook/manager-webpack5": "^6.4.22",
"@storybook/react": "^6.4.22",
"@svgr/webpack": "^6.2.1",
"esbuild": "^0.14.36",
"eslint": "^8.13.0",
Expand All @@ -37,8 +36,9 @@
"framer-motion": "^6.3.0",
"mdx-bundler": "^9.0.0",
"next": "^12.1.5",
"react-dom": "^18.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"storybook": "^6.4.22",
"three": "^0.139.2"
},
"scripts": {
Expand Down
6 changes: 3 additions & 3 deletions src/components/Carousel/Carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
WebGLRenderer,
sRGBEncoding,
} from 'three';
import { getImageFromSrcSet } from 'utils/image';
import { resolveSrcFromSrcSet } from 'utils/image';
import { cssProps } from 'utils/style';
import { cleanRenderer, cleanScene } from 'utils/three';
import styles from './Carousel.module.css';
Expand Down Expand Up @@ -99,7 +99,7 @@ export const Carousel = ({ width, height, images, placeholder, ...rest }) => {
const anisotropy = renderer.current.capabilities.getMaxAnisotropy();

const texturePromises = images.map(async image => {
const imageSrc = await getImageFromSrcSet(image);
const imageSrc = await resolveSrcFromSrcSet(image);
const imageTexture = await textureLoader.loadAsync(imageSrc);
await renderer.current.initTexture(imageTexture);
imageTexture.encoding = sRGBEncoding;
Expand Down Expand Up @@ -378,7 +378,7 @@ export const Carousel = ({ width, height, images, placeholder, ...rest }) => {
aria-hidden
className={styles.placeholder}
data-loaded={loaded && !!textures}
src={placeholder}
src={placeholder.src}
ref={placeholderRef}
alt=""
role="presentation"
Expand Down
6 changes: 3 additions & 3 deletions src/components/Carousel/Carousel.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ export const images = () => (
placeholder={placeholderImg}
images={[
{
src: 'https://source.unsplash.com/ANJHXftvvJ8/1280x720',
src: { src: 'https://source.unsplash.com/ANJHXftvvJ8/1280x720' },
alt: 'A neon sign with kanji',
},
{
src: 'https://source.unsplash.com/qEWEz-U5p8Q/1280x720',
src: { src: 'https://source.unsplash.com/qEWEz-U5p8Q/1280x720' },
alt: 'Tokyo at night',
},
{
src: 'https://source.unsplash.com/lx9RWIg1Rdg/1280x720',
src: { src: 'https://source.unsplash.com/lx9RWIg1Rdg/1280x720' },
alt: 'A rad cyberpunk dude',
},
]}
Expand Down
16 changes: 11 additions & 5 deletions src/components/Image/Image.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Icon } from 'components/Icon';
import { useTheme } from 'components/ThemeProvider';
import { useInViewport, usePrefersReducedMotion } from 'hooks';
import { Fragment, useCallback, useEffect, useRef, useState } from 'react';
import { resolveVideoSrcFromSrcSet } from 'utils/image';
import { resolveSrcFromSrcSet, srcSetToString } from 'utils/image';
import { classes, cssProps, numToMs } from 'utils/style';
import styles from './Image.module.css';

Expand All @@ -13,13 +13,15 @@ export const Image = ({
reveal,
delay = 0,
raised,
src,
src: baseSrc,
srcSet,
placeholder,
...rest
}) => {
const [loaded, setLoaded] = useState(false);
const { themeId } = useTheme();
const containerRef = useRef();
const src = baseSrc || srcSet?.[0];
const inViewport = useInViewport(containerRef, !getIsVideo(src));

const onLoad = useCallback(() => {
Expand All @@ -43,6 +45,7 @@ export const Image = ({
inViewport={inViewport}
reveal={reveal}
src={src}
srcSet={srcSet}
placeholder={placeholder}
{...rest}
/>
Expand All @@ -62,6 +65,7 @@ const ImageElements = ({
play = true,
restartOnPause,
reveal,
sizes,
...rest
}) => {
const prefersReducedMotion = usePrefersReducedMotion();
Expand All @@ -73,10 +77,11 @@ const ImageElements = ({
const videoRef = useRef();
const isVideo = getIsVideo(src);
const showFullRes = inViewport;
const srcSetString = srcSetToString(srcSet);

useEffect(() => {
const resolveVideoSrc = async () => {
const resolvedVideoSrc = await resolveVideoSrcFromSrcSet(srcSet);
const resolvedVideoSrc = await resolveSrcFromSrcSet({ srcSet, sizes });
setVideoSrc(resolvedVideoSrc);
};

Expand Down Expand Up @@ -167,10 +172,11 @@ const ImageElements = ({
onLoad={onLoad}
decoding="async"
src={showFullRes ? src.src : undefined}
srcSet={showFullRes ? srcSet : undefined}
srcSet={showFullRes ? srcSetString : undefined}
width={src.width}
height={src.height}
alt={alt}
sizes={sizes}
{...rest}
/>
)}
Expand All @@ -195,5 +201,5 @@ const ImageElements = ({
};

function getIsVideo(src) {
return typeof src === 'string' && src.endsWith('.mp4');
return typeof src.src === 'string' && src.src.endsWith('.mp4');
}
31 changes: 31 additions & 0 deletions src/components/Image/Image.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Image } from 'components/Image';
import { StoryContainer } from '../../../.storybook/StoryContainer';

export default {
title: 'Image',
};

const imageSrc = {
src: {
src: 'https://images.unsplash.com/photo-1563089145-599997674d42?auto=format&fit=crop&w=1317&q=80',
width: 1317,
height: 878,
},
placeholder: {
src: 'https://images.unsplash.com/photo-1563089145-599997674d42?auto=format&fit=crop&w=439&q=2',
width: 1317,
height: 878,
},
};

export const image = () => (
<StoryContainer>
<Image {...imageSrc} />
</StoryContainer>
);

export const reveal = () => (
<StoryContainer>
<Image reveal {...imageSrc} />
</StoryContainer>
);
4 changes: 2 additions & 2 deletions src/components/Model/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
} from 'three';
import { HorizontalBlurShader } from 'three/examples/jsm/shaders/HorizontalBlurShader.js';
import { VerticalBlurShader } from 'three/examples/jsm/shaders/VerticalBlurShader.js';
import { getImageFromSrcSet } from 'utils/image';
import { resolveSrcFromSrcSet } from 'utils/image';
import { classes, cssProps, numToMs } from 'utils/style';
import { cleanRenderer, cleanScene, modelLoader, removeLights } from 'utils/three';
import styles from './Model.module.css';
Expand Down Expand Up @@ -397,7 +397,7 @@ const Device = ({
if (node.name === MeshType.Screen) {
applyScreenTexture(placeholder, node);
loadFullResTexture = async () => {
const image = await getImageFromSrcSet(texture);
const image = await resolveSrcFromSrcSet(texture);
const fullSize = await textureLoader.current.loadAsync(image);
await applyScreenTexture(fullSize, node);
};
Expand Down
3 changes: 1 addition & 2 deletions src/layouts/Home/Profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ export const Profile = ({ id, visible, sectionRef }) => {
reveal
delay={100}
placeholder={profileImgPlaceholder}
src={profileImg}
srcSet={`${profileImg.src} 480w, ${profileImgLarge.src} 960w`}
srcSet={[profileImg, profileImgLarge]}
sizes={`(max-width: ${media.mobile}px) 100vw, 480px`}
alt="Me standing in front of the Torii on Miyajima, an island off the coast of Hiroshima in Japan"
/>
Expand Down
22 changes: 12 additions & 10 deletions src/layouts/Post/Post.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,18 @@ export const Post = ({
</RouterLink>
<div className={styles.bannerReadTime}>{readTime}</div>
</div>
<div className={styles.banner}>
<Image
reveal
delay={600}
className={styles.bannerImage}
src={banner ? banner : undefined}
placeholder={{ src: bannerPlaceholder }}
alt={bannerAlt}
/>
</div>
{banner && (
<div className={styles.banner}>
<Image
reveal
delay={600}
className={styles.bannerImage}
src={{ src: banner }}
placeholder={{ src: bannerPlaceholder }}
alt={bannerAlt}
/>
</div>
)}
</header>
<Section className={styles.contentWrapper} id="postContent" tabIndex={-1}>
<div className={styles.content}>{children}</div>
Expand Down
2 changes: 2 additions & 0 deletions src/pages/Contact/Contact.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Button } from 'components/Button';
import { DecoderText } from 'components/DecoderText';
import { Divider } from 'components/Divider';
import { Footer } from 'components/Footer';
import { Heading } from 'components/Heading';
import { Icon } from 'components/Icon';
import { Input } from 'components/Input';
Expand Down Expand Up @@ -175,6 +176,7 @@ export const Contact = () => {
</div>
)}
</Transition>
<Footer className={styles.footer} />
</Section>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/pages/articles/Articles.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const ArticlesPost = ({
restartOnPause
play={hovered}
className={styles.postImage}
src={banner}
src={{ src: banner }}
placeholder={{ src: bannerPlaceholder }}
alt={bannerAlt}
/>
Expand Down
6 changes: 4 additions & 2 deletions src/pages/contact/Contact.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
--formHeight: 530px;

position: absolute;
display: flex;
display: grid;
grid-template-rows: 1fr auto;
justify-items: center;
justify-content: center;
padding-top: calc(50vh - var(--formHeight) / 2);
align-items: center;
min-height: 100vh;
width: 100%;

Expand Down
15 changes: 5 additions & 10 deletions src/pages/projects/slice/Slice.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,14 @@ export const Slice = () => {
<div className={styles.sidebarImages}>
<Image
className={styles.sidebarImage}
src={sliceSidebarLayers}
srcSet={`${sliceSidebarLayers.src} 300w, ${sliceSidebarLayersLarge.src} 700w`}
srcSet={[sliceSidebarLayers, sliceSidebarLayersLarge]}
placeholder={sliceSidebarLayersPlaceholder}
alt="The layers sidebar design, now with user profiles."
sizes={`(max-width: ${media.mobile}px) 200px, 343px`}
/>
<Image
className={styles.sidebarImage}
src={sliceSidebarAnnotations}
srcSet={`${sliceSidebarAnnotations.src} 300w, ${sliceSidebarAnnotationsLarge.src} 700w`}
srcSet={[sliceSidebarAnnotations, sliceSidebarAnnotationsLarge]}
placeholder={sliceSidebarAnnotationsPlaceholder}
alt="Multiple user annotations on a shared layer."
sizes={`(max-width: ${media.mobile}px) 200px, 343px`}
Expand All @@ -120,8 +118,7 @@ export const Slice = () => {
</ProjectSectionText>
</ProjectTextRow>
<Image
src={sliceSlides}
srcSet={`${sliceSlides.src} 800w, ${sliceSlidesLarge.src} 1440w`}
srcSet={[sliceSlides, sliceSlidesLarge]}
placeholder={sliceSlidesPlaceholder}
alt="The new My Slides tab in slice, showing annotated and favorited slides."
sizes={`(max-width: ${media.mobile}px) 500px, (max-width: ${media.tablet}px) 800px, 1000px`}
Expand All @@ -133,8 +130,7 @@ export const Slice = () => {
<div className={styles.gridImage}>
<div className={styles.gridBackground}>
<Image
src={sliceBackgroundBar}
srcSet={`${sliceBackgroundBar.src} 400w, ${sliceBackgroundBarLarge.src} 898w`}
srcSet={[sliceBackgroundBar, sliceBackgroundBarLarge]}
placeholder={sliceBackgroundBarPlaceholder}
alt=""
role="presentation"
Expand All @@ -143,8 +139,7 @@ export const Slice = () => {
</div>
<div className={styles.gridForeground}>
<Image
src={sliceAnnotation}
srcSet={`${sliceAnnotation.src} 440w, ${sliceAnnotationLarge.src} 880w`}
srcSet={[sliceAnnotation, sliceAnnotationLarge]}
placeholder={sliceAnnotationPlaceholder}
alt="An annotation preview popover with statistics for shape perimeter and area."
sizes={`(max-width: ${media.mobile}px) 584px, (max-width: ${media.tablet}px) 747px, 556px`}
Expand Down
2 changes: 2 additions & 0 deletions src/pages/projects/smart-sparrow/Earth.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ export const Earth = ({
}, []);

const handleScroll = useCallback(() => {
if (!container.current) return;

const { offsetTop } = container.current;
const { innerHeight } = window;

Expand Down
Loading

0 comments on commit 8438d6f

Please sign in to comment.