Skip to content

Commit 02abe32

Browse files
committed
Address halftone linear gradient review
1 parent acfafe8 commit 02abe32

22 files changed

Lines changed: 603 additions & 172 deletions

packages/core/src/sequence-field-schema.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ export type TranslateFieldSchema = {
3131
description?: string;
3232
};
3333

34+
export type UvCoordinateFieldSchema = {
35+
type: 'uv-coordinate';
36+
min?: number;
37+
max?: number;
38+
step?: number;
39+
default: readonly [number, number] | undefined;
40+
description?: string;
41+
};
42+
3443
export type ColorFieldSchema = {
3544
type: 'color';
3645
default: string | undefined;
@@ -49,6 +58,7 @@ export type VisibleFieldSchema =
4958
| BooleanFieldSchema
5059
| RotationFieldSchema
5160
| TranslateFieldSchema
61+
| UvCoordinateFieldSchema
5262
| ColorFieldSchema
5363
| EnumFieldSchema;
5464

packages/docs/components/demos/control.tsx

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, {useMemo} from 'react';
2-
import styles from './styles.module.css';
32
import type {Option} from './types';
3+
import styles from './styles.module.css';
44

55
const left: React.CSSProperties = {
66
fontFamily: 'GTPlanar',
@@ -26,8 +26,10 @@ export const Control = ({
2626
setValue,
2727
}: {
2828
readonly option: Option;
29-
readonly value: number | string | boolean;
30-
readonly setValue: (value: number | string | boolean | null) => void;
29+
readonly value: number | string | boolean | readonly [number, number];
30+
readonly setValue: (
31+
value: number | string | boolean | readonly [number, number] | null,
32+
) => void;
3133
}) => {
3234
const enabled = value !== null;
3335

@@ -56,6 +58,22 @@ export const Control = ({
5658
[],
5759
);
5860

61+
const uvValue = useMemo<readonly [number, number] | null>(() => {
62+
if (option.type !== 'uv-coordinate') {
63+
return null;
64+
}
65+
66+
if (
67+
Array.isArray(value) &&
68+
value.length === 2 &&
69+
value.every((item) => typeof item === 'number')
70+
) {
71+
return [value[0], value[1]];
72+
}
73+
74+
return option.default;
75+
}, [option, value]);
76+
5977
return (
6078
<label style={labelStyle} className={styles.item}>
6179
<div style={left}>
@@ -85,11 +103,46 @@ export const Control = ({
85103
style={inputStyle}
86104
onChange={(e) => setValue(Number(e.target.value))}
87105
/>
106+
) : option.type === 'uv-coordinate' && enabled ? (
107+
<>
108+
<input
109+
type="range"
110+
min={option.min}
111+
max={option.max}
112+
step={option.step}
113+
value={(uvValue ?? option.default)[0]}
114+
style={inputStyle}
115+
onChange={(e) =>
116+
setValue([
117+
Number(e.target.value),
118+
(uvValue ?? option.default)[1],
119+
] as const)
120+
}
121+
/>
122+
<input
123+
type="range"
124+
min={option.min}
125+
max={option.max}
126+
step={option.step}
127+
value={(uvValue ?? option.default)[1]}
128+
style={inputStyle}
129+
onChange={(e) =>
130+
setValue([
131+
(uvValue ?? option.default)[0],
132+
Number(e.target.value),
133+
] as const)
134+
}
135+
/>
136+
</>
88137
) : null}
89138
{option.type === 'numeric' ? (
90139
<div style={right}>
91140
<code>{value}</code>
92141
</div>
142+
) : option.type === 'uv-coordinate' ? (
143+
<div style={right}>
144+
<code>{`[${(uvValue ?? option.default)[0]}, ${(uvValue ?? option.default)[1]}]`}</code>
145+
</div>
93146
) : option.type === 'enum' ? (
94147
<div>
95148
<select

packages/docs/components/demos/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
effectsGlowDemo,
2727
effectsGrayscaleDemo,
2828
effectsHalftoneDemo,
29-
effectsHalftoneGradientDemo,
29+
effectsHalftoneLinearGradientDemo,
3030
effectsHueDemo,
3131
effectsInvertDemo,
3232
effectsLightLeakDemo,
@@ -112,7 +112,7 @@ const demos: DemoType[] = [
112112
effectsChromaticAberrationDemo,
113113
effectsWaveDemo,
114114
effectsHalftoneDemo,
115-
effectsHalftoneGradientDemo,
115+
effectsHalftoneLinearGradientDemo,
116116
effectsStarburstDemo,
117117
effectsLightLeakDemo,
118118
arrowDemo,

packages/docs/components/demos/types.ts

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {EffectsContrastPreview} from '../effects/effects-contrast-preview';
77
import {EffectsDuotonePreview} from '../effects/effects-duotone-preview';
88
import {EffectsGlowPreview} from '../effects/effects-glow-preview';
99
import {EffectsGrayscalePreview} from '../effects/effects-grayscale-preview';
10-
import {EffectsHalftoneGradientPreview} from '../effects/effects-halftone-gradient-preview';
10+
import {EffectsHalftoneLinearGradientPreview} from '../effects/effects-halftone-linear-gradient-preview';
1111
import {EffectsHalftonePreview} from '../effects/effects-halftone-preview';
1212
import {EffectsHuePreview} from '../effects/effects-hue-preview';
1313
import {EffectsInvertPreview} from '../effects/effects-invert-preview';
@@ -110,6 +110,13 @@ export type Option = {
110110
type: 'color';
111111
default: string;
112112
}
113+
| {
114+
type: 'uv-coordinate';
115+
min: number;
116+
default: readonly [number, number];
117+
max: number;
118+
step: number;
119+
}
113120
);
114121

115122
export type DemoType = {
@@ -2096,13 +2103,13 @@ export const effectsHalftoneDemo: DemoType = {
20962103
],
20972104
};
20982105

2099-
export const effectsHalftoneGradientDemo: DemoType = {
2100-
comp: EffectsHalftoneGradientPreview,
2106+
export const effectsHalftoneLinearGradientDemo: DemoType = {
2107+
comp: EffectsHalftoneLinearGradientPreview,
21012108
compHeight: 720,
21022109
compWidth: 1280,
21032110
durationInFrames: 1,
21042111
fps: 30,
2105-
id: 'effects-halftone-gradient',
2112+
id: 'effects-halftone-linear-gradient',
21062113
autoPlay: false,
21072114
controls: false,
21082115
logLevel: 'info',
@@ -2125,6 +2132,24 @@ export const effectsHalftoneGradientDemo: DemoType = {
21252132
default: 40,
21262133
optional: 'no',
21272134
},
2135+
{
2136+
name: 'firstStopPosition',
2137+
type: 'uv-coordinate',
2138+
min: 0,
2139+
max: 1,
2140+
step: 0.01,
2141+
default: [0, 0.5],
2142+
optional: 'no',
2143+
},
2144+
{
2145+
name: 'secondStopPosition',
2146+
type: 'uv-coordinate',
2147+
min: 0,
2148+
max: 1,
2149+
step: 0.01,
2150+
default: [1, 0.5],
2151+
optional: 'no',
2152+
},
21282153
{
21292154
name: 'gridSize',
21302155
type: 'numeric',
@@ -2134,15 +2159,6 @@ export const effectsHalftoneGradientDemo: DemoType = {
21342159
default: 24,
21352160
optional: 'no',
21362161
},
2137-
{
2138-
name: 'rotation',
2139-
type: 'numeric',
2140-
min: -180,
2141-
max: 180,
2142-
step: 1,
2143-
default: 0,
2144-
optional: 'no',
2145-
},
21462162
{
21472163
name: 'colorMode',
21482164
type: 'enum',
@@ -2153,7 +2169,7 @@ export const effectsHalftoneGradientDemo: DemoType = {
21532169
{
21542170
name: 'dotColor',
21552171
type: 'color',
2156-
default: '#ffffff',
2172+
default: '#0b84f3',
21572173
optional: 'no',
21582174
showIf: {
21592175
option: 'colorMode',

packages/docs/components/effects/effects-halftone-gradient-preview.tsx renamed to packages/docs/components/effects/effects-halftone-linear-gradient-preview.tsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
import type {HalftoneGradientColorMode} from '@remotion/effects/halftone-gradient';
2-
import {halftoneGradient} from '@remotion/effects/halftone-gradient';
1+
import type {
2+
HalftoneLinearGradientColorMode,
3+
UvCoordinate,
4+
} from '@remotion/effects/halftone-linear-gradient';
5+
import {halftoneLinearGradient} from '@remotion/effects/halftone-linear-gradient';
36
import React from 'react';
47
import {CanvasImage} from 'remotion';
58
import {EFFECTS_PREVIEW_IMAGE_SRC} from './effects-preview-image';
@@ -9,18 +12,20 @@ const fullSize: React.CSSProperties = {
912
height: '100%',
1013
};
1114

12-
export const EffectsHalftoneGradientPreview: React.FC<{
15+
export const EffectsHalftoneLinearGradientPreview: React.FC<{
1316
readonly firstStopDotSize: number;
1417
readonly secondStopDotSize: number;
18+
readonly firstStopPosition: UvCoordinate;
19+
readonly secondStopPosition: UvCoordinate;
1520
readonly gridSize: number;
16-
readonly rotation: number;
17-
readonly colorMode: HalftoneGradientColorMode;
21+
readonly colorMode: HalftoneLinearGradientColorMode;
1822
readonly dotColor: string;
1923
}> = ({
2024
firstStopDotSize,
2125
secondStopDotSize,
26+
firstStopPosition,
27+
secondStopPosition,
2228
gridSize,
23-
rotation,
2429
colorMode,
2530
dotColor,
2631
}) => {
@@ -37,11 +42,12 @@ export const EffectsHalftoneGradientPreview: React.FC<{
3742
fit="cover"
3843
style={fullSize}
3944
effects={[
40-
halftoneGradient({
45+
halftoneLinearGradient({
4146
firstStopDotSize,
4247
secondStopDotSize,
48+
firstStopPosition,
49+
secondStopPosition,
4350
gridSize,
44-
rotation,
4551
...colorParams,
4652
}),
4753
]}

packages/docs/docs/effects/halftone-gradient.mdx renamed to packages/docs/docs/effects/halftone-linear-gradient.mdx

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
---
2-
image: /generated/articles-docs-effects-halftone-gradient.png
3-
slug: /effects/halftone-gradient
4-
title: halftoneGradient()
5-
sidebar_label: halftoneGradient()
2+
image: /generated/articles-docs-effects-halftone-linear-gradient.png
3+
slug: /effects/halftone-linear-gradient
4+
title: halftoneLinearGradient()
5+
sidebar_label: halftoneLinearGradient()
66
crumb: '@remotion/effects'
77
---
88

9-
# halftoneGradient()<AvailableFrom v="4.0.468" />
9+
# halftoneLinearGradient()<AvailableFrom v="4.0.468" />
1010

1111
_Part of the [`@remotion/effects`](/docs/effects/api) package._
1212

@@ -16,27 +16,28 @@ Use it for dot-pattern wipes, overlays, and backgrounds on canvas-based componen
1616

1717
## Preview
1818

19-
<Demo type="effects-halftone-gradient" />
19+
<Demo type="effects-halftone-linear-gradient" />
2020

2121
## Example
2222

2323
```tsx twoslash title="MyComp.tsx"
2424
import {AbsoluteFill} from 'remotion';
2525
import {Video} from '@remotion/media';
26-
import {halftoneGradient} from '@remotion/effects/halftone-gradient';
26+
import {halftoneLinearGradient} from '@remotion/effects/halftone-linear-gradient';
2727

2828
export const MyComp: React.FC = () => {
2929
return (
3030
<AbsoluteFill>
3131
<Video
3232
src="https://remotion.media/video.mp4"
3333
effects={[
34-
halftoneGradient({
34+
halftoneLinearGradient({
3535
firstStopDotSize: 0,
3636
secondStopDotSize: 42,
37+
firstStopPosition: [0, 0.5],
38+
secondStopPosition: [1, 0.5],
3739
gridSize: 24,
38-
rotation: 20,
39-
dotColor: '#111111',
40+
dotColor: '#0b84f3',
4041
}),
4142
]}
4243
/>
@@ -50,19 +51,20 @@ To use colors from the previous effect in the chain, set `colorMode` to `'source
5051
```tsx twoslash title="MyComp.tsx"
5152
import {AbsoluteFill} from 'remotion';
5253
import {Video} from '@remotion/media';
53-
import {halftoneGradient} from '@remotion/effects/halftone-gradient';
54+
import {halftoneLinearGradient} from '@remotion/effects/halftone-linear-gradient';
5455

5556
export const MyComp: React.FC = () => {
5657
return (
5758
<AbsoluteFill>
5859
<Video
5960
src="https://remotion.media/video.mp4"
6061
effects={[
61-
halftoneGradient({
62+
halftoneLinearGradient({
6263
firstStopDotSize: 8,
6364
secondStopDotSize: 44,
65+
firstStopPosition: [0.2, 0],
66+
secondStopPosition: [0.8, 1],
6467
gridSize: 24,
65-
rotation: -25,
6668
colorMode: 'source',
6769
}),
6870
]}
@@ -74,7 +76,7 @@ export const MyComp: React.FC = () => {
7476

7577
## API
7678

77-
Pass an object with the following properties. You can also call `halftoneGradient()` without arguments.
79+
Pass an object with the following properties. You can also call `halftoneLinearGradient()` without arguments.
7880

7981
### `firstStopDotSize?`
8082

@@ -88,13 +90,21 @@ Dot diameter in pixels on the opposite side of the gradient. Defaults to `40`. M
8890

8991
Set both dot sizes to `0` for no coverage. Set both large enough to overlap neighboring cells for full coverage.
9092

91-
### `gridSize?`
93+
### `firstStopPosition?`
9294

93-
Distance between adjacent dot centers in pixels. Defaults to `24`. Must be greater than `0`.
95+
UV coordinate where `firstStopDotSize` is reached. Defaults to `[0, 0.5]`.
96+
97+
Pass a `[number, number]` tuple.
98+
99+
### `secondStopPosition?`
94100

95-
### `rotation?`
101+
UV coordinate where `secondStopDotSize` is reached. Defaults to `[1, 0.5]`.
96102

97-
Rotation of the dot grid and linear gradient in degrees. Defaults to `0`.
103+
Pass a `[number, number]` tuple.
104+
105+
### `gridSize?`
106+
107+
Distance between adjacent dot centers in pixels. Defaults to `24`. Must be greater than `0`.
98108

99109
### `colorMode?`
100110

@@ -116,11 +126,11 @@ When `true`, the effect is skipped. Defaults to `false`.
116126

117127
## Requirements
118128

119-
`halftoneGradient()` uses a WebGL2 backend. During renders, enable WebGL via [`Config.setChromiumOpenGlRenderer()`](/docs/config#setchromiumopenglrenderer) (for example `'angle'`). See [Using WebGL during renders](/docs/remotion/html-in-canvas#using-webgl-during-renders).
129+
`halftoneLinearGradient()` uses a WebGL2 backend. During renders, enable WebGL via [`Config.setChromiumOpenGlRenderer()`](/docs/config#setchromiumopenglrenderer) (for example `'angle'`). See [Using WebGL during renders](/docs/remotion/html-in-canvas#using-webgl-during-renders).
120130

121131
## See also
122132

123133
- [`@remotion/effects`](/docs/effects/api)
124134
- [`halftone()`](/docs/effects/halftone)
125135
- [HTML-in-canvas guide](/docs/html-in-canvas)
126-
- [Source code for this effect](https://github.com/remotion-dev/remotion/blob/main/packages/effects/src/halftone-gradient.ts)
136+
- [Source code for this effect](https://github.com/remotion-dev/remotion/blob/main/packages/effects/src/halftone-linear-gradient.ts)

0 commit comments

Comments
 (0)