Skip to content

Commit 64c2f01

Browse files
committed
[Motion] feat: transform origin, scale 값 추가
1 parent bbcba7e commit 64c2f01

File tree

6 files changed

+42
-8
lines changed

6 files changed

+42
-8
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"dev": "vite",
88
"build": "tsc && vite build",
99
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
10-
"preview": "vite preview"
10+
"preview": "vite preview",
11+
"lint-ts": "tsc --noEmit"
1112
},
1213
"dependencies": {
1314
"@tanstack/react-query": "^5.32.0",

src/components/layout/CheatLayout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,14 @@ function SettingArea<T extends MotionJsonKeyType>({
150150
step={0.01}
151151
{...register(`${keyName}.delay`)}
152152
/>
153+
<SettingInput label="originX" {...register(`${keyName}.originX`)} />
154+
<SettingInput label="originY" {...register(`${keyName}.originY`)} />
153155
<div className="border-sky-100 border-solid flex flex-col gap-2">
154156
{fields.map((item, idx) => {
155157
return (
156158
<div key={item.id} className="flex flex-row gap-2">
157159
<div className="flex flex-col">
158-
{["x", "y", "rotate", "opacity", "ease"].map((key) => {
160+
{["x", "y", "rotate", "opacity", "ease", "scale"].map((key) => {
159161
const formName = `${keyName}.to[${idx}].${key}` as const;
160162
return (
161163
<SettingInput

src/hooks/useMotion.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { ObjectFilter, hasOwn } from "@Utils/objectExtension";
33
import {
44
MotionJsonValue,
55
Options,
6+
Styles,
67
To,
8+
ToOptions,
79
getMotionJson,
810
} from "@Utils/motionManager";
911

@@ -16,7 +18,6 @@ export default function useMotion({ id }: UseMotionProps) {
1618
const motionJson = getMotionJson();
1719

1820
if (!hasOwn(motionJson, id)) return null;
19-
// @ts-ignore
2021
return convert(motionJson[id]);
2122
});
2223

@@ -28,27 +29,39 @@ export default function useMotion({ id }: UseMotionProps) {
2829
}
2930

3031
function convert(info: MotionJsonValue) {
31-
const to: To = { x: [], y: [], rotate: [], opacity: [] };
32+
const to: To = { x: [], y: [], rotate: [], opacity: [], scale: [] };
3233
const options: Options = {
3334
delay: 0,
3435
duration: 0,
3536
ease: [],
3637
};
3738

39+
const styles: Styles = {
40+
originX: "50%",
41+
originY: "50%",
42+
};
43+
44+
// mapping to
3845
info.to.forEach((item) => {
3946
Object.entries(item).forEach(([key, value]) => {
40-
if (key === "ease") {
47+
const newKey = key as keyof ToOptions;
48+
49+
if (newKey === "ease") {
4150
options.ease.push(value);
4251
} else {
43-
// @ts-ignore
44-
to[key].push(value);
52+
to[newKey].push(value);
4553
}
4654
});
4755
});
4856

57+
// mapping options
4958
options.duration = info.duration;
5059
options.delay = info.delay;
5160

61+
// mapping sytles
62+
styles.originX = info.originX;
63+
styles.originY = info.originX;
64+
5265
const filteredTo = ObjectFilter(
5366
to,
5467
({ value }) => !(value instanceof Array && value.length === 0)
@@ -59,5 +72,10 @@ function convert(info: MotionJsonValue) {
5972
({ value }) => !(value instanceof Array && value.length === 0)
6073
);
6174

62-
return { to: filteredTo, options: filteredOptions };
75+
const filteredStyles = ObjectFilter(
76+
styles,
77+
({ value }) => !(value instanceof Array && value.length === 0)
78+
);
79+
80+
return { to: filteredTo, options: filteredOptions, styles: filteredStyles };
6381
}

src/pages/choose/Choose.page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default function ChoosePage() {
1818
initial={{ y: "100%" }}
1919
animate={motionContent.to}
2020
transition={motionContent.options}
21+
style={motionContent.styles}
2122
>
2223
<Top />
2324
<div className="flex flex-col px-[24px] overflow-y-auto gap-[32px]">

src/pages/landing/Landing.page.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export default function LandingPage() {
3535
className="flex flex-col h-full overflow-hidden absolute w-full"
3636
exit={motionContent.to}
3737
transition={motionContent.options}
38+
style={motionContent.styles}
3839
>
3940
<div className="h-full relative px-[16px] flex w-full justify-between gap-[9px]">
4041
<MovieSide />
@@ -45,6 +46,7 @@ export default function LandingPage() {
4546
<motion.div
4647
exit={motionButton.to}
4748
transition={motionButton.options}
49+
style={motionButton.styles}
4850
className="absolute flex w-full bottom-[32px] left-0 right-0 m-auto justify-center"
4951
>
5052
<Button
@@ -58,6 +60,7 @@ export default function LandingPage() {
5860
<div
5961
className="absolute w-[100px] left-0 right-0 m-auto bottom-0 translate-y-full"
6062
ref={scope}
63+
style={motionCathand.styles}
6164
>
6265
<CatHand />
6366
</div>

src/utils/motionManager.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,23 @@ export interface ToOptions {
1010
rotate?: number | string;
1111
opacity?: number;
1212
ease?: Easing;
13+
scale?: number;
1314
}
1415

1516
export interface MotionJsonValue {
1617
to: ToOptions[];
1718
delay: number;
1819
duration: number;
20+
originX: number | string;
21+
originY: number | string;
1922
}
2023

2124
export interface To {
2225
x: (number | string)[];
2326
y: (number | string)[];
2427
rotate: (number | string)[];
2528
opacity: number[];
29+
scale: number[];
2630
}
2731

2832
export interface Options {
@@ -31,6 +35,11 @@ export interface Options {
3135
ease: Easing[];
3236
}
3337

38+
export interface Styles {
39+
originX: number | string;
40+
originY: number | string;
41+
}
42+
3443
export type MotionJsonKeyType = keyof typeof MotionJson;
3544
export type MotionJsonType = Record<MotionJsonKeyType, MotionJsonValue>;
3645

0 commit comments

Comments
 (0)