anim-3d-obj 2.0.1 → 2.0.2
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.cjs +35 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +38 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +20 -2
- package/dist/index.d.ts +20 -2
- package/dist/index.js +20 -219
- package/dist/index.js.map +1 -1
- package/package.json +23 -26
- package/dist/components/Obj.d.mts +0 -50
- package/dist/components/Obj.d.ts +0 -50
- package/dist/components/Obj.js +0 -231
- package/dist/components/Obj.js.map +0 -1
- package/dist/components/Obj.mjs +0 -206
- package/dist/components/Obj.mjs.map +0 -1
- package/dist/index.mjs +0 -205
- package/dist/index.mjs.map +0 -1
- package/dist/obj-PY72GEW6.css +0 -39
package/dist/components/Obj.js
DELETED
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/components/Obj.tsx
|
|
21
|
-
var Obj_exports = {};
|
|
22
|
-
__export(Obj_exports, {
|
|
23
|
-
Obj: () => Obj,
|
|
24
|
-
default: () => Obj_default
|
|
25
|
-
});
|
|
26
|
-
module.exports = __toCommonJS(Obj_exports);
|
|
27
|
-
var import_react = require("react");
|
|
28
|
-
|
|
29
|
-
// src/keyframes.ts
|
|
30
|
-
function ensureStyleTag() {
|
|
31
|
-
let tag = document.getElementById(
|
|
32
|
-
"anim3d-keyframes"
|
|
33
|
-
);
|
|
34
|
-
if (!tag) {
|
|
35
|
-
tag = document.createElement("style");
|
|
36
|
-
tag.id = "anim3d-keyframes";
|
|
37
|
-
document.head.appendChild(tag);
|
|
38
|
-
}
|
|
39
|
-
return tag;
|
|
40
|
-
}
|
|
41
|
-
function inject(css) {
|
|
42
|
-
if (typeof document === "undefined") return;
|
|
43
|
-
const tag = ensureStyleTag();
|
|
44
|
-
tag.appendChild(document.createTextNode(css));
|
|
45
|
-
}
|
|
46
|
-
function builtInKeyframes(name, cfg) {
|
|
47
|
-
const hi = cfg.degreesHi ?? 15;
|
|
48
|
-
const lo = cfg.degreesLow ?? -15;
|
|
49
|
-
switch (name) {
|
|
50
|
-
case "Y360":
|
|
51
|
-
return `@keyframes Y360 { from { transform: rotateY(0deg) } to { transform: rotateY(360deg) } }`;
|
|
52
|
-
case "X360":
|
|
53
|
-
return `@keyframes X360 { from { transform: rotateX(0deg) } to { transform: rotateX(360deg) } }`;
|
|
54
|
-
case "Z360":
|
|
55
|
-
return `@keyframes Z360 { from { transform: rotateZ(0deg) } to { transform: rotateZ(360deg) } }`;
|
|
56
|
-
case "rockY":
|
|
57
|
-
return `@keyframes rockY { 0%{ transform: rotateY(${lo}deg) } 50%{ transform: rotateY(${hi}deg) } 100%{ transform: rotateY(${lo}deg) } }`;
|
|
58
|
-
case "rockX":
|
|
59
|
-
return `@keyframes rockX { 0%{ transform: rotateX(${lo}deg) } 50%{ transform: rotateX(${hi}deg) } 100%{ transform: rotateX(${lo}deg) } }`;
|
|
60
|
-
default:
|
|
61
|
-
return "";
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
function resolveAnimation(cfg) {
|
|
65
|
-
if (!cfg) return null;
|
|
66
|
-
const name = cfg.name;
|
|
67
|
-
const builtIn = builtInKeyframes(name, cfg);
|
|
68
|
-
if (builtIn) {
|
|
69
|
-
const marker = `/*kf-${name}*/`;
|
|
70
|
-
if (typeof document !== "undefined") {
|
|
71
|
-
const tag = ensureStyleTag();
|
|
72
|
-
if (!tag.innerHTML.includes(marker)) {
|
|
73
|
-
inject(`${builtIn}
|
|
74
|
-
${marker}`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return name;
|
|
78
|
-
}
|
|
79
|
-
return name;
|
|
80
|
-
}
|
|
81
|
-
function toAnimationShorthand(cfg) {
|
|
82
|
-
const name = resolveAnimation(cfg);
|
|
83
|
-
if (!cfg || !name) return null;
|
|
84
|
-
const dur = (cfg.duration ?? 10) + "s";
|
|
85
|
-
const delay = (cfg.delay ?? 0) + "s";
|
|
86
|
-
const iter = cfg.iterationCount ?? "infinite";
|
|
87
|
-
const dir = cfg.direction ?? "normal";
|
|
88
|
-
const timing = cfg.timing ?? "linear";
|
|
89
|
-
const fill = cfg.fillMode ?? "forwards";
|
|
90
|
-
const play = cfg.animationPlayState ?? "running";
|
|
91
|
-
return `${name} ${dur} ${timing} ${delay} ${iter} ${dir} ${fill} ${play}`;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// src/components/Obj.tsx
|
|
95
|
-
var import_obj = require("../obj-PY72GEW6.css");
|
|
96
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
97
|
-
function faceTransform(name, w, h, d) {
|
|
98
|
-
const z = d / 2;
|
|
99
|
-
switch (name) {
|
|
100
|
-
case "front":
|
|
101
|
-
return `translate3d(-50%, -50%, ${z}px)`;
|
|
102
|
-
case "back":
|
|
103
|
-
return `translate3d(-50%, -50%, ${-z}px) rotateY(180deg)`;
|
|
104
|
-
case "left":
|
|
105
|
-
return `translate3d(-50%, -50%, 0) rotateY(-90deg) translateZ(${w / 2}px)`;
|
|
106
|
-
case "right":
|
|
107
|
-
return `translate3d(-50%, -50%, 0) rotateY(90deg) translateZ(${w / 2}px)`;
|
|
108
|
-
case "top":
|
|
109
|
-
return `translate3d(-50%, -50%, 0) rotateX(90deg) translateZ(${h / 2}px)`;
|
|
110
|
-
case "bottom":
|
|
111
|
-
return `translate3d(-50%, -50%, 0) rotateX(-90deg) translateZ(${h / 2}px)`;
|
|
112
|
-
// legacy/extra – position near top/bottom, front/back edges
|
|
113
|
-
case "top_front":
|
|
114
|
-
return `translate3d(-50%, -50%, ${z / 2}px) rotateX(75deg)`;
|
|
115
|
-
case "top_rear":
|
|
116
|
-
return `translate3d(-50%, -50%, ${-z / 2}px) rotateX(105deg)`;
|
|
117
|
-
case "bottom_front":
|
|
118
|
-
return `translate3d(-50%, -50%, ${z / 2}px) rotateX(-75deg)`;
|
|
119
|
-
case "bottom_rear":
|
|
120
|
-
return `translate3d(-50%, -50%, ${-z / 2}px) rotateX(-105deg)`;
|
|
121
|
-
default:
|
|
122
|
-
return `translate3d(-50%, -50%, ${z}px)`;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
function mergeStyles(inlineCSS, style) {
|
|
126
|
-
const out = { ...style ?? {} };
|
|
127
|
-
if (inlineCSS) {
|
|
128
|
-
inlineCSS.split(";").map((s) => s.trim()).filter(Boolean).forEach((rule) => {
|
|
129
|
-
const [k, v] = rule.split(":");
|
|
130
|
-
if (!k || !v) return;
|
|
131
|
-
const key = k.trim().replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
132
|
-
out[key] = v.trim();
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
return out;
|
|
136
|
-
}
|
|
137
|
-
function Face({
|
|
138
|
-
w,
|
|
139
|
-
h,
|
|
140
|
-
d,
|
|
141
|
-
face,
|
|
142
|
-
global
|
|
143
|
-
}) {
|
|
144
|
-
const base = (0, import_react.useMemo)(
|
|
145
|
-
() => mergeStyles(global?.css, global?.style),
|
|
146
|
-
[global]
|
|
147
|
-
);
|
|
148
|
-
const merged = (0, import_react.useMemo)(
|
|
149
|
-
() => ({ ...base, ...mergeStyles(face.css, face.style) }),
|
|
150
|
-
[base, face.css, face.style]
|
|
151
|
-
);
|
|
152
|
-
const content = face.body ?? global?.body ?? null;
|
|
153
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
154
|
-
"div",
|
|
155
|
-
{
|
|
156
|
-
className: `anim3d-face ${face.className ?? ""}`,
|
|
157
|
-
style: {
|
|
158
|
-
transform: faceTransform(face.name, w, h, d),
|
|
159
|
-
...merged
|
|
160
|
-
},
|
|
161
|
-
"data-face": face.name,
|
|
162
|
-
children: typeof content === "string" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: content }) : content
|
|
163
|
-
}
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
var Obj = ({
|
|
167
|
-
width = 160,
|
|
168
|
-
height = 160,
|
|
169
|
-
depth = 150,
|
|
170
|
-
perspective = 500,
|
|
171
|
-
perspectiveOrigin = "50% 50%",
|
|
172
|
-
faces = [
|
|
173
|
-
{ name: "front", body: "FRONT" },
|
|
174
|
-
{ name: "back", body: "BACK" },
|
|
175
|
-
{ name: "left", body: "LEFT" },
|
|
176
|
-
{ name: "right", body: "RIGHT" },
|
|
177
|
-
{ name: "top", body: "TOP" },
|
|
178
|
-
{ name: "bottom", body: "BOTTOM" }
|
|
179
|
-
],
|
|
180
|
-
global,
|
|
181
|
-
anim1,
|
|
182
|
-
anim2,
|
|
183
|
-
showCenterDiv = false,
|
|
184
|
-
className,
|
|
185
|
-
style
|
|
186
|
-
}) => {
|
|
187
|
-
const resolvedAnim1 = toAnimationShorthand(anim1);
|
|
188
|
-
const resolvedAnim2 = toAnimationShorthand(anim2);
|
|
189
|
-
const animation = [resolvedAnim1, resolvedAnim2].filter(Boolean).join(", ");
|
|
190
|
-
const stageStyle = {
|
|
191
|
-
perspective: `${perspective}px`,
|
|
192
|
-
perspectiveOrigin
|
|
193
|
-
};
|
|
194
|
-
const wrapperStyle = {
|
|
195
|
-
// consumed by CSS var
|
|
196
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
197
|
-
// @ts-ignore
|
|
198
|
-
"--obj-w": `${width}px`,
|
|
199
|
-
"--obj-h": `${height}px`,
|
|
200
|
-
width,
|
|
201
|
-
height,
|
|
202
|
-
"animation": animation || void 0
|
|
203
|
-
};
|
|
204
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
205
|
-
"div",
|
|
206
|
-
{
|
|
207
|
-
className: `anim3d-stage ${className ?? ""}`,
|
|
208
|
-
style: { ...stageStyle, ...style },
|
|
209
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "anim3d-wrapper", style: wrapperStyle, children: [
|
|
210
|
-
showCenterDiv && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "anim3d-center" }),
|
|
211
|
-
faces.map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
212
|
-
Face,
|
|
213
|
-
{
|
|
214
|
-
w: width,
|
|
215
|
-
h: height,
|
|
216
|
-
d: depth,
|
|
217
|
-
face: f,
|
|
218
|
-
global
|
|
219
|
-
},
|
|
220
|
-
`${f.name}-${i}`
|
|
221
|
-
))
|
|
222
|
-
] })
|
|
223
|
-
}
|
|
224
|
-
);
|
|
225
|
-
};
|
|
226
|
-
var Obj_default = Obj;
|
|
227
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
228
|
-
0 && (module.exports = {
|
|
229
|
-
Obj
|
|
230
|
-
});
|
|
231
|
-
//# sourceMappingURL=Obj.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Obj.tsx","../../src/keyframes.ts"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { FaceDef, GlobalDef, ObjProps, FaceName } from \"../types\";\nimport { toAnimationShorthand } from \"../keyframes\";\nimport \"../styles/obj.css\";\n\n/** Map face name -> transform so it sits on a rectangular prism */\nfunction faceTransform(name: string, w: number, h: number, d: number): string {\n const z = d / 2;\n switch (name as FaceName) {\n case \"front\":\n return `translate3d(-50%, -50%, ${z}px)`;\n case \"back\":\n return `translate3d(-50%, -50%, ${-z}px) rotateY(180deg)`;\n case \"left\":\n return `translate3d(-50%, -50%, 0) rotateY(-90deg) translateZ(${\n w / 2\n }px)`;\n case \"right\":\n return `translate3d(-50%, -50%, 0) rotateY(90deg) translateZ(${\n w / 2\n }px)`;\n case \"top\":\n return `translate3d(-50%, -50%, 0) rotateX(90deg) translateZ(${\n h / 2\n }px)`;\n case \"bottom\":\n return `translate3d(-50%, -50%, 0) rotateX(-90deg) translateZ(${\n h / 2\n }px)`;\n // legacy/extra – position near top/bottom, front/back edges\n case \"top_front\":\n return `translate3d(-50%, -50%, ${z / 2}px) rotateX(75deg)`;\n case \"top_rear\":\n return `translate3d(-50%, -50%, ${-z / 2}px) rotateX(105deg)`;\n case \"bottom_front\":\n return `translate3d(-50%, -50%, ${z / 2}px) rotateX(-75deg)`;\n case \"bottom_rear\":\n return `translate3d(-50%, -50%, ${-z / 2}px) rotateX(-105deg)`;\n default:\n return `translate3d(-50%, -50%, ${z}px)`;\n }\n}\n\n/** Merge legacy CSS string + style object */\nfunction mergeStyles(inlineCSS?: string, style?: CSSProperties): CSSProperties {\n const out: CSSProperties = { ...(style ?? {}) };\n if (inlineCSS) {\n // naive parser: split by ;, then key:value\n inlineCSS\n .split(\";\")\n .map((s) => s.trim())\n .filter(Boolean)\n .forEach((rule) => {\n const [k, v] = rule.split(\":\");\n if (!k || !v) return;\n const key = k\n .trim()\n .replace(/-([a-z])/g, (_, c) => c.toUpperCase());\n (out as any)[key] = v.trim();\n });\n }\n return out;\n}\n\nfunction Face({\n w,\n h,\n d,\n face,\n global,\n}: {\n w: number;\n h: number;\n d: number;\n face: FaceDef;\n global?: GlobalDef;\n}) {\n const base = useMemo(\n () => mergeStyles(global?.css, global?.style),\n [global]\n );\n const merged = useMemo(\n () => ({ ...base, ...mergeStyles(face.css, face.style) }),\n [base, face.css, face.style]\n );\n\n const content: ReactNode = face.body ?? global?.body ?? null;\n\n return (\n <div\n className={`anim3d-face ${face.className ?? \"\"}`}\n style={{\n transform: faceTransform(face.name, w, h, d),\n ...merged,\n }}\n data-face={face.name}\n >\n {typeof content === \"string\" ? <span>{content}</span> : content}\n </div>\n );\n}\n\nconst Obj: React.FC<ObjProps> = ({\n width = 160,\n height = 160,\n depth = 150,\n perspective = 500,\n perspectiveOrigin = \"50% 50%\",\n faces = [\n { name: \"front\", body: \"FRONT\" },\n { name: \"back\", body: \"BACK\" },\n { name: \"left\", body: \"LEFT\" },\n { name: \"right\", body: \"RIGHT\" },\n { name: \"top\", body: \"TOP\" },\n { name: \"bottom\", body: \"BOTTOM\" },\n ],\n global,\n anim1,\n anim2,\n showCenterDiv = false,\n className,\n style,\n}) => {\n const resolvedAnim1 = toAnimationShorthand(anim1);\n const resolvedAnim2 = toAnimationShorthand(anim2);\n const animation = [resolvedAnim1, resolvedAnim2].filter(Boolean).join(\", \");\n\n const stageStyle: CSSProperties = {\n perspective: `${perspective}px`,\n perspectiveOrigin,\n };\n\n const wrapperStyle: CSSProperties = {\n // consumed by CSS var\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n \"--obj-w\": `${width}px`,\n \"--obj-h\": `${height}px`,\n width,\n height,\n \"animation\": animation || undefined,\n };\n\n return (\n <div\n className={`anim3d-stage ${className ?? \"\"}`}\n style={{ ...stageStyle, ...style }}\n >\n <div className='anim3d-wrapper' style={wrapperStyle as any}>\n {showCenterDiv && <div className='anim3d-center' />}\n {faces.map((f, i) => (\n <Face\n key={`${f.name}-${i}`}\n w={width}\n h={height}\n d={depth}\n face={f}\n global={global}\n />\n ))}\n </div>\n </div>\n );\n};\n\nexport default Obj;\nexport { Obj };\n","import type { AnimationConfig } from \"./types\";\n\nlet counter = 0;\nconst uid = () => (++counter).toString(36);\n\n/** Create (or reuse) a <style> tag for dynamic keyframes */\nfunction ensureStyleTag(): HTMLStyleElement {\n let tag = document.getElementById(\n \"anim3d-keyframes\"\n ) as HTMLStyleElement | null;\n if (!tag) {\n tag = document.createElement(\"style\");\n tag.id = \"anim3d-keyframes\";\n document.head.appendChild(tag);\n }\n return tag;\n}\n\nfunction inject(css: string) {\n if (typeof document === \"undefined\") return; // SSR\n const tag = ensureStyleTag();\n tag.appendChild(document.createTextNode(css));\n}\n\n/** Keyframes text for built-ins */\nfunction builtInKeyframes(name: string, cfg: AnimationConfig) {\n const hi = cfg.degreesHi ?? 15;\n const lo = cfg.degreesLow ?? -15;\n switch (name) {\n case \"Y360\":\n return `@keyframes Y360 { from { transform: rotateY(0deg) } to { transform: rotateY(360deg) } }`;\n case \"X360\":\n return `@keyframes X360 { from { transform: rotateX(0deg) } to { transform: rotateX(360deg) } }`;\n case \"Z360\":\n return `@keyframes Z360 { from { transform: rotateZ(0deg) } to { transform: rotateZ(360deg) } }`;\n case \"rockY\":\n return `@keyframes rockY { 0%{ transform: rotateY(${lo}deg) } 50%{ transform: rotateY(${hi}deg) } 100%{ transform: rotateY(${lo}deg) } }`;\n case \"rockX\":\n return `@keyframes rockX { 0%{ transform: rotateX(${lo}deg) } 50%{ transform: rotateX(${hi}deg) } 100%{ transform: rotateX(${lo}deg) } }`;\n default:\n // Custom names: let authors supply their own @keyframes in global CSS with that name.\n return \"\";\n }\n}\n\n/** Returns a concrete animation-name and ensures keyframes exist (for built-ins) */\nexport function resolveAnimation(cfg?: AnimationConfig): string | null {\n if (!cfg) return null;\n const name = cfg.name;\n const builtIn = builtInKeyframes(name, cfg);\n if (builtIn) {\n // Ensure single injection per built-in name\n const marker = `/*kf-${name}*/`;\n if (typeof document !== \"undefined\") {\n const tag = ensureStyleTag();\n if (!tag.innerHTML.includes(marker)) {\n inject(`${builtIn}\\n${marker}`);\n }\n }\n return name; // use built-in name as animation-name\n }\n // custom: use author-provided @keyframes by name\n return name;\n}\n\n/** Build the full CSS animation shorthand from a config and resolved name */\nexport function toAnimationShorthand(cfg?: AnimationConfig): string | null {\n const name = resolveAnimation(cfg);\n if (!cfg || !name) return null;\n const dur = (cfg.duration ?? 10) + \"s\";\n const delay = (cfg.delay ?? 0) + \"s\";\n const iter = cfg.iterationCount ?? \"infinite\";\n const dir = cfg.direction ?? \"normal\";\n const timing = cfg.timing ?? \"linear\";\n const fill = cfg.fillMode ?? \"forwards\";\n const play = cfg.animationPlayState ?? \"running\";\n // name duration timing delay iteration-count direction fill-mode play-state\n return `${name} ${dur} ${timing} ${delay} ${iter} ${dir} ${fill} ${play}`;\n}\n"],"mappings":"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","names":[]}
|
package/dist/components/Obj.mjs
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
// src/components/Obj.tsx
|
|
2
|
-
import { useMemo } from "react";
|
|
3
|
-
|
|
4
|
-
// src/keyframes.ts
|
|
5
|
-
function ensureStyleTag() {
|
|
6
|
-
let tag = document.getElementById(
|
|
7
|
-
"anim3d-keyframes"
|
|
8
|
-
);
|
|
9
|
-
if (!tag) {
|
|
10
|
-
tag = document.createElement("style");
|
|
11
|
-
tag.id = "anim3d-keyframes";
|
|
12
|
-
document.head.appendChild(tag);
|
|
13
|
-
}
|
|
14
|
-
return tag;
|
|
15
|
-
}
|
|
16
|
-
function inject(css) {
|
|
17
|
-
if (typeof document === "undefined") return;
|
|
18
|
-
const tag = ensureStyleTag();
|
|
19
|
-
tag.appendChild(document.createTextNode(css));
|
|
20
|
-
}
|
|
21
|
-
function builtInKeyframes(name, cfg) {
|
|
22
|
-
const hi = cfg.degreesHi ?? 15;
|
|
23
|
-
const lo = cfg.degreesLow ?? -15;
|
|
24
|
-
switch (name) {
|
|
25
|
-
case "Y360":
|
|
26
|
-
return `@keyframes Y360 { from { transform: rotateY(0deg) } to { transform: rotateY(360deg) } }`;
|
|
27
|
-
case "X360":
|
|
28
|
-
return `@keyframes X360 { from { transform: rotateX(0deg) } to { transform: rotateX(360deg) } }`;
|
|
29
|
-
case "Z360":
|
|
30
|
-
return `@keyframes Z360 { from { transform: rotateZ(0deg) } to { transform: rotateZ(360deg) } }`;
|
|
31
|
-
case "rockY":
|
|
32
|
-
return `@keyframes rockY { 0%{ transform: rotateY(${lo}deg) } 50%{ transform: rotateY(${hi}deg) } 100%{ transform: rotateY(${lo}deg) } }`;
|
|
33
|
-
case "rockX":
|
|
34
|
-
return `@keyframes rockX { 0%{ transform: rotateX(${lo}deg) } 50%{ transform: rotateX(${hi}deg) } 100%{ transform: rotateX(${lo}deg) } }`;
|
|
35
|
-
default:
|
|
36
|
-
return "";
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
function resolveAnimation(cfg) {
|
|
40
|
-
if (!cfg) return null;
|
|
41
|
-
const name = cfg.name;
|
|
42
|
-
const builtIn = builtInKeyframes(name, cfg);
|
|
43
|
-
if (builtIn) {
|
|
44
|
-
const marker = `/*kf-${name}*/`;
|
|
45
|
-
if (typeof document !== "undefined") {
|
|
46
|
-
const tag = ensureStyleTag();
|
|
47
|
-
if (!tag.innerHTML.includes(marker)) {
|
|
48
|
-
inject(`${builtIn}
|
|
49
|
-
${marker}`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return name;
|
|
53
|
-
}
|
|
54
|
-
return name;
|
|
55
|
-
}
|
|
56
|
-
function toAnimationShorthand(cfg) {
|
|
57
|
-
const name = resolveAnimation(cfg);
|
|
58
|
-
if (!cfg || !name) return null;
|
|
59
|
-
const dur = (cfg.duration ?? 10) + "s";
|
|
60
|
-
const delay = (cfg.delay ?? 0) + "s";
|
|
61
|
-
const iter = cfg.iterationCount ?? "infinite";
|
|
62
|
-
const dir = cfg.direction ?? "normal";
|
|
63
|
-
const timing = cfg.timing ?? "linear";
|
|
64
|
-
const fill = cfg.fillMode ?? "forwards";
|
|
65
|
-
const play = cfg.animationPlayState ?? "running";
|
|
66
|
-
return `${name} ${dur} ${timing} ${delay} ${iter} ${dir} ${fill} ${play}`;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// src/components/Obj.tsx
|
|
70
|
-
import "../obj-PY72GEW6.css";
|
|
71
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
72
|
-
function faceTransform(name, w, h, d) {
|
|
73
|
-
const z = d / 2;
|
|
74
|
-
switch (name) {
|
|
75
|
-
case "front":
|
|
76
|
-
return `translate3d(-50%, -50%, ${z}px)`;
|
|
77
|
-
case "back":
|
|
78
|
-
return `translate3d(-50%, -50%, ${-z}px) rotateY(180deg)`;
|
|
79
|
-
case "left":
|
|
80
|
-
return `translate3d(-50%, -50%, 0) rotateY(-90deg) translateZ(${w / 2}px)`;
|
|
81
|
-
case "right":
|
|
82
|
-
return `translate3d(-50%, -50%, 0) rotateY(90deg) translateZ(${w / 2}px)`;
|
|
83
|
-
case "top":
|
|
84
|
-
return `translate3d(-50%, -50%, 0) rotateX(90deg) translateZ(${h / 2}px)`;
|
|
85
|
-
case "bottom":
|
|
86
|
-
return `translate3d(-50%, -50%, 0) rotateX(-90deg) translateZ(${h / 2}px)`;
|
|
87
|
-
// legacy/extra – position near top/bottom, front/back edges
|
|
88
|
-
case "top_front":
|
|
89
|
-
return `translate3d(-50%, -50%, ${z / 2}px) rotateX(75deg)`;
|
|
90
|
-
case "top_rear":
|
|
91
|
-
return `translate3d(-50%, -50%, ${-z / 2}px) rotateX(105deg)`;
|
|
92
|
-
case "bottom_front":
|
|
93
|
-
return `translate3d(-50%, -50%, ${z / 2}px) rotateX(-75deg)`;
|
|
94
|
-
case "bottom_rear":
|
|
95
|
-
return `translate3d(-50%, -50%, ${-z / 2}px) rotateX(-105deg)`;
|
|
96
|
-
default:
|
|
97
|
-
return `translate3d(-50%, -50%, ${z}px)`;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
function mergeStyles(inlineCSS, style) {
|
|
101
|
-
const out = { ...style ?? {} };
|
|
102
|
-
if (inlineCSS) {
|
|
103
|
-
inlineCSS.split(";").map((s) => s.trim()).filter(Boolean).forEach((rule) => {
|
|
104
|
-
const [k, v] = rule.split(":");
|
|
105
|
-
if (!k || !v) return;
|
|
106
|
-
const key = k.trim().replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
107
|
-
out[key] = v.trim();
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
return out;
|
|
111
|
-
}
|
|
112
|
-
function Face({
|
|
113
|
-
w,
|
|
114
|
-
h,
|
|
115
|
-
d,
|
|
116
|
-
face,
|
|
117
|
-
global
|
|
118
|
-
}) {
|
|
119
|
-
const base = useMemo(
|
|
120
|
-
() => mergeStyles(global?.css, global?.style),
|
|
121
|
-
[global]
|
|
122
|
-
);
|
|
123
|
-
const merged = useMemo(
|
|
124
|
-
() => ({ ...base, ...mergeStyles(face.css, face.style) }),
|
|
125
|
-
[base, face.css, face.style]
|
|
126
|
-
);
|
|
127
|
-
const content = face.body ?? global?.body ?? null;
|
|
128
|
-
return /* @__PURE__ */ jsx(
|
|
129
|
-
"div",
|
|
130
|
-
{
|
|
131
|
-
className: `anim3d-face ${face.className ?? ""}`,
|
|
132
|
-
style: {
|
|
133
|
-
transform: faceTransform(face.name, w, h, d),
|
|
134
|
-
...merged
|
|
135
|
-
},
|
|
136
|
-
"data-face": face.name,
|
|
137
|
-
children: typeof content === "string" ? /* @__PURE__ */ jsx("span", { children: content }) : content
|
|
138
|
-
}
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
var Obj = ({
|
|
142
|
-
width = 160,
|
|
143
|
-
height = 160,
|
|
144
|
-
depth = 150,
|
|
145
|
-
perspective = 500,
|
|
146
|
-
perspectiveOrigin = "50% 50%",
|
|
147
|
-
faces = [
|
|
148
|
-
{ name: "front", body: "FRONT" },
|
|
149
|
-
{ name: "back", body: "BACK" },
|
|
150
|
-
{ name: "left", body: "LEFT" },
|
|
151
|
-
{ name: "right", body: "RIGHT" },
|
|
152
|
-
{ name: "top", body: "TOP" },
|
|
153
|
-
{ name: "bottom", body: "BOTTOM" }
|
|
154
|
-
],
|
|
155
|
-
global,
|
|
156
|
-
anim1,
|
|
157
|
-
anim2,
|
|
158
|
-
showCenterDiv = false,
|
|
159
|
-
className,
|
|
160
|
-
style
|
|
161
|
-
}) => {
|
|
162
|
-
const resolvedAnim1 = toAnimationShorthand(anim1);
|
|
163
|
-
const resolvedAnim2 = toAnimationShorthand(anim2);
|
|
164
|
-
const animation = [resolvedAnim1, resolvedAnim2].filter(Boolean).join(", ");
|
|
165
|
-
const stageStyle = {
|
|
166
|
-
perspective: `${perspective}px`,
|
|
167
|
-
perspectiveOrigin
|
|
168
|
-
};
|
|
169
|
-
const wrapperStyle = {
|
|
170
|
-
// consumed by CSS var
|
|
171
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
172
|
-
// @ts-ignore
|
|
173
|
-
"--obj-w": `${width}px`,
|
|
174
|
-
"--obj-h": `${height}px`,
|
|
175
|
-
width,
|
|
176
|
-
height,
|
|
177
|
-
"animation": animation || void 0
|
|
178
|
-
};
|
|
179
|
-
return /* @__PURE__ */ jsx(
|
|
180
|
-
"div",
|
|
181
|
-
{
|
|
182
|
-
className: `anim3d-stage ${className ?? ""}`,
|
|
183
|
-
style: { ...stageStyle, ...style },
|
|
184
|
-
children: /* @__PURE__ */ jsxs("div", { className: "anim3d-wrapper", style: wrapperStyle, children: [
|
|
185
|
-
showCenterDiv && /* @__PURE__ */ jsx("div", { className: "anim3d-center" }),
|
|
186
|
-
faces.map((f, i) => /* @__PURE__ */ jsx(
|
|
187
|
-
Face,
|
|
188
|
-
{
|
|
189
|
-
w: width,
|
|
190
|
-
h: height,
|
|
191
|
-
d: depth,
|
|
192
|
-
face: f,
|
|
193
|
-
global
|
|
194
|
-
},
|
|
195
|
-
`${f.name}-${i}`
|
|
196
|
-
))
|
|
197
|
-
] })
|
|
198
|
-
}
|
|
199
|
-
);
|
|
200
|
-
};
|
|
201
|
-
var Obj_default = Obj;
|
|
202
|
-
export {
|
|
203
|
-
Obj,
|
|
204
|
-
Obj_default as default
|
|
205
|
-
};
|
|
206
|
-
//# sourceMappingURL=Obj.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/Obj.tsx","../../src/keyframes.ts"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { FaceDef, GlobalDef, ObjProps, FaceName } from \"../types\";\nimport { toAnimationShorthand } from \"../keyframes\";\nimport \"../styles/obj.css\";\n\n/** Map face name -> transform so it sits on a rectangular prism */\nfunction faceTransform(name: string, w: number, h: number, d: number): string {\n const z = d / 2;\n switch (name as FaceName) {\n case \"front\":\n return `translate3d(-50%, -50%, ${z}px)`;\n case \"back\":\n return `translate3d(-50%, -50%, ${-z}px) rotateY(180deg)`;\n case \"left\":\n return `translate3d(-50%, -50%, 0) rotateY(-90deg) translateZ(${\n w / 2\n }px)`;\n case \"right\":\n return `translate3d(-50%, -50%, 0) rotateY(90deg) translateZ(${\n w / 2\n }px)`;\n case \"top\":\n return `translate3d(-50%, -50%, 0) rotateX(90deg) translateZ(${\n h / 2\n }px)`;\n case \"bottom\":\n return `translate3d(-50%, -50%, 0) rotateX(-90deg) translateZ(${\n h / 2\n }px)`;\n // legacy/extra – position near top/bottom, front/back edges\n case \"top_front\":\n return `translate3d(-50%, -50%, ${z / 2}px) rotateX(75deg)`;\n case \"top_rear\":\n return `translate3d(-50%, -50%, ${-z / 2}px) rotateX(105deg)`;\n case \"bottom_front\":\n return `translate3d(-50%, -50%, ${z / 2}px) rotateX(-75deg)`;\n case \"bottom_rear\":\n return `translate3d(-50%, -50%, ${-z / 2}px) rotateX(-105deg)`;\n default:\n return `translate3d(-50%, -50%, ${z}px)`;\n }\n}\n\n/** Merge legacy CSS string + style object */\nfunction mergeStyles(inlineCSS?: string, style?: CSSProperties): CSSProperties {\n const out: CSSProperties = { ...(style ?? {}) };\n if (inlineCSS) {\n // naive parser: split by ;, then key:value\n inlineCSS\n .split(\";\")\n .map((s) => s.trim())\n .filter(Boolean)\n .forEach((rule) => {\n const [k, v] = rule.split(\":\");\n if (!k || !v) return;\n const key = k\n .trim()\n .replace(/-([a-z])/g, (_, c) => c.toUpperCase());\n (out as any)[key] = v.trim();\n });\n }\n return out;\n}\n\nfunction Face({\n w,\n h,\n d,\n face,\n global,\n}: {\n w: number;\n h: number;\n d: number;\n face: FaceDef;\n global?: GlobalDef;\n}) {\n const base = useMemo(\n () => mergeStyles(global?.css, global?.style),\n [global]\n );\n const merged = useMemo(\n () => ({ ...base, ...mergeStyles(face.css, face.style) }),\n [base, face.css, face.style]\n );\n\n const content: ReactNode = face.body ?? global?.body ?? null;\n\n return (\n <div\n className={`anim3d-face ${face.className ?? \"\"}`}\n style={{\n transform: faceTransform(face.name, w, h, d),\n ...merged,\n }}\n data-face={face.name}\n >\n {typeof content === \"string\" ? <span>{content}</span> : content}\n </div>\n );\n}\n\nconst Obj: React.FC<ObjProps> = ({\n width = 160,\n height = 160,\n depth = 150,\n perspective = 500,\n perspectiveOrigin = \"50% 50%\",\n faces = [\n { name: \"front\", body: \"FRONT\" },\n { name: \"back\", body: \"BACK\" },\n { name: \"left\", body: \"LEFT\" },\n { name: \"right\", body: \"RIGHT\" },\n { name: \"top\", body: \"TOP\" },\n { name: \"bottom\", body: \"BOTTOM\" },\n ],\n global,\n anim1,\n anim2,\n showCenterDiv = false,\n className,\n style,\n}) => {\n const resolvedAnim1 = toAnimationShorthand(anim1);\n const resolvedAnim2 = toAnimationShorthand(anim2);\n const animation = [resolvedAnim1, resolvedAnim2].filter(Boolean).join(\", \");\n\n const stageStyle: CSSProperties = {\n perspective: `${perspective}px`,\n perspectiveOrigin,\n };\n\n const wrapperStyle: CSSProperties = {\n // consumed by CSS var\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n \"--obj-w\": `${width}px`,\n \"--obj-h\": `${height}px`,\n width,\n height,\n \"animation\": animation || undefined,\n };\n\n return (\n <div\n className={`anim3d-stage ${className ?? \"\"}`}\n style={{ ...stageStyle, ...style }}\n >\n <div className='anim3d-wrapper' style={wrapperStyle as any}>\n {showCenterDiv && <div className='anim3d-center' />}\n {faces.map((f, i) => (\n <Face\n key={`${f.name}-${i}`}\n w={width}\n h={height}\n d={depth}\n face={f}\n global={global}\n />\n ))}\n </div>\n </div>\n );\n};\n\nexport default Obj;\nexport { Obj };\n","import type { AnimationConfig } from \"./types\";\n\nlet counter = 0;\nconst uid = () => (++counter).toString(36);\n\n/** Create (or reuse) a <style> tag for dynamic keyframes */\nfunction ensureStyleTag(): HTMLStyleElement {\n let tag = document.getElementById(\n \"anim3d-keyframes\"\n ) as HTMLStyleElement | null;\n if (!tag) {\n tag = document.createElement(\"style\");\n tag.id = \"anim3d-keyframes\";\n document.head.appendChild(tag);\n }\n return tag;\n}\n\nfunction inject(css: string) {\n if (typeof document === \"undefined\") return; // SSR\n const tag = ensureStyleTag();\n tag.appendChild(document.createTextNode(css));\n}\n\n/** Keyframes text for built-ins */\nfunction builtInKeyframes(name: string, cfg: AnimationConfig) {\n const hi = cfg.degreesHi ?? 15;\n const lo = cfg.degreesLow ?? -15;\n switch (name) {\n case \"Y360\":\n return `@keyframes Y360 { from { transform: rotateY(0deg) } to { transform: rotateY(360deg) } }`;\n case \"X360\":\n return `@keyframes X360 { from { transform: rotateX(0deg) } to { transform: rotateX(360deg) } }`;\n case \"Z360\":\n return `@keyframes Z360 { from { transform: rotateZ(0deg) } to { transform: rotateZ(360deg) } }`;\n case \"rockY\":\n return `@keyframes rockY { 0%{ transform: rotateY(${lo}deg) } 50%{ transform: rotateY(${hi}deg) } 100%{ transform: rotateY(${lo}deg) } }`;\n case \"rockX\":\n return `@keyframes rockX { 0%{ transform: rotateX(${lo}deg) } 50%{ transform: rotateX(${hi}deg) } 100%{ transform: rotateX(${lo}deg) } }`;\n default:\n // Custom names: let authors supply their own @keyframes in global CSS with that name.\n return \"\";\n }\n}\n\n/** Returns a concrete animation-name and ensures keyframes exist (for built-ins) */\nexport function resolveAnimation(cfg?: AnimationConfig): string | null {\n if (!cfg) return null;\n const name = cfg.name;\n const builtIn = builtInKeyframes(name, cfg);\n if (builtIn) {\n // Ensure single injection per built-in name\n const marker = `/*kf-${name}*/`;\n if (typeof document !== \"undefined\") {\n const tag = ensureStyleTag();\n if (!tag.innerHTML.includes(marker)) {\n inject(`${builtIn}\\n${marker}`);\n }\n }\n return name; // use built-in name as animation-name\n }\n // custom: use author-provided @keyframes by name\n return name;\n}\n\n/** Build the full CSS animation shorthand from a config and resolved name */\nexport function toAnimationShorthand(cfg?: AnimationConfig): string | null {\n const name = resolveAnimation(cfg);\n if (!cfg || !name) return null;\n const dur = (cfg.duration ?? 10) + \"s\";\n const delay = (cfg.delay ?? 0) + \"s\";\n const iter = cfg.iterationCount ?? \"infinite\";\n const dir = cfg.direction ?? \"normal\";\n const timing = cfg.timing ?? \"linear\";\n const fill = cfg.fillMode ?? \"forwards\";\n const play = cfg.animationPlayState ?? \"running\";\n // name duration timing delay iteration-count direction fill-mode play-state\n return `${name} ${dur} ${timing} ${delay} ${iter} ${dir} ${fill} ${play}`;\n}\n"],"mappings":"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","names":[]}
|