react-magic-card 0.0.10 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{readme.md → README.md} +27 -2
- package/dist/MagicCircle/index.d.ts +2 -50
- package/dist/MagicCircle/index.js +78 -44
- package/dist/MagicStraight/index.d.ts +3 -0
- package/dist/MagicStraight/index.js +200 -0
- package/dist/MagicStraight/styles.module.css +9 -0
- package/dist/common/ScaleFilterImage/index.d.ts +4 -0
- package/dist/common/ScaleFilterImage/index.js +26 -0
- package/dist/common/ScaleFilterImage/styles.module.css +10 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/dist/types.d.ts +87 -0
- package/dist/types.js +2 -0
- package/package.json +7 -3
- /package/dist/MagicCircle/{main.css → styles.module.css} +0 -0
package/{readme.md → README.md}
RENAMED
|
@@ -54,6 +54,8 @@ function MyComponent() {
|
|
|
54
54
|
selectRotateZ: -10
|
|
55
55
|
}}
|
|
56
56
|
transition={{ duration: 0.2 }}
|
|
57
|
+
pickTransition={{ duration: 0.4 }}
|
|
58
|
+
pickProperty={{ white: true, alpha: 0.4, blur: 4, scale: 2, offset: 220 }}
|
|
57
59
|
/>
|
|
58
60
|
)
|
|
59
61
|
}
|
|
@@ -64,9 +66,7 @@ function MyComponent() {
|
|
|
64
66
|
| images | array of images and objects containing the src and alt properties. |
|
|
65
67
|
| width | width of a single image. |
|
|
66
68
|
| height | height of a single image. |
|
|
67
|
-
| dynamic | indicating whether dynamic rotation is allowed. |
|
|
68
69
|
| start | index number of the starting scale position. |
|
|
69
|
-
| radius | radius of the circle. |
|
|
70
70
|
| controller | diameter plus the value of the controller is the size of the controller. |
|
|
71
71
|
| className | class name of the component. |
|
|
72
72
|
| classImage | class name of the images. |
|
|
@@ -74,6 +74,20 @@ function MyComponent() {
|
|
|
74
74
|
| animate | object in the animation property. |
|
|
75
75
|
| initial | object in the animation property. |
|
|
76
76
|
| transition | object in the transition property. |
|
|
77
|
+
| pickTransition | object in the transition property. |
|
|
78
|
+
| pickProperty | object in the pick property. |
|
|
79
|
+
|
|
80
|
+
| Only in MagicCircle | Explanation |
|
|
81
|
+
| ------------------- | ----------------------------------------------- |
|
|
82
|
+
| dynamic | indicating whether dynamic rotation is allowed. |
|
|
83
|
+
| radius | radius of the circle. |
|
|
84
|
+
|
|
85
|
+
| Only in MagicStraight | Explanation |
|
|
86
|
+
| --------------------- | ----------------------------------- |
|
|
87
|
+
| vertical | vertical or horizontal boolean flag |
|
|
88
|
+
| margin | spacing of the between images |
|
|
89
|
+
| selectOffsetX | X-axis position |
|
|
90
|
+
| selectOffsetY | Y-axis position |
|
|
77
91
|
|
|
78
92
|
## Animation property
|
|
79
93
|
|
|
@@ -92,6 +106,17 @@ function MyComponent() {
|
|
|
92
106
|
|
|
93
107
|
It Inherits framer motion transition properties other than intera.
|
|
94
108
|
|
|
109
|
+
## Pick property
|
|
110
|
+
|
|
111
|
+
| Property | Explanation |
|
|
112
|
+
| --------- | ---------------------------------------------------------- |
|
|
113
|
+
| classPick | class name of the pick image |
|
|
114
|
+
| white | white or black boolean flag for background |
|
|
115
|
+
| alpha | background transparency a number between 0 ~ 1 |
|
|
116
|
+
| blur | blur intensity a number between 1 and 10 a preferred |
|
|
117
|
+
| scale | scale of the pick image |
|
|
118
|
+
| offset | offset of the appearance position from the center position |
|
|
119
|
+
|
|
95
120
|
## License
|
|
96
121
|
|
|
97
122
|
MIT License
|
|
@@ -1,51 +1,3 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import '
|
|
3
|
-
|
|
4
|
-
src: string;
|
|
5
|
-
alt: string;
|
|
6
|
-
};
|
|
7
|
-
type AnimationProperty = {
|
|
8
|
-
scale?: number;
|
|
9
|
-
opacity?: number;
|
|
10
|
-
rotateY?: number;
|
|
11
|
-
rotateX?: number;
|
|
12
|
-
rotateZ?: number;
|
|
13
|
-
selectScale?: number;
|
|
14
|
-
selectOpacity?: number;
|
|
15
|
-
selectRotateY?: number;
|
|
16
|
-
selectRotateX?: number;
|
|
17
|
-
selectRotateZ?: number;
|
|
18
|
-
};
|
|
19
|
-
type TransitionProperty = {
|
|
20
|
-
duration?: number;
|
|
21
|
-
type: undefined;
|
|
22
|
-
ease: number[] | 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | 'circIn' | 'circOut' | 'circInOut' | 'backIn' | 'backOut' | 'backInOut' | 'anticipate';
|
|
23
|
-
} | {
|
|
24
|
-
duration?: number;
|
|
25
|
-
type?: 'spring';
|
|
26
|
-
bounce?: number;
|
|
27
|
-
damping?: number;
|
|
28
|
-
mass?: number;
|
|
29
|
-
stiffness?: number;
|
|
30
|
-
velocity?: number;
|
|
31
|
-
restSpeed?: number;
|
|
32
|
-
restDelta?: number;
|
|
33
|
-
};
|
|
34
|
-
type MagicCircleProps = {
|
|
35
|
-
images: ImageProperty[];
|
|
36
|
-
width: number;
|
|
37
|
-
height: number;
|
|
38
|
-
radius: number;
|
|
39
|
-
controller: number;
|
|
40
|
-
start: number;
|
|
41
|
-
dynamic: boolean;
|
|
42
|
-
wheelDelay: number;
|
|
43
|
-
animate?: AnimationProperty;
|
|
44
|
-
initial?: AnimationProperty;
|
|
45
|
-
transition?: TransitionProperty;
|
|
46
|
-
className?: string;
|
|
47
|
-
classImage?: string;
|
|
48
|
-
classImageUnique?: string;
|
|
49
|
-
};
|
|
50
|
-
export declare const MagicCircle: ({ images, width, height, radius, controller, start, dynamic, wheelDelay, animate, initial, transition, className, classImage, classImageUnique }: MagicCircleProps) => React.JSX.Element;
|
|
51
|
-
export {};
|
|
2
|
+
import type { MagicCircleProps } from '../types';
|
|
3
|
+
export declare const MagicCircle: ({ images, height, width, radius, controller, start, dynamic, wheelDelay, animate, initial, transition, className, classImage, classImageUnique, selectCursor, pickProperty, pickTransition }: MagicCircleProps) => React.JSX.Element;
|
|
@@ -22,30 +22,39 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
29
|
exports.MagicCircle = void 0;
|
|
27
30
|
const react_1 = __importStar(require("react"));
|
|
28
31
|
const framer_motion_1 = require("framer-motion");
|
|
29
|
-
require("./
|
|
30
|
-
const
|
|
32
|
+
const styles_module_css_1 = __importDefault(require("./styles.module.css"));
|
|
33
|
+
const ScaleFilterImage_1 = __importDefault(require("../common/ScaleFilterImage"));
|
|
34
|
+
const MagicCircle = ({ images, height, width, radius, controller, start, dynamic = true, wheelDelay, animate, initial, transition, className, classImage, classImageUnique, selectCursor = 'pointer', pickProperty, pickTransition }) => {
|
|
31
35
|
const [count, setCount] = (0, react_1.useState)(0);
|
|
32
36
|
const [touchStartY, setTouchStartY] = (0, react_1.useState)(0);
|
|
37
|
+
const [hasShift, setHasShift] = (0, react_1.useState)(false);
|
|
33
38
|
const [hasDelayed, setHasDelayed] = (0, react_1.useState)(true);
|
|
34
39
|
const [select, setSelect] = (0, react_1.useState)(start);
|
|
35
|
-
const
|
|
40
|
+
const [hasPick, setHasPick] = (0, react_1.useState)(false);
|
|
41
|
+
const div1Ref = (0, react_1.useRef)(null);
|
|
42
|
+
const div2Ref = (0, react_1.useRef)(null);
|
|
36
43
|
const centralAngle = ((2 * Math.PI) / images.length) * (180 / Math.PI);
|
|
37
44
|
// Functions of the rotation and select and delay.
|
|
38
45
|
// turn left
|
|
39
46
|
const shiftLeft = (0, react_1.useCallback)(() => {
|
|
40
|
-
setHasDelayed(false);
|
|
41
47
|
setSelect(select == images.length - 1 ? 0 : select + 1);
|
|
48
|
+
setHasShift(true);
|
|
49
|
+
setHasDelayed(false);
|
|
42
50
|
if (dynamic)
|
|
43
51
|
return setCount(count - centralAngle);
|
|
44
52
|
}, [centralAngle, count, dynamic, images.length, select]);
|
|
45
53
|
// turn right
|
|
46
54
|
const shiftRight = (0, react_1.useCallback)(() => {
|
|
47
|
-
setHasDelayed(false);
|
|
48
55
|
setSelect(select == 0 ? images.length - 1 : select - 1);
|
|
56
|
+
setHasShift(false);
|
|
57
|
+
setHasDelayed(false);
|
|
49
58
|
if (dynamic)
|
|
50
59
|
return setCount(count + centralAngle);
|
|
51
60
|
}, [centralAngle, count, dynamic, images.length, select]);
|
|
@@ -73,21 +82,29 @@ const MagicCircle = ({ images, width, height, radius, controller, start, dynamic
|
|
|
73
82
|
}, [shiftLeft, shiftRight, touchStartY]);
|
|
74
83
|
// Main functional, exit function if ref and hasDelayed does not exist.
|
|
75
84
|
(0, react_1.useEffect)(() => {
|
|
76
|
-
const
|
|
85
|
+
const elm1Div = div1Ref.current;
|
|
86
|
+
const elm2Div = div2Ref.current;
|
|
87
|
+
const elms = [elm1Div, elm2Div];
|
|
77
88
|
const timeId = setTimeout(() => {
|
|
78
89
|
setHasDelayed(true);
|
|
79
90
|
}, wheelDelay);
|
|
80
|
-
if (!range || !hasDelayed)
|
|
81
|
-
return;
|
|
82
91
|
// Add handle event when component mount and deps update.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
92
|
+
elms.forEach(elm => {
|
|
93
|
+
if (!elm || !hasDelayed)
|
|
94
|
+
return;
|
|
95
|
+
elm.addEventListener('wheel', handleWheel, { passive: true });
|
|
96
|
+
elm.addEventListener('touchstart', handleTouchStart, { passive: true });
|
|
97
|
+
elm.addEventListener('touchmove', handleTouchMove, { passive: true });
|
|
98
|
+
});
|
|
86
99
|
// Clean up event and timeId when component is unmount.
|
|
87
100
|
return () => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
101
|
+
elms.forEach(elm => {
|
|
102
|
+
if (!elm)
|
|
103
|
+
return;
|
|
104
|
+
elm.removeEventListener('wheel', handleWheel);
|
|
105
|
+
elm.removeEventListener('touchstart', handleTouchStart);
|
|
106
|
+
elm.removeEventListener('touchmove', handleTouchMove);
|
|
107
|
+
});
|
|
91
108
|
clearTimeout(timeId);
|
|
92
109
|
};
|
|
93
110
|
}, [handleTouchMove, handleWheel, hasDelayed, wheelDelay]);
|
|
@@ -103,62 +120,78 @@ const MagicCircle = ({ images, width, height, radius, controller, start, dynamic
|
|
|
103
120
|
};
|
|
104
121
|
// Added event when component is mounted.
|
|
105
122
|
(0, react_1.useEffect)(() => {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
123
|
+
const elm1Div = div1Ref.current;
|
|
124
|
+
const elm2Div = div2Ref.current;
|
|
125
|
+
const elms = [elm1Div, elm2Div];
|
|
109
126
|
// Add event.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
127
|
+
elms.forEach(elm => {
|
|
128
|
+
if (!elm)
|
|
129
|
+
return;
|
|
130
|
+
elm.addEventListener('mouseover', enterControll);
|
|
131
|
+
elm.addEventListener('mouseout', leaveControll);
|
|
132
|
+
elm.addEventListener('touchmove', enterControll);
|
|
133
|
+
elm.addEventListener('touchend', leaveControll);
|
|
134
|
+
});
|
|
114
135
|
// Clean up event when component is unmount.
|
|
115
136
|
return () => {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
137
|
+
elms.forEach(elm => {
|
|
138
|
+
if (!elm)
|
|
139
|
+
return;
|
|
140
|
+
elm.removeEventListener('mouseover', enterControll);
|
|
141
|
+
elm.removeEventListener('mouseout', leaveControll);
|
|
142
|
+
elm.removeEventListener('touchmove', enterControll);
|
|
143
|
+
elm.addEventListener('touchend', leaveControll);
|
|
144
|
+
});
|
|
120
145
|
};
|
|
121
146
|
}, []);
|
|
122
147
|
// angle between images.
|
|
123
148
|
const angle = parseFloat((2 * Math.PI).toFixed(15)) / images.length;
|
|
124
149
|
return (react_1.default.createElement(framer_motion_1.LazyMotion, { features: framer_motion_1.domAnimation },
|
|
125
|
-
react_1.default.createElement(framer_motion_1.m.div, { ref:
|
|
150
|
+
react_1.default.createElement(framer_motion_1.m.div, { ref: div1Ref, className: className + ' ' + styles_module_css_1.default.outer, style: {
|
|
126
151
|
width: radius * 2 + controller + 'px',
|
|
127
152
|
height: radius * 2 + controller + 'px'
|
|
128
153
|
}, animate: { rotate: count }, transition: { duration: transition === null || transition === void 0 ? void 0 : transition.duration } },
|
|
129
|
-
react_1.default.createElement("div", { className:
|
|
154
|
+
react_1.default.createElement("div", { className: styles_module_css_1.default.inner, style: { width: radius * 2 + 'px', height: radius * 2 + 'px' } }, images.map((image, index) => {
|
|
130
155
|
const hasSelect = images[select] == images[index];
|
|
131
156
|
return (react_1.default.createElement(framer_motion_1.m.img, { key: index, animate: {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
?
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
: animate === null || animate === void 0 ? void 0 : animate.rotateX,
|
|
157
|
+
rotate: -count,
|
|
158
|
+
scale: hasSelect
|
|
159
|
+
? hasPick
|
|
160
|
+
? 0
|
|
161
|
+
: animate === null || animate === void 0 ? void 0 : animate.selectScale
|
|
162
|
+
: animate === null || animate === void 0 ? void 0 : animate.scale,
|
|
139
163
|
rotateY: hasSelect
|
|
140
164
|
? animate === null || animate === void 0 ? void 0 : animate.selectRotateY
|
|
141
165
|
: animate === null || animate === void 0 ? void 0 : animate.rotateY,
|
|
166
|
+
rotateX: hasSelect
|
|
167
|
+
? animate === null || animate === void 0 ? void 0 : animate.selectRotateX
|
|
168
|
+
: animate === null || animate === void 0 ? void 0 : animate.rotateX,
|
|
142
169
|
rotateZ: hasSelect
|
|
143
170
|
? animate === null || animate === void 0 ? void 0 : animate.selectRotateZ
|
|
144
171
|
: animate === null || animate === void 0 ? void 0 : animate.rotateZ,
|
|
145
|
-
|
|
172
|
+
opacity: hasSelect
|
|
173
|
+
? hasPick
|
|
174
|
+
? 0
|
|
175
|
+
: animate === null || animate === void 0 ? void 0 : animate.selectOpacity
|
|
176
|
+
: animate === null || animate === void 0 ? void 0 : animate.opacity
|
|
146
177
|
}, initial: {
|
|
178
|
+
rotate: -count,
|
|
147
179
|
scale: hasSelect ? initial === null || initial === void 0 ? void 0 : initial.selectScale : initial === null || initial === void 0 ? void 0 : initial.scale,
|
|
148
|
-
opacity: hasSelect
|
|
149
|
-
? initial === null || initial === void 0 ? void 0 : initial.selectOpacity
|
|
150
|
-
: initial === null || initial === void 0 ? void 0 : initial.opacity,
|
|
151
|
-
rotateX: hasSelect
|
|
152
|
-
? initial === null || initial === void 0 ? void 0 : initial.selectRotateX
|
|
153
|
-
: initial === null || initial === void 0 ? void 0 : initial.rotateX,
|
|
154
180
|
rotateY: hasSelect
|
|
155
181
|
? initial === null || initial === void 0 ? void 0 : initial.selectRotateY
|
|
156
182
|
: initial === null || initial === void 0 ? void 0 : initial.rotateY,
|
|
183
|
+
rotateX: hasSelect
|
|
184
|
+
? initial === null || initial === void 0 ? void 0 : initial.selectRotateX
|
|
185
|
+
: initial === null || initial === void 0 ? void 0 : initial.rotateX,
|
|
157
186
|
rotateZ: hasSelect
|
|
158
187
|
? initial === null || initial === void 0 ? void 0 : initial.selectRotateZ
|
|
159
188
|
: initial === null || initial === void 0 ? void 0 : initial.rotateZ,
|
|
160
|
-
|
|
161
|
-
}, transition: transition, onClick: () =>
|
|
189
|
+
opacity: hasSelect ? initial === null || initial === void 0 ? void 0 : initial.selectOpacity : initial === null || initial === void 0 ? void 0 : initial.opacity
|
|
190
|
+
}, transition: transition, onClick: () => {
|
|
191
|
+
setSelect(index);
|
|
192
|
+
hasSelect && setHasPick(true);
|
|
193
|
+
}, className: classImage + ' ' + classImageUnique + index, src: image.src, alt: image.alt, style: {
|
|
194
|
+
cursor: hasSelect ? selectCursor : 'default',
|
|
162
195
|
width: width + 'px',
|
|
163
196
|
height: height + 'px',
|
|
164
197
|
left: radius * Math.cos(index * angle) +
|
|
@@ -170,6 +203,7 @@ const MagicCircle = ({ images, width, height, radius, controller, start, dynamic
|
|
|
170
203
|
height / 2 +
|
|
171
204
|
'px'
|
|
172
205
|
} }));
|
|
173
|
-
})))
|
|
206
|
+
}))),
|
|
207
|
+
react_1.default.createElement(ScaleFilterImage_1.default, { onClick: () => setHasPick(false), hasPick: hasPick, classPick: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.classPick, white: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.white, alpha: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.alpha, blur: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.blur, scale: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.scale, offset: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.offset, hasShift: hasShift, argRef: div2Ref, argKey: select, src: images[select].src, alt: images[select].alt, width: width, height: height, transition: pickTransition, zIndex: images.length + 1 })));
|
|
174
208
|
};
|
|
175
209
|
exports.MagicCircle = MagicCircle;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { MagicStraightProps } from '../types';
|
|
3
|
+
export declare const MagicStraight: ({ images, height, width, start, controller, wheelDelay, vertical, className, classImage, classImageUnique, animate, initial, transition, margin, selectOffsetX, selectOffsetY, selectCursor, pickProperty, pickTransition }: MagicStraightProps) => React.JSX.Element;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.MagicStraight = void 0;
|
|
30
|
+
const react_1 = __importStar(require("react"));
|
|
31
|
+
const framer_motion_1 = require("framer-motion");
|
|
32
|
+
const styles_module_css_1 = __importDefault(require("./styles.module.css"));
|
|
33
|
+
const ScaleFilterImage_1 = __importDefault(require("../common/ScaleFilterImage"));
|
|
34
|
+
const MagicStraight = ({ images, height, width, start, controller, wheelDelay, vertical, className, classImage, classImageUnique, animate, initial, transition, margin = 0, selectOffsetX = 0, selectOffsetY = 0, selectCursor = 'pointer', pickProperty, pickTransition }) => {
|
|
35
|
+
const [touchStartY, setTouchStartY] = (0, react_1.useState)(0);
|
|
36
|
+
const [touchStartX, setTouchStartX] = (0, react_1.useState)(0);
|
|
37
|
+
const [hasShift, setHasShift] = (0, react_1.useState)(false);
|
|
38
|
+
const [hasDelayed, setHasDelayed] = (0, react_1.useState)(true);
|
|
39
|
+
const [select, setSelect] = (0, react_1.useState)(start);
|
|
40
|
+
const [hasPick, setHasPick] = (0, react_1.useState)(false);
|
|
41
|
+
const div1Ref = (0, react_1.useRef)(null);
|
|
42
|
+
const div2Ref = (0, react_1.useRef)(null);
|
|
43
|
+
const shiftRight = (0, react_1.useCallback)(() => {
|
|
44
|
+
setSelect(select == images.length - 1 ? 0 : select + 1);
|
|
45
|
+
setHasShift(true);
|
|
46
|
+
setHasDelayed(false);
|
|
47
|
+
}, [images.length, select]);
|
|
48
|
+
const shiftLeft = (0, react_1.useCallback)(() => {
|
|
49
|
+
setSelect(select == 0 ? images.length - 1 : select - 1);
|
|
50
|
+
setHasShift(false);
|
|
51
|
+
setHasDelayed(false);
|
|
52
|
+
}, [images.length, select]);
|
|
53
|
+
const handleWheel = (0, react_1.useCallback)((e) => {
|
|
54
|
+
const delta = e.deltaY;
|
|
55
|
+
if (delta > 0)
|
|
56
|
+
shiftRight();
|
|
57
|
+
if (delta < 0)
|
|
58
|
+
shiftLeft();
|
|
59
|
+
}, [shiftLeft, shiftRight]);
|
|
60
|
+
const handleTouchStart = (event) => {
|
|
61
|
+
const touch = event.touches[0];
|
|
62
|
+
setTouchStartY(touch.clientY);
|
|
63
|
+
setTouchStartX(touch.clientX);
|
|
64
|
+
};
|
|
65
|
+
const handleTouchMove = (0, react_1.useCallback)((event) => {
|
|
66
|
+
const touch = event.touches[0];
|
|
67
|
+
const delta = hasPick
|
|
68
|
+
? touch.clientX - touchStartX
|
|
69
|
+
: vertical
|
|
70
|
+
? touch.clientY - touchStartY
|
|
71
|
+
: touch.clientX - touchStartX;
|
|
72
|
+
if (delta > 0)
|
|
73
|
+
shiftRight();
|
|
74
|
+
if (delta < 0)
|
|
75
|
+
shiftLeft();
|
|
76
|
+
}, [hasPick, shiftLeft, shiftRight, touchStartX, touchStartY, vertical]);
|
|
77
|
+
(0, react_1.useEffect)(() => {
|
|
78
|
+
const elm1Div = div1Ref.current;
|
|
79
|
+
const elm2Div = div2Ref.current;
|
|
80
|
+
const elms = [elm1Div, elm2Div];
|
|
81
|
+
const timeId = setTimeout(() => {
|
|
82
|
+
setHasDelayed(true);
|
|
83
|
+
}, wheelDelay);
|
|
84
|
+
elms.forEach(elm => {
|
|
85
|
+
if (!elm || !hasDelayed)
|
|
86
|
+
return;
|
|
87
|
+
elm.addEventListener('wheel', handleWheel, { passive: true });
|
|
88
|
+
elm.addEventListener('touchstart', handleTouchStart, { passive: true });
|
|
89
|
+
elm.addEventListener('touchmove', handleTouchMove, { passive: true });
|
|
90
|
+
});
|
|
91
|
+
return () => {
|
|
92
|
+
elms.forEach(elm => {
|
|
93
|
+
if (!elm)
|
|
94
|
+
return;
|
|
95
|
+
elm.removeEventListener('wheel', handleWheel);
|
|
96
|
+
elm.removeEventListener('touchstart', handleTouchStart);
|
|
97
|
+
elm.removeEventListener('touchmove', handleTouchMove);
|
|
98
|
+
});
|
|
99
|
+
clearTimeout(timeId);
|
|
100
|
+
};
|
|
101
|
+
}, [handleTouchMove, handleWheel, hasDelayed, wheelDelay]);
|
|
102
|
+
const enterControll = (e) => {
|
|
103
|
+
e.preventDefault();
|
|
104
|
+
document.body.style.overflow = 'hidden';
|
|
105
|
+
};
|
|
106
|
+
const leaveControll = () => {
|
|
107
|
+
document.body.style.overflow = 'auto';
|
|
108
|
+
};
|
|
109
|
+
(0, react_1.useEffect)(() => {
|
|
110
|
+
const elm1Div = div1Ref.current;
|
|
111
|
+
const elm2Div = div2Ref.current;
|
|
112
|
+
const elms = [elm1Div, elm2Div];
|
|
113
|
+
elms.forEach(elm => {
|
|
114
|
+
if (!elm)
|
|
115
|
+
return;
|
|
116
|
+
elm.addEventListener('mouseover', enterControll);
|
|
117
|
+
elm.addEventListener('mouseout', leaveControll);
|
|
118
|
+
elm.addEventListener('touchmove', enterControll);
|
|
119
|
+
elm.addEventListener('touchend', leaveControll);
|
|
120
|
+
});
|
|
121
|
+
return () => {
|
|
122
|
+
elms.forEach(elm => {
|
|
123
|
+
if (!elm)
|
|
124
|
+
return;
|
|
125
|
+
elm.removeEventListener('mouseover', enterControll);
|
|
126
|
+
elm.removeEventListener('mouseout', leaveControll);
|
|
127
|
+
elm.removeEventListener('touchmove', enterControll);
|
|
128
|
+
elm.addEventListener('touchend', leaveControll);
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
}, []);
|
|
132
|
+
let total = 0;
|
|
133
|
+
for (let i = 1; i < images.length; i++)
|
|
134
|
+
total += i;
|
|
135
|
+
const Total = total / images.length;
|
|
136
|
+
const clasess = className + ' ' + styles_module_css_1.default.outer;
|
|
137
|
+
return (react_1.default.createElement(framer_motion_1.LazyMotion, { features: framer_motion_1.domAnimation },
|
|
138
|
+
react_1.default.createElement("div", { ref: div1Ref, className: clasess, style: {
|
|
139
|
+
width: !vertical ? height + controller + 'px' : 'fit-content',
|
|
140
|
+
height: vertical ? width + controller + 'px' : 'fit-content',
|
|
141
|
+
padding: vertical
|
|
142
|
+
? controller + 'px' + ' ' + controller / 2 + 'px'
|
|
143
|
+
: controller / 2 + 'px' + ' ' + controller + 'px',
|
|
144
|
+
flexDirection: vertical ? 'column' : 'row'
|
|
145
|
+
} }, images.map((image, index) => {
|
|
146
|
+
const hasSelect = images[select] == images[index];
|
|
147
|
+
const reverseIndex = images.length - 1 - index;
|
|
148
|
+
return (react_1.default.createElement(framer_motion_1.m.img, { key: index, animate: {
|
|
149
|
+
y: hasSelect
|
|
150
|
+
? vertical
|
|
151
|
+
? (Total - index) * height +
|
|
152
|
+
(Total - index) * (margin * 2) +
|
|
153
|
+
selectOffsetY
|
|
154
|
+
: selectOffsetY
|
|
155
|
+
: 0,
|
|
156
|
+
x: hasSelect
|
|
157
|
+
? !vertical
|
|
158
|
+
? (Total - index) * width +
|
|
159
|
+
(Total - index) * (margin * 2) +
|
|
160
|
+
selectOffsetX
|
|
161
|
+
: selectOffsetX
|
|
162
|
+
: 0,
|
|
163
|
+
scale: hasSelect
|
|
164
|
+
? hasPick
|
|
165
|
+
? 0
|
|
166
|
+
: animate === null || animate === void 0 ? void 0 : animate.selectScale
|
|
167
|
+
: animate === null || animate === void 0 ? void 0 : animate.scale,
|
|
168
|
+
rotateY: hasSelect ? animate === null || animate === void 0 ? void 0 : animate.selectRotateY : animate === null || animate === void 0 ? void 0 : animate.rotateY,
|
|
169
|
+
rotateX: hasSelect ? animate === null || animate === void 0 ? void 0 : animate.selectRotateX : animate === null || animate === void 0 ? void 0 : animate.rotateX,
|
|
170
|
+
rotateZ: hasSelect ? animate === null || animate === void 0 ? void 0 : animate.selectRotateZ : animate === null || animate === void 0 ? void 0 : animate.rotateZ,
|
|
171
|
+
opacity: hasSelect
|
|
172
|
+
? hasPick
|
|
173
|
+
? 0
|
|
174
|
+
: animate === null || animate === void 0 ? void 0 : animate.selectOpacity
|
|
175
|
+
: animate === null || animate === void 0 ? void 0 : animate.opacity
|
|
176
|
+
}, initial: {
|
|
177
|
+
scale: hasSelect ? initial === null || initial === void 0 ? void 0 : initial.selectScale : initial === null || initial === void 0 ? void 0 : initial.scale,
|
|
178
|
+
rotateY: hasSelect ? initial === null || initial === void 0 ? void 0 : initial.selectRotateY : initial === null || initial === void 0 ? void 0 : initial.rotateY,
|
|
179
|
+
rotateX: hasSelect ? initial === null || initial === void 0 ? void 0 : initial.selectRotateX : initial === null || initial === void 0 ? void 0 : initial.rotateX,
|
|
180
|
+
rotateZ: hasSelect ? initial === null || initial === void 0 ? void 0 : initial.selectRotateZ : initial === null || initial === void 0 ? void 0 : initial.rotateZ,
|
|
181
|
+
opacity: hasSelect ? initial === null || initial === void 0 ? void 0 : initial.selectOpacity : initial === null || initial === void 0 ? void 0 : initial.opacity
|
|
182
|
+
}, transition: transition, onClick: () => {
|
|
183
|
+
setSelect(index);
|
|
184
|
+
hasSelect && setHasPick(true);
|
|
185
|
+
}, className: classImage + ' ' + classImageUnique + index, src: image.src, alt: image.alt, role: "button", style: {
|
|
186
|
+
zIndex: hasSelect
|
|
187
|
+
? hasPick
|
|
188
|
+
? 0
|
|
189
|
+
: images.length + 1
|
|
190
|
+
: reverseIndex,
|
|
191
|
+
cursor: hasSelect ? selectCursor : 'default',
|
|
192
|
+
width: width + 'px',
|
|
193
|
+
height: height + 'px',
|
|
194
|
+
margin: vertical ? margin + 'px' + ' 0' : '0 ' + margin + 'px'
|
|
195
|
+
} }));
|
|
196
|
+
})),
|
|
197
|
+
react_1.default.createElement("button", { onClick: () => shiftRight() }, hasPick ? 'true' : 'false'),
|
|
198
|
+
react_1.default.createElement(ScaleFilterImage_1.default, { onClick: () => setHasPick(false), hasPick: hasPick, classPick: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.classPick, white: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.white, alpha: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.alpha, blur: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.blur, scale: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.scale, offset: pickProperty === null || pickProperty === void 0 ? void 0 : pickProperty.offset, hasShift: hasShift, argRef: div2Ref, argKey: select, src: images[select].src, alt: images[select].alt, width: width, height: height, transition: pickTransition, zIndex: images.length + 1 })));
|
|
199
|
+
};
|
|
200
|
+
exports.MagicStraight = MagicStraight;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ScaleFilterImageProps } from '../../types';
|
|
3
|
+
declare const ScaleFilterImage: ({ onClick, classPick, hasPick, hasShift, argRef, argKey, src, alt, width, height, zIndex, white, alpha, blur, scale, offset, transition }: ScaleFilterImageProps) => React.JSX.Element;
|
|
4
|
+
export default ScaleFilterImage;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const framer_motion_1 = require("framer-motion");
|
|
8
|
+
const styles_module_css_1 = __importDefault(require("./styles.module.css"));
|
|
9
|
+
const ScaleFilterImage = ({ onClick, classPick, hasPick, hasShift, argRef, argKey, src, alt, width, height, zIndex, white, alpha = 0.4, blur = 4, scale = 2, offset = 200, transition }) => {
|
|
10
|
+
return (react_1.default.createElement(framer_motion_1.m.div, { role: "button", onClick: onClick, ref: argRef, className: styles_module_css_1.default.full_size, animate: {
|
|
11
|
+
zIndex: zIndex,
|
|
12
|
+
background: white
|
|
13
|
+
? `rgba(255, 255, 255, ${alpha})`
|
|
14
|
+
: `rgba(0, 0, 0, ${alpha})`,
|
|
15
|
+
backdropFilter: `blur(${blur}px)`,
|
|
16
|
+
opacity: hasPick ? 1 : 0,
|
|
17
|
+
pointerEvents: hasPick ? 'auto' : 'none'
|
|
18
|
+
}, initial: { background: 'none' }, transition: transition },
|
|
19
|
+
react_1.default.createElement(framer_motion_1.m.img, { className: classPick, onClick: e => e.stopPropagation(), key: argKey, src: src, alt: alt, width: width, height: height, animate: {
|
|
20
|
+
zIndex: zIndex + 1,
|
|
21
|
+
scale: scale,
|
|
22
|
+
opacity: hasPick ? 1 : 0,
|
|
23
|
+
x: 0
|
|
24
|
+
}, initial: { scale: 1, opacity: 0, x: hasShift ? offset : -offset }, transition: transition })));
|
|
25
|
+
};
|
|
26
|
+
exports.default = ScaleFilterImage;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MagicCircle = void 0;
|
|
3
|
+
exports.MagicStraight = exports.MagicCircle = void 0;
|
|
4
4
|
const MagicCircle_1 = require("./MagicCircle");
|
|
5
5
|
Object.defineProperty(exports, "MagicCircle", { enumerable: true, get: function () { return MagicCircle_1.MagicCircle; } });
|
|
6
|
+
const MagicStraight_1 = require("./MagicStraight");
|
|
7
|
+
Object.defineProperty(exports, "MagicStraight", { enumerable: true, get: function () { return MagicStraight_1.MagicStraight; } });
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Ref, MouseEventHandler } from 'react';
|
|
2
|
+
type ImageProperty = {
|
|
3
|
+
src: string;
|
|
4
|
+
alt: string;
|
|
5
|
+
};
|
|
6
|
+
type AnimationProperty = {
|
|
7
|
+
scale?: number;
|
|
8
|
+
rotateY?: number;
|
|
9
|
+
rotateX?: number;
|
|
10
|
+
rotateZ?: number;
|
|
11
|
+
opacity?: number;
|
|
12
|
+
selectScale?: number;
|
|
13
|
+
selectRotateY?: number;
|
|
14
|
+
selectRotateX?: number;
|
|
15
|
+
selectRotateZ?: number;
|
|
16
|
+
selectOpacity?: number;
|
|
17
|
+
};
|
|
18
|
+
type TransitionProperty = {
|
|
19
|
+
duration?: number;
|
|
20
|
+
type: undefined;
|
|
21
|
+
ease: number[] | 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | 'circIn' | 'circOut' | 'circInOut' | 'backIn' | 'backOut' | 'backInOut' | 'anticipate';
|
|
22
|
+
} | {
|
|
23
|
+
duration?: number;
|
|
24
|
+
type?: 'spring';
|
|
25
|
+
bounce?: number;
|
|
26
|
+
damping?: number;
|
|
27
|
+
mass?: number;
|
|
28
|
+
stiffness?: number;
|
|
29
|
+
velocity?: number;
|
|
30
|
+
restSpeed?: number;
|
|
31
|
+
restDelta?: number;
|
|
32
|
+
};
|
|
33
|
+
type PickProperty = {
|
|
34
|
+
classPick?: string;
|
|
35
|
+
white?: boolean;
|
|
36
|
+
alpha?: number;
|
|
37
|
+
blur?: number;
|
|
38
|
+
scale?: number;
|
|
39
|
+
offset?: number;
|
|
40
|
+
};
|
|
41
|
+
type MagicProperty = {
|
|
42
|
+
images: ImageProperty[];
|
|
43
|
+
height: number;
|
|
44
|
+
width: number;
|
|
45
|
+
controller: number;
|
|
46
|
+
start: number;
|
|
47
|
+
wheelDelay: number;
|
|
48
|
+
className?: string;
|
|
49
|
+
classImage?: string;
|
|
50
|
+
classImageUnique?: string;
|
|
51
|
+
animate?: AnimationProperty;
|
|
52
|
+
initial?: AnimationProperty;
|
|
53
|
+
transition?: TransitionProperty;
|
|
54
|
+
selectCursor?: 'pointer' | 'zoom-in' | 'crosshair' | 'help';
|
|
55
|
+
pickProperty?: PickProperty;
|
|
56
|
+
pickTransition?: TransitionProperty;
|
|
57
|
+
};
|
|
58
|
+
export type MagicCircleProps = MagicProperty & {
|
|
59
|
+
radius: number;
|
|
60
|
+
dynamic?: boolean;
|
|
61
|
+
};
|
|
62
|
+
export type MagicStraightProps = MagicProperty & {
|
|
63
|
+
vertical?: boolean;
|
|
64
|
+
margin?: number;
|
|
65
|
+
selectOffsetX?: number;
|
|
66
|
+
selectOffsetY?: number;
|
|
67
|
+
};
|
|
68
|
+
export type ScaleFilterImageProps = {
|
|
69
|
+
onClick: MouseEventHandler<HTMLDivElement>;
|
|
70
|
+
classPick?: string;
|
|
71
|
+
hasPick: boolean;
|
|
72
|
+
hasShift: boolean;
|
|
73
|
+
argRef: Ref<HTMLDivElement>;
|
|
74
|
+
argKey: number;
|
|
75
|
+
src: string;
|
|
76
|
+
alt: string;
|
|
77
|
+
width: number;
|
|
78
|
+
height: number;
|
|
79
|
+
zIndex: number;
|
|
80
|
+
white?: boolean;
|
|
81
|
+
alpha?: number;
|
|
82
|
+
blur?: number;
|
|
83
|
+
scale?: number;
|
|
84
|
+
offset?: number;
|
|
85
|
+
transition?: TransitionProperty;
|
|
86
|
+
};
|
|
87
|
+
export {};
|
package/dist/types.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-magic-card",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "image gallery component with framer motion",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
13
|
"tsc": "./node_modules/.bin/tsc",
|
|
14
|
-
"copy-css": "cp src/MagicCircle/main.css dist/MagicCircle/main.css",
|
|
15
14
|
"compile": "tsc && npm run copy-css",
|
|
15
|
+
"copy-css": "npm run copy-css1 && npm run copy-css2 && npm run copy-css3",
|
|
16
|
+
"copy-css1": "cp src/MagicCircle/styles.module.css dist/MagicCircle/styles.module.css",
|
|
17
|
+
"copy-css2": "cp src/MagicStraight/styles.module.css dist/MagicStraight/styles.module.css",
|
|
18
|
+
"copy-css3": "cp src/common/ScaleFilterImage/styles.module.css dist/common/ScaleFilterImage/styles.module.css",
|
|
16
19
|
"test": "test"
|
|
17
20
|
},
|
|
18
21
|
"keywords": [
|
|
@@ -29,6 +32,7 @@
|
|
|
29
32
|
"typescript": "^5.1.3"
|
|
30
33
|
},
|
|
31
34
|
"devDependencies": {
|
|
32
|
-
"@types/react": "^18.2.12"
|
|
35
|
+
"@types/react": "^18.2.12",
|
|
36
|
+
"@types/css-modules": "^1.0.2"
|
|
33
37
|
}
|
|
34
38
|
}
|
|
File without changes
|