Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/picture matte #290

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/blocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,13 @@ function figure(slice: Slice): BlockType {
attribution,
caption,
image,
device = 'None',
border = false,
frame = 'None',
} = slice.primary;

const output = {
border,
device: device as Device,
frame,
source: image,
attribution: undefined,
caption: undefined,
Expand Down
2 changes: 1 addition & 1 deletion lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export type SpaceScale = 'xxnarrow' | 'xnarrow' | 'narrow' | 'medium' | 'wide' |
export type Prominence = 'Small' | 'Medium' | 'Large';
export type GallerySize = 'small' | 'medium' | 'large';
export type ImageFit = 'default' | 'contain' | 'cover';
export type Device = 'None' | 'Phone' | 'Tablet (horizontal)' | 'Tablet (vertical)';
export type Frame = 'None' | 'Matte' | 'Frame & matte' | 'Panel' | 'Phone' | 'Tablet (horizontal)' | 'Tablet (vertical)';

// --- type ---
export type TypeScale = 'alpha' | 'beta' | 'gamma' | 'delta' | 'epsilon' | 'zeta';
Expand Down
4 changes: 2 additions & 2 deletions src/components/blocks/Collage.astro
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import Image from '@components/elements/Image.astro';
import Figure from '@components/blocks/Figure.astro';

// types
import type { SpaceScale, FormattedText, ImageFit, Device } from '@lib/types';
import type { SpaceScale, FormattedText, ImageFit, Frame } from '@lib/types';
import type { ImageField } from '@prismicio/types';

type CollageItemSize = 'Default' | 'Large' | 'XLarge';
type CollageItemPriority = '1' | '2' | '3';

type CollageItem = {
source: ImageField,
device?: Device,
frame?: Frame,
priority?: CollageItemPriority,
relativeSize?: CollageItemSize,
};
Expand Down
79 changes: 67 additions & 12 deletions src/components/blocks/Figure.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import '@styles/tokens/contentWidth.css';
// child components
import Image from '@components/elements/Image.astro';
import DeviceFrame from '@components/elements/DeviceFrame.astro';
import PictureFrame from '@components/elements/PictureFrame.astro';
import Caption from '@components/blocks/FigureCaption.astro';
import RevealOnScroll from '@components/layout/RevealOnScroll.astro';

// typescript
import type { ImageField } from '@prismicio/types';

import type {
Device,
Frame,
FormattedText,
ImageFit,
} from '@lib/types';
Expand All @@ -23,36 +24,90 @@ export interface Props {
attribution?: FormattedText;
border?: boolean;
caption?: FormattedText;
device?: Device;
frame?: Frame;
device?: Frame;
fit?: ImageFit;
class?: string;
}

// props
const {
source,
attribution,
border,
caption,
frame = 'None',
device = 'None',
class: className,
fit,
} = Astro.props as Props;

console.log(`Figure: ${frame}, ${source?.alt}`)

const frameComponents = {
'None': {
component: Image,
props: {
border,
fit,
source,
},
},
'Matte': {
component: PictureFrame,
props: {
type: 'matte',
source,
},
},
'Frame & matte': {
component: PictureFrame,
props: {
type: 'frame',
source,
},
},
'Panel': {
component: PictureFrame,
props: {
type: 'panel',
source,
},
},
'Phone': {
component: DeviceFrame,
props: {
type: 'Phone',
source,
},
},
'Tablet (landscape)': {
component: DeviceFrame,
props: {
type: 'Tablet (landscape)',
source,
},
},
'Tablet (portrait)': {
component: DeviceFrame,
props: {
type: 'Tablet (portrait)',
source,
},
},
};

const {
component: FrameComponent,
props,
} = frameComponents[frame];
---

<figure class={['figure', className].join(' ')}>
<RevealOnScroll>
<slot>
{source && (
device !== 'None'
? <DeviceFrame
type={device}
{source}
/>
: <Image
{border}
{fit}
{source}
/>
<FrameComponent {...props} />
)}
</slot>

Expand Down
6 changes: 3 additions & 3 deletions src/components/elements/DeviceFrame.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
import Image from '@components/elements/Image.astro';

// types
import type { Device } from '@lib/types';
import type { Frame } from '@lib/types';
import type { ImageField } from '@prismicio/types';

export interface Props {
source: ImageField,
class?: string,
type?: Device,
type?: Frame,
};

const {
Expand All @@ -25,7 +25,7 @@
} = Astro.props as Props;

const types = {
Phone: {
'Phone': {
className: 'phone',
ratio: '1/2',
},
Expand Down
34 changes: 26 additions & 8 deletions src/components/elements/PictureFrame.astro
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,23 @@ export interface Props {
frameThickness: number,
matteColor?: CSSVariable | HexColor | HSLColor | HSLAColor,
matteThickness?: number,
type?: 'frame' | 'panel',
type?: 'matte' | 'frame' | 'panel',
};

const types = {
// matte only
matte: {
matte: 18,
border: 0,
},

// picture frame
frame: {
matte: 20,
border: 0.25,
},

// framed panel/canvas
panel: {
matte: 2,
border: 0.25,
Expand All @@ -47,18 +56,22 @@ const {
frameThickness = types[type].border,
matteThickness = types[type].matte,
matteColor,
el = 'figure',
} = Astro.props as Props;


const { width, height } = source.dimensions;

const matteAndFrameInPx = ((matteThickness / 100) * width) + (frameThickness * 16);
console.log(matteAndFrameInPx);

const aspectRatio = [
width + matteAndFrameInPx,
height + matteAndFrameInPx,
].join(' / ');

const El = el;

const classList = [
'picture',
type,
Expand All @@ -67,31 +80,31 @@ const classList = [

const styleList = arrayToPunctatedString([
`--aspect-ratio: ${aspectRatio}`,
matteColor && `--matte-color: ${matteColor};`,
`--frame-thickness: ${frameThickness}em`,
`--frame-thickness: ${frameThickness > 0 ? `${frameThickness}em` : 0}`,
`--matte-thickness: ${matteThickness}%`,
matteColor && `--matte-color: ${matteColor};`,
]);
---

<figure
<El
class={classList}
style={styleList}
>
<Image class="image" {source} />
</figure>
</El>

<style is:global>
.picture.matte,
.picture.frame,
.picture.panel {
--frame-color: var(--color-primary);
--shadow-color: var(--color-shadow);
--matte-color: var(--color-island, #fff);
--matte-color: var(--color-well, #fff);

align-items: center;
aspect-ratio: var(--aspect-ratio);
background-color: var(--matte-color);
border: var(--frame-thickness) solid var(--frame-color);
box-shadow: 0 0.25em 0.5em var(--color-shadow);
display: flex;
flex-direction: column;
height: auto;
Expand All @@ -100,11 +113,16 @@ const styleList = arrayToPunctatedString([
max-height: 100%;
}

.picture.frame,
.picture.panel {
box-shadow: 0 0.25em 0.5em var(--color-shadow);
}

.picture.panel {
box-shadow: 0 0.7em 0.4em var(--color-shadow);
}

.picture .image {
.picture .image[width][height] {
width: calc(100% - var(--matte-thickness));
}
</style>