@chao-component/bag-animation-ui 1.0.11 → 1.0.13
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/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +131 -110
- package/dist/index.mjs +131 -110
- package/package.json +10 -7
package/dist/index.d.mts
CHANGED
|
@@ -5,13 +5,15 @@ interface BagAnimationProps {
|
|
|
5
5
|
frames?: string[];
|
|
6
6
|
defaultImage?: string;
|
|
7
7
|
defaultImageAlt?: string;
|
|
8
|
+
hasChances?: boolean;
|
|
8
9
|
swipeHintText?: string;
|
|
9
10
|
boxOpeningText?: string;
|
|
11
|
+
clickHintText?: string;
|
|
10
12
|
showMask?: boolean;
|
|
11
13
|
maskOpacity?: number;
|
|
12
14
|
maskBlur?: number;
|
|
13
15
|
}
|
|
14
|
-
declare function BagAnimation({ doneFunction, frames, defaultImage, defaultImageAlt, swipeHintText, boxOpeningText, showMask, maskOpacity, maskBlur }: BagAnimationProps): react_jsx_runtime.JSX.Element;
|
|
16
|
+
declare function BagAnimation({ doneFunction, frames, defaultImage, defaultImageAlt, swipeHintText, boxOpeningText, clickHintText, hasChances, showMask, maskOpacity, maskBlur }: BagAnimationProps): react_jsx_runtime.JSX.Element;
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* 获取打包后的资源路径
|
package/dist/index.d.ts
CHANGED
|
@@ -5,13 +5,15 @@ interface BagAnimationProps {
|
|
|
5
5
|
frames?: string[];
|
|
6
6
|
defaultImage?: string;
|
|
7
7
|
defaultImageAlt?: string;
|
|
8
|
+
hasChances?: boolean;
|
|
8
9
|
swipeHintText?: string;
|
|
9
10
|
boxOpeningText?: string;
|
|
11
|
+
clickHintText?: string;
|
|
10
12
|
showMask?: boolean;
|
|
11
13
|
maskOpacity?: number;
|
|
12
14
|
maskBlur?: number;
|
|
13
15
|
}
|
|
14
|
-
declare function BagAnimation({ doneFunction, frames, defaultImage, defaultImageAlt, swipeHintText, boxOpeningText, showMask, maskOpacity, maskBlur }: BagAnimationProps): react_jsx_runtime.JSX.Element;
|
|
16
|
+
declare function BagAnimation({ doneFunction, frames, defaultImage, defaultImageAlt, swipeHintText, boxOpeningText, clickHintText, hasChances, showMask, maskOpacity, maskBlur }: BagAnimationProps): react_jsx_runtime.JSX.Element;
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* 获取打包后的资源路径
|
package/dist/index.js
CHANGED
|
@@ -785,6 +785,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
785
785
|
// src/BagAnimation.tsx
|
|
786
786
|
var import_react = require("react");
|
|
787
787
|
var import_apng_js = __toESM(require_lib());
|
|
788
|
+
var import_lucide_react = require("lucide-react");
|
|
788
789
|
|
|
789
790
|
// src/assets.ts
|
|
790
791
|
function getAssetPath(relativePath) {
|
|
@@ -808,6 +809,8 @@ function BagAnimation({
|
|
|
808
809
|
defaultImageAlt = "Weedza Mystery Box",
|
|
809
810
|
swipeHintText = "Swipe to open",
|
|
810
811
|
boxOpeningText = "Box Opening...",
|
|
812
|
+
clickHintText = "Click to open",
|
|
813
|
+
hasChances = true,
|
|
811
814
|
showMask = true,
|
|
812
815
|
maskOpacity = 0.7,
|
|
813
816
|
maskBlur = 8
|
|
@@ -1030,127 +1033,145 @@ function BagAnimation({
|
|
|
1030
1033
|
setShowSwipeHint(true);
|
|
1031
1034
|
}
|
|
1032
1035
|
};
|
|
1033
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
1034
|
-
isAnimating && /* @__PURE__ */ (0, import_jsx_runtime.
|
|
1035
|
-
|
|
1036
|
-
"
|
|
1036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1037
|
+
!isAnimating && hasChances && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute top-8 left-[calc(50%-0px)] transform -translate-x-1/2 z-50 pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col items-center animate-bounce", children: [
|
|
1038
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1039
|
+
"p",
|
|
1037
1040
|
{
|
|
1038
|
-
className: "
|
|
1039
|
-
|
|
1040
|
-
backgroundColor: `rgba(0, 0, 0, ${maskOpacity})`,
|
|
1041
|
-
backdropFilter: `blur(${maskBlur}px)`,
|
|
1042
|
-
WebkitBackdropFilter: `blur(${maskBlur}px)`
|
|
1043
|
-
// Safari 支持
|
|
1044
|
-
},
|
|
1045
|
-
onClick: (e) => {
|
|
1046
|
-
e.stopPropagation();
|
|
1047
|
-
}
|
|
1041
|
+
className: "font-bold text-lg md:text-xl mb-1 drop-shadow-lg text-theme_gold",
|
|
1042
|
+
children: clickHintText
|
|
1048
1043
|
}
|
|
1049
1044
|
),
|
|
1050
1045
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1051
|
-
|
|
1046
|
+
import_lucide_react.ChevronDown,
|
|
1052
1047
|
{
|
|
1053
|
-
className: "
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
setThirdFrameProgress(progress);
|
|
1087
|
-
if (progress >= 95 && !hasTriggeredFourthFrame.current) {
|
|
1088
|
-
hasTriggeredFourthFrame.current = true;
|
|
1089
|
-
setIsPausedAtThird(false);
|
|
1090
|
-
setThirdFrameProgress(0);
|
|
1091
|
-
setFrame(3);
|
|
1092
|
-
}
|
|
1093
|
-
},
|
|
1094
|
-
onTouchEnd: (e) => {
|
|
1095
|
-
if (isPausedAtThird) {
|
|
1096
|
-
e.preventDefault();
|
|
1097
|
-
setThirdFrameProgress(0);
|
|
1098
|
-
setShowSwipeHint(true);
|
|
1099
|
-
}
|
|
1100
|
-
},
|
|
1101
|
-
className: "select-none cursor-pointer w-full h-full object-contain",
|
|
1102
|
-
style: {
|
|
1103
|
-
imageRendering: "pixelated",
|
|
1104
|
-
cursor: isPausedAtThird ? "grab" : "pointer",
|
|
1105
|
-
touchAction: "none",
|
|
1106
|
-
// 防止默認觸摸行為
|
|
1107
|
-
userSelect: "none",
|
|
1108
|
-
// 防止選中
|
|
1109
|
-
maxWidth: "100%",
|
|
1110
|
-
maxHeight: "100%"
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
),
|
|
1114
|
-
isPausedAtThird && showSwipeHint && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute bottom-8 left-1/2 transform -translate-x-1/2 bg-black/70 text-white px-6 py-3 rounded-full text-sm md:text-base font-medium animate-pulse pointer-events-none z-20", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1048
|
+
className: "h-8 w-8 md:h-10 md:w-10 text-lime-500 drop-shadow-lg text-theme_gold",
|
|
1049
|
+
strokeWidth: 4
|
|
1050
|
+
}
|
|
1051
|
+
)
|
|
1052
|
+
] }) }),
|
|
1053
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex w-full relative justify-center items-center", children: [
|
|
1054
|
+
isAnimating && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1055
|
+
showMask && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1056
|
+
"div",
|
|
1057
|
+
{
|
|
1058
|
+
className: "fixed inset-0 z-[99]",
|
|
1059
|
+
style: {
|
|
1060
|
+
backgroundColor: `rgba(0, 0, 0, ${maskOpacity})`,
|
|
1061
|
+
backdropFilter: `blur(${maskBlur}px)`,
|
|
1062
|
+
WebkitBackdropFilter: `blur(${maskBlur}px)`
|
|
1063
|
+
// Safari 支持
|
|
1064
|
+
},
|
|
1065
|
+
onClick: (e) => {
|
|
1066
|
+
e.stopPropagation();
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
),
|
|
1070
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1071
|
+
"div",
|
|
1072
|
+
{
|
|
1073
|
+
className: "fixed inset-0 z-[100] flex items-center justify-center pointer-events-none",
|
|
1074
|
+
style: { pointerEvents: "none" },
|
|
1075
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1076
|
+
"div",
|
|
1077
|
+
{
|
|
1078
|
+
className: "relative w-full max-w-[90vw] max-h-[90vh] flex items-center justify-center pointer-events-auto",
|
|
1079
|
+
style: { pointerEvents: "auto" },
|
|
1080
|
+
children: [
|
|
1115
1081
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1116
|
-
"
|
|
1082
|
+
"canvas",
|
|
1117
1083
|
{
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
{
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1084
|
+
ref: canvasRef,
|
|
1085
|
+
onMouseDown,
|
|
1086
|
+
onMouseMove,
|
|
1087
|
+
onMouseUp,
|
|
1088
|
+
onMouseLeave: onMouseUp,
|
|
1089
|
+
onTouchStart: (e) => {
|
|
1090
|
+
if (isPausedAtThird && canvasRef.current) {
|
|
1091
|
+
const touch = e.touches[0];
|
|
1092
|
+
const rect = canvasRef.current.getBoundingClientRect();
|
|
1093
|
+
const touchGap = touch.clientX - rect.left;
|
|
1094
|
+
const initialProgress = Math.max(0, Math.min(100, touchGap / rect.width * 100));
|
|
1095
|
+
setThirdFrameProgress(initialProgress);
|
|
1096
|
+
setShowSwipeHint(false);
|
|
1129
1097
|
}
|
|
1130
|
-
|
|
1098
|
+
},
|
|
1099
|
+
onTouchMove: (e) => {
|
|
1100
|
+
if (!isPausedAtThird || !canvasRef.current || hasTriggeredFourthFrame.current) return;
|
|
1101
|
+
const touch = e.touches[0];
|
|
1102
|
+
const rect = canvasRef.current.getBoundingClientRect();
|
|
1103
|
+
const relativeX = touch.clientX - rect.left;
|
|
1104
|
+
const canvasWidth = rect.width;
|
|
1105
|
+
const progress = Math.max(0, Math.min(100, relativeX / canvasWidth * 100));
|
|
1106
|
+
setThirdFrameProgress(progress);
|
|
1107
|
+
if (progress >= 95 && !hasTriggeredFourthFrame.current) {
|
|
1108
|
+
hasTriggeredFourthFrame.current = true;
|
|
1109
|
+
setIsPausedAtThird(false);
|
|
1110
|
+
setThirdFrameProgress(0);
|
|
1111
|
+
setFrame(3);
|
|
1112
|
+
}
|
|
1113
|
+
},
|
|
1114
|
+
onTouchEnd: (e) => {
|
|
1115
|
+
if (isPausedAtThird) {
|
|
1116
|
+
e.preventDefault();
|
|
1117
|
+
setThirdFrameProgress(0);
|
|
1118
|
+
setShowSwipeHint(true);
|
|
1119
|
+
}
|
|
1120
|
+
},
|
|
1121
|
+
className: "select-none cursor-pointer w-full h-full object-contain",
|
|
1122
|
+
style: {
|
|
1123
|
+
imageRendering: "pixelated",
|
|
1124
|
+
cursor: isPausedAtThird ? "grab" : "pointer",
|
|
1125
|
+
touchAction: "none",
|
|
1126
|
+
// 防止默認觸摸行為
|
|
1127
|
+
userSelect: "none",
|
|
1128
|
+
// 防止選中
|
|
1129
|
+
maxWidth: "100%",
|
|
1130
|
+
maxHeight: "100%"
|
|
1131
|
+
}
|
|
1131
1132
|
}
|
|
1132
1133
|
),
|
|
1133
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1134
|
+
isPausedAtThird && showSwipeHint && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute bottom-8 left-1/2 transform -translate-x-1/2 bg-black/70 text-white px-6 py-3 rounded-full text-sm md:text-base font-medium animate-pulse pointer-events-none z-20", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1135
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1136
|
+
"svg",
|
|
1137
|
+
{
|
|
1138
|
+
className: "w-5 h-5 md:w-6 md:h-6",
|
|
1139
|
+
fill: "none",
|
|
1140
|
+
stroke: "currentColor",
|
|
1141
|
+
viewBox: "0 0 24 24",
|
|
1142
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1143
|
+
"path",
|
|
1144
|
+
{
|
|
1145
|
+
strokeLinecap: "round",
|
|
1146
|
+
strokeLinejoin: "round",
|
|
1147
|
+
strokeWidth: 2,
|
|
1148
|
+
d: "M13 7l5 5m0 0l-5 5m5-5H6"
|
|
1149
|
+
}
|
|
1150
|
+
)
|
|
1151
|
+
}
|
|
1152
|
+
),
|
|
1153
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: swipeHintText })
|
|
1154
|
+
] }) })
|
|
1155
|
+
]
|
|
1156
|
+
}
|
|
1157
|
+
)
|
|
1158
|
+
}
|
|
1159
|
+
),
|
|
1160
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "fixed z-[101] top-0 left-0 w-full h-[10%] flex justify-center items-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-theme_gold animate-pulse text-sm md:text-base text-center z-[101]", children: boxOpeningText }) })
|
|
1161
|
+
] }),
|
|
1162
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1163
|
+
"img",
|
|
1164
|
+
{
|
|
1165
|
+
src: mysteryBoxImage,
|
|
1166
|
+
alt: mysteryBoxAlt,
|
|
1167
|
+
onClick: () => {
|
|
1168
|
+
setIsAnimating(true);
|
|
1169
|
+
},
|
|
1170
|
+
className: "w-36 h-36 md:w-96 md:h-96 object-contain relative z-10"
|
|
1138
1171
|
}
|
|
1139
|
-
)
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1143
|
-
"img",
|
|
1144
|
-
{
|
|
1145
|
-
src: mysteryBoxImage,
|
|
1146
|
-
alt: mysteryBoxAlt,
|
|
1147
|
-
onClick: () => {
|
|
1148
|
-
setIsAnimating(true);
|
|
1149
|
-
},
|
|
1150
|
-
className: "w-36 h-36 md:w-96 md:h-96 object-contain relative z-10"
|
|
1151
|
-
}
|
|
1152
|
-
)
|
|
1153
|
-
] }) });
|
|
1172
|
+
)
|
|
1173
|
+
] })
|
|
1174
|
+
] });
|
|
1154
1175
|
}
|
|
1155
1176
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1156
1177
|
0 && (module.exports = {
|
package/dist/index.mjs
CHANGED
|
@@ -769,6 +769,7 @@ var require_lib = __commonJS({
|
|
|
769
769
|
// src/BagAnimation.tsx
|
|
770
770
|
var import_apng_js = __toESM(require_lib());
|
|
771
771
|
import { useEffect, useRef, useState } from "react";
|
|
772
|
+
import { ChevronDown } from "lucide-react";
|
|
772
773
|
|
|
773
774
|
// src/assets.ts
|
|
774
775
|
function getAssetPath(relativePath) {
|
|
@@ -792,6 +793,8 @@ function BagAnimation({
|
|
|
792
793
|
defaultImageAlt = "Weedza Mystery Box",
|
|
793
794
|
swipeHintText = "Swipe to open",
|
|
794
795
|
boxOpeningText = "Box Opening...",
|
|
796
|
+
clickHintText = "Click to open",
|
|
797
|
+
hasChances = true,
|
|
795
798
|
showMask = true,
|
|
796
799
|
maskOpacity = 0.7,
|
|
797
800
|
maskBlur = 8
|
|
@@ -1014,127 +1017,145 @@ function BagAnimation({
|
|
|
1014
1017
|
setShowSwipeHint(true);
|
|
1015
1018
|
}
|
|
1016
1019
|
};
|
|
1017
|
-
return /* @__PURE__ */
|
|
1018
|
-
isAnimating && /* @__PURE__ */ jsxs(
|
|
1019
|
-
|
|
1020
|
-
"
|
|
1020
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1021
|
+
!isAnimating && hasChances && /* @__PURE__ */ jsx("div", { className: "absolute top-8 left-[calc(50%-0px)] transform -translate-x-1/2 z-50 pointer-events-none", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center animate-bounce", children: [
|
|
1022
|
+
/* @__PURE__ */ jsx(
|
|
1023
|
+
"p",
|
|
1021
1024
|
{
|
|
1022
|
-
className: "
|
|
1023
|
-
|
|
1024
|
-
backgroundColor: `rgba(0, 0, 0, ${maskOpacity})`,
|
|
1025
|
-
backdropFilter: `blur(${maskBlur}px)`,
|
|
1026
|
-
WebkitBackdropFilter: `blur(${maskBlur}px)`
|
|
1027
|
-
// Safari 支持
|
|
1028
|
-
},
|
|
1029
|
-
onClick: (e) => {
|
|
1030
|
-
e.stopPropagation();
|
|
1031
|
-
}
|
|
1025
|
+
className: "font-bold text-lg md:text-xl mb-1 drop-shadow-lg text-theme_gold",
|
|
1026
|
+
children: clickHintText
|
|
1032
1027
|
}
|
|
1033
1028
|
),
|
|
1034
1029
|
/* @__PURE__ */ jsx(
|
|
1035
|
-
|
|
1030
|
+
ChevronDown,
|
|
1036
1031
|
{
|
|
1037
|
-
className: "
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
setThirdFrameProgress(progress);
|
|
1071
|
-
if (progress >= 95 && !hasTriggeredFourthFrame.current) {
|
|
1072
|
-
hasTriggeredFourthFrame.current = true;
|
|
1073
|
-
setIsPausedAtThird(false);
|
|
1074
|
-
setThirdFrameProgress(0);
|
|
1075
|
-
setFrame(3);
|
|
1076
|
-
}
|
|
1077
|
-
},
|
|
1078
|
-
onTouchEnd: (e) => {
|
|
1079
|
-
if (isPausedAtThird) {
|
|
1080
|
-
e.preventDefault();
|
|
1081
|
-
setThirdFrameProgress(0);
|
|
1082
|
-
setShowSwipeHint(true);
|
|
1083
|
-
}
|
|
1084
|
-
},
|
|
1085
|
-
className: "select-none cursor-pointer w-full h-full object-contain",
|
|
1086
|
-
style: {
|
|
1087
|
-
imageRendering: "pixelated",
|
|
1088
|
-
cursor: isPausedAtThird ? "grab" : "pointer",
|
|
1089
|
-
touchAction: "none",
|
|
1090
|
-
// 防止默認觸摸行為
|
|
1091
|
-
userSelect: "none",
|
|
1092
|
-
// 防止選中
|
|
1093
|
-
maxWidth: "100%",
|
|
1094
|
-
maxHeight: "100%"
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
),
|
|
1098
|
-
isPausedAtThird && showSwipeHint && /* @__PURE__ */ jsx("div", { className: "absolute bottom-8 left-1/2 transform -translate-x-1/2 bg-black/70 text-white px-6 py-3 rounded-full text-sm md:text-base font-medium animate-pulse pointer-events-none z-20", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1032
|
+
className: "h-8 w-8 md:h-10 md:w-10 text-lime-500 drop-shadow-lg text-theme_gold",
|
|
1033
|
+
strokeWidth: 4
|
|
1034
|
+
}
|
|
1035
|
+
)
|
|
1036
|
+
] }) }),
|
|
1037
|
+
/* @__PURE__ */ jsxs("div", { className: "flex w-full relative justify-center items-center", children: [
|
|
1038
|
+
isAnimating && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1039
|
+
showMask && /* @__PURE__ */ jsx(
|
|
1040
|
+
"div",
|
|
1041
|
+
{
|
|
1042
|
+
className: "fixed inset-0 z-[99]",
|
|
1043
|
+
style: {
|
|
1044
|
+
backgroundColor: `rgba(0, 0, 0, ${maskOpacity})`,
|
|
1045
|
+
backdropFilter: `blur(${maskBlur}px)`,
|
|
1046
|
+
WebkitBackdropFilter: `blur(${maskBlur}px)`
|
|
1047
|
+
// Safari 支持
|
|
1048
|
+
},
|
|
1049
|
+
onClick: (e) => {
|
|
1050
|
+
e.stopPropagation();
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
),
|
|
1054
|
+
/* @__PURE__ */ jsx(
|
|
1055
|
+
"div",
|
|
1056
|
+
{
|
|
1057
|
+
className: "fixed inset-0 z-[100] flex items-center justify-center pointer-events-none",
|
|
1058
|
+
style: { pointerEvents: "none" },
|
|
1059
|
+
children: /* @__PURE__ */ jsxs(
|
|
1060
|
+
"div",
|
|
1061
|
+
{
|
|
1062
|
+
className: "relative w-full max-w-[90vw] max-h-[90vh] flex items-center justify-center pointer-events-auto",
|
|
1063
|
+
style: { pointerEvents: "auto" },
|
|
1064
|
+
children: [
|
|
1099
1065
|
/* @__PURE__ */ jsx(
|
|
1100
|
-
"
|
|
1066
|
+
"canvas",
|
|
1101
1067
|
{
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
{
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1068
|
+
ref: canvasRef,
|
|
1069
|
+
onMouseDown,
|
|
1070
|
+
onMouseMove,
|
|
1071
|
+
onMouseUp,
|
|
1072
|
+
onMouseLeave: onMouseUp,
|
|
1073
|
+
onTouchStart: (e) => {
|
|
1074
|
+
if (isPausedAtThird && canvasRef.current) {
|
|
1075
|
+
const touch = e.touches[0];
|
|
1076
|
+
const rect = canvasRef.current.getBoundingClientRect();
|
|
1077
|
+
const touchGap = touch.clientX - rect.left;
|
|
1078
|
+
const initialProgress = Math.max(0, Math.min(100, touchGap / rect.width * 100));
|
|
1079
|
+
setThirdFrameProgress(initialProgress);
|
|
1080
|
+
setShowSwipeHint(false);
|
|
1113
1081
|
}
|
|
1114
|
-
|
|
1082
|
+
},
|
|
1083
|
+
onTouchMove: (e) => {
|
|
1084
|
+
if (!isPausedAtThird || !canvasRef.current || hasTriggeredFourthFrame.current) return;
|
|
1085
|
+
const touch = e.touches[0];
|
|
1086
|
+
const rect = canvasRef.current.getBoundingClientRect();
|
|
1087
|
+
const relativeX = touch.clientX - rect.left;
|
|
1088
|
+
const canvasWidth = rect.width;
|
|
1089
|
+
const progress = Math.max(0, Math.min(100, relativeX / canvasWidth * 100));
|
|
1090
|
+
setThirdFrameProgress(progress);
|
|
1091
|
+
if (progress >= 95 && !hasTriggeredFourthFrame.current) {
|
|
1092
|
+
hasTriggeredFourthFrame.current = true;
|
|
1093
|
+
setIsPausedAtThird(false);
|
|
1094
|
+
setThirdFrameProgress(0);
|
|
1095
|
+
setFrame(3);
|
|
1096
|
+
}
|
|
1097
|
+
},
|
|
1098
|
+
onTouchEnd: (e) => {
|
|
1099
|
+
if (isPausedAtThird) {
|
|
1100
|
+
e.preventDefault();
|
|
1101
|
+
setThirdFrameProgress(0);
|
|
1102
|
+
setShowSwipeHint(true);
|
|
1103
|
+
}
|
|
1104
|
+
},
|
|
1105
|
+
className: "select-none cursor-pointer w-full h-full object-contain",
|
|
1106
|
+
style: {
|
|
1107
|
+
imageRendering: "pixelated",
|
|
1108
|
+
cursor: isPausedAtThird ? "grab" : "pointer",
|
|
1109
|
+
touchAction: "none",
|
|
1110
|
+
// 防止默認觸摸行為
|
|
1111
|
+
userSelect: "none",
|
|
1112
|
+
// 防止選中
|
|
1113
|
+
maxWidth: "100%",
|
|
1114
|
+
maxHeight: "100%"
|
|
1115
|
+
}
|
|
1115
1116
|
}
|
|
1116
1117
|
),
|
|
1117
|
-
/* @__PURE__ */ jsx("
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1118
|
+
isPausedAtThird && showSwipeHint && /* @__PURE__ */ jsx("div", { className: "absolute bottom-8 left-1/2 transform -translate-x-1/2 bg-black/70 text-white px-6 py-3 rounded-full text-sm md:text-base font-medium animate-pulse pointer-events-none z-20", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1119
|
+
/* @__PURE__ */ jsx(
|
|
1120
|
+
"svg",
|
|
1121
|
+
{
|
|
1122
|
+
className: "w-5 h-5 md:w-6 md:h-6",
|
|
1123
|
+
fill: "none",
|
|
1124
|
+
stroke: "currentColor",
|
|
1125
|
+
viewBox: "0 0 24 24",
|
|
1126
|
+
children: /* @__PURE__ */ jsx(
|
|
1127
|
+
"path",
|
|
1128
|
+
{
|
|
1129
|
+
strokeLinecap: "round",
|
|
1130
|
+
strokeLinejoin: "round",
|
|
1131
|
+
strokeWidth: 2,
|
|
1132
|
+
d: "M13 7l5 5m0 0l-5 5m5-5H6"
|
|
1133
|
+
}
|
|
1134
|
+
)
|
|
1135
|
+
}
|
|
1136
|
+
),
|
|
1137
|
+
/* @__PURE__ */ jsx("span", { children: swipeHintText })
|
|
1138
|
+
] }) })
|
|
1139
|
+
]
|
|
1140
|
+
}
|
|
1141
|
+
)
|
|
1142
|
+
}
|
|
1143
|
+
),
|
|
1144
|
+
/* @__PURE__ */ jsx("div", { className: "fixed z-[101] top-0 left-0 w-full h-[10%] flex justify-center items-center", children: /* @__PURE__ */ jsx("p", { className: "text-theme_gold animate-pulse text-sm md:text-base text-center z-[101]", children: boxOpeningText }) })
|
|
1145
|
+
] }),
|
|
1146
|
+
/* @__PURE__ */ jsx(
|
|
1147
|
+
"img",
|
|
1148
|
+
{
|
|
1149
|
+
src: mysteryBoxImage,
|
|
1150
|
+
alt: mysteryBoxAlt,
|
|
1151
|
+
onClick: () => {
|
|
1152
|
+
setIsAnimating(true);
|
|
1153
|
+
},
|
|
1154
|
+
className: "w-36 h-36 md:w-96 md:h-96 object-contain relative z-10"
|
|
1122
1155
|
}
|
|
1123
|
-
)
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
/* @__PURE__ */ jsx(
|
|
1127
|
-
"img",
|
|
1128
|
-
{
|
|
1129
|
-
src: mysteryBoxImage,
|
|
1130
|
-
alt: mysteryBoxAlt,
|
|
1131
|
-
onClick: () => {
|
|
1132
|
-
setIsAnimating(true);
|
|
1133
|
-
},
|
|
1134
|
-
className: "w-36 h-36 md:w-96 md:h-96 object-contain relative z-10"
|
|
1135
|
-
}
|
|
1136
|
-
)
|
|
1137
|
-
] }) });
|
|
1156
|
+
)
|
|
1157
|
+
] })
|
|
1158
|
+
] });
|
|
1138
1159
|
}
|
|
1139
1160
|
export {
|
|
1140
1161
|
BagAnimation,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chao-component/bag-animation-ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -37,17 +37,20 @@
|
|
|
37
37
|
"react-dom": "^19.2.3"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"apng-js": "^1.1.5",
|
|
41
40
|
"@types/react": "^19.2.7",
|
|
42
41
|
"@types/react-dom": "^19.2.3",
|
|
43
|
-
"tsup": "^8.5.1",
|
|
44
|
-
"typescript": "^5.9.3",
|
|
45
|
-
"vite": "^5.0.0",
|
|
46
42
|
"@vitejs/plugin-react": "^4.2.0",
|
|
43
|
+
"apng-js": "^1.1.5",
|
|
44
|
+
"autoprefixer": "^10.4.0",
|
|
45
|
+
"postcss": "^8.4.0",
|
|
47
46
|
"react": "^19.2.3",
|
|
48
47
|
"react-dom": "^19.2.3",
|
|
49
48
|
"tailwindcss": "^3.4.0",
|
|
50
|
-
"
|
|
51
|
-
"
|
|
49
|
+
"tsup": "^8.5.1",
|
|
50
|
+
"typescript": "^5.9.3",
|
|
51
|
+
"vite": "^5.0.0"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"lucide-react": "^0.562.0"
|
|
52
55
|
}
|
|
53
56
|
}
|