@chao-component/bag-animation-ui 1.0.10 → 1.0.12
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 +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +129 -106
- package/dist/index.mjs +129 -106
- package/package.json +10 -7
package/dist/index.d.mts
CHANGED
|
@@ -5,12 +5,15 @@ interface BagAnimationProps {
|
|
|
5
5
|
frames?: string[];
|
|
6
6
|
defaultImage?: string;
|
|
7
7
|
defaultImageAlt?: string;
|
|
8
|
+
hasChances?: boolean;
|
|
8
9
|
swipeHintText?: string;
|
|
10
|
+
boxOpeningText?: string;
|
|
11
|
+
clickHintText?: string;
|
|
9
12
|
showMask?: boolean;
|
|
10
13
|
maskOpacity?: number;
|
|
11
14
|
maskBlur?: number;
|
|
12
15
|
}
|
|
13
|
-
declare function BagAnimation({ doneFunction, frames, defaultImage, defaultImageAlt, swipeHintText, 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;
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* 获取打包后的资源路径
|
package/dist/index.d.ts
CHANGED
|
@@ -5,12 +5,15 @@ interface BagAnimationProps {
|
|
|
5
5
|
frames?: string[];
|
|
6
6
|
defaultImage?: string;
|
|
7
7
|
defaultImageAlt?: string;
|
|
8
|
+
hasChances?: boolean;
|
|
8
9
|
swipeHintText?: string;
|
|
10
|
+
boxOpeningText?: string;
|
|
11
|
+
clickHintText?: string;
|
|
9
12
|
showMask?: boolean;
|
|
10
13
|
maskOpacity?: number;
|
|
11
14
|
maskBlur?: number;
|
|
12
15
|
}
|
|
13
|
-
declare function BagAnimation({ doneFunction, frames, defaultImage, defaultImageAlt, swipeHintText, 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;
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
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) {
|
|
@@ -807,6 +808,9 @@ function BagAnimation({
|
|
|
807
808
|
defaultImage = defaultImagePath,
|
|
808
809
|
defaultImageAlt = "Weedza Mystery Box",
|
|
809
810
|
swipeHintText = "Swipe to open",
|
|
811
|
+
boxOpeningText = "Box Opening...",
|
|
812
|
+
clickHintText = "Click to open",
|
|
813
|
+
hasChances = true,
|
|
810
814
|
showMask = true,
|
|
811
815
|
maskOpacity = 0.7,
|
|
812
816
|
maskBlur = 8
|
|
@@ -1030,124 +1034,143 @@ function BagAnimation({
|
|
|
1030
1034
|
}
|
|
1031
1035
|
};
|
|
1032
1036
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1033
|
-
isAnimating && /* @__PURE__ */ (0, import_jsx_runtime.
|
|
1034
|
-
|
|
1035
|
-
"
|
|
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",
|
|
1036
1040
|
{
|
|
1037
|
-
className: "
|
|
1038
|
-
|
|
1039
|
-
backgroundColor: `rgba(0, 0, 0, ${maskOpacity})`,
|
|
1040
|
-
backdropFilter: `blur(${maskBlur}px)`,
|
|
1041
|
-
WebkitBackdropFilter: `blur(${maskBlur}px)`
|
|
1042
|
-
// Safari 支持
|
|
1043
|
-
},
|
|
1044
|
-
onClick: (e) => {
|
|
1045
|
-
e.stopPropagation();
|
|
1046
|
-
}
|
|
1041
|
+
className: "font-bold text-lg md:text-xl mb-1 drop-shadow-lg text-theme_gold",
|
|
1042
|
+
children: clickHintText
|
|
1047
1043
|
}
|
|
1048
1044
|
),
|
|
1049
1045
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1050
|
-
|
|
1046
|
+
import_lucide_react.ChevronDown,
|
|
1051
1047
|
{
|
|
1052
|
-
className: "
|
|
1053
|
-
|
|
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
|
-
setThirdFrameProgress(progress);
|
|
1086
|
-
if (progress >= 95 && !hasTriggeredFourthFrame.current) {
|
|
1087
|
-
hasTriggeredFourthFrame.current = true;
|
|
1088
|
-
setIsPausedAtThird(false);
|
|
1089
|
-
setThirdFrameProgress(0);
|
|
1090
|
-
setFrame(3);
|
|
1091
|
-
}
|
|
1092
|
-
},
|
|
1093
|
-
onTouchEnd: (e) => {
|
|
1094
|
-
if (isPausedAtThird) {
|
|
1095
|
-
e.preventDefault();
|
|
1096
|
-
setThirdFrameProgress(0);
|
|
1097
|
-
setShowSwipeHint(true);
|
|
1098
|
-
}
|
|
1099
|
-
},
|
|
1100
|
-
className: "select-none cursor-pointer w-full h-full object-contain",
|
|
1101
|
-
style: {
|
|
1102
|
-
imageRendering: "pixelated",
|
|
1103
|
-
cursor: isPausedAtThird ? "grab" : "pointer",
|
|
1104
|
-
touchAction: "none",
|
|
1105
|
-
// 防止默認觸摸行為
|
|
1106
|
-
userSelect: "none",
|
|
1107
|
-
// 防止選中
|
|
1108
|
-
maxWidth: "100%",
|
|
1109
|
-
maxHeight: "100%"
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
),
|
|
1113
|
-
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: [
|
|
1114
1081
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1115
|
-
"
|
|
1082
|
+
"canvas",
|
|
1116
1083
|
{
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
{
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
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);
|
|
1128
1097
|
}
|
|
1129
|
-
|
|
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
|
+
}
|
|
1130
1132
|
}
|
|
1131
1133
|
),
|
|
1132
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
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"
|
|
1137
1171
|
}
|
|
1138
1172
|
)
|
|
1139
|
-
] })
|
|
1140
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1141
|
-
"img",
|
|
1142
|
-
{
|
|
1143
|
-
src: mysteryBoxImage,
|
|
1144
|
-
alt: mysteryBoxAlt,
|
|
1145
|
-
onClick: () => {
|
|
1146
|
-
setIsAnimating(true);
|
|
1147
|
-
},
|
|
1148
|
-
className: "w-36 h-36 md:w-96 md:h-96 object-contain relative z-10"
|
|
1149
|
-
}
|
|
1150
|
-
)
|
|
1173
|
+
] })
|
|
1151
1174
|
] });
|
|
1152
1175
|
}
|
|
1153
1176
|
// Annotate the CommonJS export names for ESM import in node:
|
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) {
|
|
@@ -791,6 +792,9 @@ function BagAnimation({
|
|
|
791
792
|
defaultImage = defaultImagePath,
|
|
792
793
|
defaultImageAlt = "Weedza Mystery Box",
|
|
793
794
|
swipeHintText = "Swipe to open",
|
|
795
|
+
boxOpeningText = "Box Opening...",
|
|
796
|
+
clickHintText = "Click to open",
|
|
797
|
+
hasChances = true,
|
|
794
798
|
showMask = true,
|
|
795
799
|
maskOpacity = 0.7,
|
|
796
800
|
maskBlur = 8
|
|
@@ -1014,124 +1018,143 @@ function BagAnimation({
|
|
|
1014
1018
|
}
|
|
1015
1019
|
};
|
|
1016
1020
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1017
|
-
isAnimating && /* @__PURE__ */ jsxs(
|
|
1018
|
-
|
|
1019
|
-
"
|
|
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",
|
|
1020
1024
|
{
|
|
1021
|
-
className: "
|
|
1022
|
-
|
|
1023
|
-
backgroundColor: `rgba(0, 0, 0, ${maskOpacity})`,
|
|
1024
|
-
backdropFilter: `blur(${maskBlur}px)`,
|
|
1025
|
-
WebkitBackdropFilter: `blur(${maskBlur}px)`
|
|
1026
|
-
// Safari 支持
|
|
1027
|
-
},
|
|
1028
|
-
onClick: (e) => {
|
|
1029
|
-
e.stopPropagation();
|
|
1030
|
-
}
|
|
1025
|
+
className: "font-bold text-lg md:text-xl mb-1 drop-shadow-lg text-theme_gold",
|
|
1026
|
+
children: clickHintText
|
|
1031
1027
|
}
|
|
1032
1028
|
),
|
|
1033
1029
|
/* @__PURE__ */ jsx(
|
|
1034
|
-
|
|
1030
|
+
ChevronDown,
|
|
1035
1031
|
{
|
|
1036
|
-
className: "
|
|
1037
|
-
|
|
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
|
-
setThirdFrameProgress(progress);
|
|
1070
|
-
if (progress >= 95 && !hasTriggeredFourthFrame.current) {
|
|
1071
|
-
hasTriggeredFourthFrame.current = true;
|
|
1072
|
-
setIsPausedAtThird(false);
|
|
1073
|
-
setThirdFrameProgress(0);
|
|
1074
|
-
setFrame(3);
|
|
1075
|
-
}
|
|
1076
|
-
},
|
|
1077
|
-
onTouchEnd: (e) => {
|
|
1078
|
-
if (isPausedAtThird) {
|
|
1079
|
-
e.preventDefault();
|
|
1080
|
-
setThirdFrameProgress(0);
|
|
1081
|
-
setShowSwipeHint(true);
|
|
1082
|
-
}
|
|
1083
|
-
},
|
|
1084
|
-
className: "select-none cursor-pointer w-full h-full object-contain",
|
|
1085
|
-
style: {
|
|
1086
|
-
imageRendering: "pixelated",
|
|
1087
|
-
cursor: isPausedAtThird ? "grab" : "pointer",
|
|
1088
|
-
touchAction: "none",
|
|
1089
|
-
// 防止默認觸摸行為
|
|
1090
|
-
userSelect: "none",
|
|
1091
|
-
// 防止選中
|
|
1092
|
-
maxWidth: "100%",
|
|
1093
|
-
maxHeight: "100%"
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
),
|
|
1097
|
-
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: [
|
|
1098
1065
|
/* @__PURE__ */ jsx(
|
|
1099
|
-
"
|
|
1066
|
+
"canvas",
|
|
1100
1067
|
{
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
{
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
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);
|
|
1112
1081
|
}
|
|
1113
|
-
|
|
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
|
+
}
|
|
1114
1116
|
}
|
|
1115
1117
|
),
|
|
1116
|
-
/* @__PURE__ */ jsx("
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
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"
|
|
1121
1155
|
}
|
|
1122
1156
|
)
|
|
1123
|
-
] })
|
|
1124
|
-
/* @__PURE__ */ jsx(
|
|
1125
|
-
"img",
|
|
1126
|
-
{
|
|
1127
|
-
src: mysteryBoxImage,
|
|
1128
|
-
alt: mysteryBoxAlt,
|
|
1129
|
-
onClick: () => {
|
|
1130
|
-
setIsAnimating(true);
|
|
1131
|
-
},
|
|
1132
|
-
className: "w-36 h-36 md:w-96 md:h-96 object-contain relative z-10"
|
|
1133
|
-
}
|
|
1134
|
-
)
|
|
1157
|
+
] })
|
|
1135
1158
|
] });
|
|
1136
1159
|
}
|
|
1137
1160
|
export {
|
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.12",
|
|
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
|
}
|