anim-3d-obj 1.1.11 → 1.1.15

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/.eslintignore ADDED
@@ -0,0 +1,2 @@
1
+ node_modules
2
+ dist
package/.eslintrc ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "root": true,
3
+ "extends": [
4
+ "prettier",
5
+ "plugin:prettier/recommended",
6
+ "eslint:recommended",
7
+ "plugin:react/recommended",
8
+ "plugin:@typescript-eslint/eslint-recommended",
9
+ "plugin:@typescript-eslint/recommended"
10
+ ],
11
+ "parser": "@typescript-eslint/parser",
12
+ "plugins": ["@typescript-eslint", "prettier", "react", "react-hooks"],
13
+ "rules": {
14
+ "react-hooks/rules-of-hooks": "error",
15
+ "react-hooks/exhaustive-deps": "warn",
16
+ "@typescript-eslint/no-non-null-assertion": "off",
17
+ "@typescript-eslint/ban-ts-comment": "off",
18
+ "@typescript-eslint/no-explicit-any": "off"
19
+ },
20
+ "settings": {
21
+ "react": {
22
+ "version": "detect"
23
+ }
24
+ },
25
+ "env": {
26
+ "browser": true,
27
+ "node": true
28
+ },
29
+ "globals": {
30
+ "JSX": true
31
+ }
32
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "bracketSpacing": true,
3
+ "singleQuote": true,
4
+ "trailingComma": "all",
5
+ "tabWidth": 2,
6
+ "semi": false,
7
+ "printWidth": 120,
8
+ "jsxSingleQuote": true,
9
+ "endOfLine": "auto"
10
+ }
package/README.md CHANGED
@@ -1,154 +1,107 @@
1
- # React Typescript Cuboid Builder
2
-
3
- This project allows a user to create Cuboids of any size simply by entering a set of parameters.
4
- The program does the leg work with regard to calculating translationZ depth and config on the fly.
5
-
6
- - [GIT HOME](https://github.com/mdnelles/anim-3d-objs-launcher)
7
- - [NPM HOME](https://www.npmjs.com/package/anim-3d-obj) npm i anim-3d-obj
8
-
9
- ## Examples
10
-
11
- - [6 sided Cuboid - animate X360 Y360](https://codesandbox.io/s/anim-3d-obj-all-sides-simple-bf67yg)
12
- - [3 sided Object - animate y-axis](https://codesandbox.io/s/anim-3d-obj-3-sides-wobble-y-axis-wglkms)
13
- - [Double box spin](https://codesandbox.io/s/react-anim-3d-double-box-spin-vbdhg2)
14
- - [2 sided object with animation wobble](https://codesandbox.io/s/anim-3d-obj-wobblex-mmidkg)
15
- - [Parallel divs animated x and y axis in tandem](https://codesandbox.io/s/anim-3d-obj-2-sides-simple-4057y7)
16
- - [Spinning Slab](https://codesandbox.io/s/react-anim-3d-pulse-kc8g0f)
17
-
18
- ## Config
19
-
20
- Animations are optional. Either or both of `anim1Specs` or `anim2Specs` can be applied to the object.
21
-
22
- ```typescript
23
- const anim1Specs: object = {
24
- border: '', // while testing reveal the animation wrapper
25
- degreesHi: -45, // degrees if spin
26
- degreesLow: 45, // degrees if spin
27
- delay: 0, // start delay in seconds
28
- direction: 'normal', //normal alternating reverse
29
- duration: 8, // seconds
30
- fillMode: 'forwards', // node forwards backwards both
31
- iterationCount: 'infinite', // number or infinte
32
- name: 'Y360', // ** ANIMATIONS
33
- timing: 'ease-in-out' // linear ease ease-in-out
34
- };
35
- ```
36
-
37
- `** ANIMATIONS`
38
-
39
- - X360: rotate 360 degrees on the x-axis
40
- - Y360: rotate 360 degrees on the y-axis
41
- - fadeInkf: fade object in from 0 to 1 Opacity
42
- - wobY: wobble on y-axis (degreesHi <-> degreesLow)
43
- - wobX: wobble on x-axis (degreesHi <-> degreesLow)
44
- - fwdx018: spin object on x-axis from 0 degrees to 180 degrees
45
- - fwdx1836: spin object on x-axis from 180 degrees to 360 degrees
46
- - fwdx09: spin object on x-axis from 0 degrees to 90 degrees
47
- - fwdx918: spin object on x-axis from 90 degrees to 180 degrees
48
- - fwdx1827: spin object on x-axis from 180 degrees to 270 degrees
49
- - fwdx2736: spin object on x-axis from 270 degrees to 360 degrees
50
- - fwdy018: spin object on y-axis from 0 degrees to 180 degrees
51
- - fwdy1836: spin object on y-axis from 180 degrees to 360 degrees
52
- - fwdy09: spin object on y-axis from 0 degrees to 90 degrees
53
- - fwdy918: spin object on y-axis from 90 degrees to 180 degrees
54
- - fwdy1827: spin object on y-axis from 180 degrees to 270 degrees
55
- - fwdy2736: spin object on y-axis from 270 degrees to 360 degrees
56
- - floatX: float object so is not stationary
57
- - floatShadow: float object + add shadow
58
- - pulseSM: pulse object Small
59
- - pulseMD: pulse object Medium
60
- - pulseLG: pulse object Large
61
- - noAnim: no animation place holder
62
-
63
- <>
64
-
65
- GLOBAL CONFIG
66
-
67
- ```typescript
68
- // EXAMPLE GLOBAL FACE CONFIG
69
- // This will be applied to all Faces that do not have their own custom config
70
- const global: object = {
71
- // // face individual styles (over rides global)
72
- css: `
73
- border: 1px solid #fff;
74
- background: rgb(2,0,36);
75
- background: linear-gradient(180deg, rgba(255,255,255,.1) 0%, rgba(141,191,249,.7) 100%);
76
- color:white;
77
- text-align:center;
78
- line-height:10;
79
- backface-visibility: visible;
80
- font-family: Arial, Helvetica, sans-serif;
81
- border-radius:5px;
82
- `,
83
- body: ' '
84
- };
85
- ```
86
-
87
- <>
88
-
89
- CUSTOM CONFIG FOR INDIVIDUAL FACES
90
-
91
- ```typescript
92
- const custom: object = {
93
- // // face individual styles (over rides global)
94
- front: {
95
- css: ``,
96
- body: <Login />,
97
- },
98
- left: {
99
- css: `
100
- border: 1px solid #fff;
101
- background: rgb(2,0,36);
102
- color:white;
103
- text-align: center;
104
- line-height:8;`
105
- body: " ",
106
- },
107
- right: {
108
- css: ``,
109
- body: " ",
110
- },
111
- back: {
112
- css: ``,
113
- body: <Logout />,
114
- },
115
- bottom: {
116
- css: `
117
- background-color:rgba(141,191,249,1);
118
- -webkit-box-shadow: 0px 0px 23px 18px #858585;
119
- box-shadow: 0px 0px 23px 18px #858585;
120
- `,
121
- },
122
- ```
123
-
124
- ## Render
125
-
126
- and
127
-
128
- ```typescript
129
- <Cuboid
130
- width={250}
131
- height={300}
132
- depth={250}
133
- perspective={800}
134
- perspectiveOrigin="50% 50%"
135
- zIndex={10}
136
- anim1Specs={anim1Specs}
137
- anim2Specs={anim2Specs}
138
- custom={custom}
139
- faces={faceprops}
140
- global={global}
141
- />
142
- ```
143
-
144
- will produce the following
145
-
146
- ![Logo](https://raw.githubusercontent.com/mdnelles/objs-local/main/img.png?token=GHSAT0AAAAAABQVNJ4VATWQM4SI3LXSTDZWYVDOL7Q)
147
-
148
- ## Authors
149
-
150
- - [@mdnelles](https://github.com/mdnelles)
151
-
152
- ## License
153
-
154
- [MIT](https://choosealicense.com/licenses/mit/)
1
+ # React Typescript Cuboid Builder
2
+
3
+ This project allows a user to create Cuboids of any size simply by entering a set of parameters.
4
+ The program does the leg work with regard to calculating translationZ depth and config on the fly.
5
+
6
+ ## Deployment
7
+
8
+ Install sequence
9
+
10
+ ```
11
+ git clone https://github.com/mdnelles/anim-3d-objs.git
12
+ npm i
13
+ npm run start
14
+ ```
15
+
16
+ ## Examples
17
+
18
+ All sided simple https://codesandbox.io/s/anim-3d-obj-all-sides-simple-sdy1q0
19
+
20
+ Two sided simple https://codesandbox.io/s/anim-3d-obj-2-sides-simple-9wognm
21
+
22
+ 90 degree wobble on X axis https://codesandbox.io/s/anim-3d-obj-wobblex-08mxqe
23
+
24
+ speed wobble(y) 3 sides https://codesandbox.io/s/anim-3d-obj-3-sides-wobble-y-axis-dceqdp
25
+
26
+ ## Authors
27
+
28
+ - [@mdnelles](https://github.com/mdnelles)
29
+
30
+ ## Demo
31
+
32
+ The following code
33
+
34
+ ```
35
+ const indivStyles: object = {
36
+ // // face individual styles (over rides global)
37
+ bottom: {
38
+ bfv: "visible",
39
+ fontFamily: "Helvetica",
40
+ },
41
+ front: {
42
+ border: "1px solid #f00",
43
+ bgc: "#f00",
44
+ bfv: "visible",
45
+ fontFamily: "Arial, Sans",
46
+ },
47
+ left: {
48
+ bgc: "yellow",
49
+ },
50
+ top: {
51
+ bgc: "pink",
52
+ },
53
+ right: {
54
+ bgc: "purple",
55
+ },
56
+ back: {
57
+ border: "1px solid #f00",
58
+ bgc: "#0f0",
59
+ bfv: "visible",
60
+ fontFamily: "Arial, Sans",
61
+ },
62
+ };
63
+ ```
64
+
65
+ and
66
+
67
+ ```
68
+ <Cuboid
69
+ width={260}
70
+ depth={260}
71
+ height={92}
72
+ perspectiveOrigin='50% 50%'
73
+ zIndex={10}
74
+ animSpecs={animSpecs}
75
+ indivStyles={indivStyles}
76
+ faces={faceprops}
77
+ globalStyles={globalStyles}
78
+ >
79
+ {}
80
+ </Cuboid>
81
+ ```
82
+
83
+ will produce the following
84
+
85
+ ![Logo](https://raw.githubusercontent.com/mdnelles/objs-local/main/img.png?token=GHSAT0AAAAAABQVNJ4VATWQM4SI3LXSTDZWYVDOL7Q)
86
+
87
+ ##Face Format
88
+ for things like `background-image: url("myImg.png");` they can be done in `moreStyles` argument.
89
+
90
+ ```
91
+ const Specs: any = styled.div`
92
+ opacity: ${opac ? opac : globalStyles.opac};
93
+ position: ${position};
94
+ left: ${left};
95
+ margin: ${margin};
96
+ padding: ${padding};
97
+ width: ${width}px;
98
+ font-family: ${fontFamily};
99
+ height: ${height}px;
100
+ background-color: ${bgc ? bgc : globalStyles.bgc};
101
+ border: ${border ? border : globalStyles.border};
102
+ backface-visibility: ${bfv ? bfv : globalStyles.bfv};
103
+ ${transform}
104
+ top: ${top};
105
+ ${moreStyles}
106
+ `;
107
+ ```
@@ -0,0 +1,8 @@
1
+ {
2
+ "transform": {
3
+ "^.+\\.(t|j)sx?$": "ts-jest"
4
+ },
5
+ "testRegex": "(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
6
+ "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
7
+ "testEnvironment": "jsdom"
8
+ }
package/package.json CHANGED
@@ -1,48 +1,65 @@
1
1
  {
2
- "name": "anim-3d-obj",
3
- "repository": {
4
- "type": "git",
5
- "url": "https://github.com/mdnelles/Component-Library"
6
- },
7
- "homepage": "https://github.com/mdnelles/anim-3d-objs-launcher",
8
- "version": "1.1.11",
9
- "description": "React library for creating 3D objects quickly. Also these objects can be animated",
10
- "main": "dist/cjs/index.js",
11
- "module": "dist/esm/index.js",
12
- "files": [
13
- "dist"
2
+ "name": "anim-3d-obj",
3
+ "version": "1.1.15",
4
+ "private": false,
5
+ "dependencies": {
6
+ "@reduxjs/toolkit": "^1.8.4",
7
+ "@testing-library/jest-dom": "^5.16.5",
8
+ "@testing-library/user-event": "^14.4.3",
9
+ "@types/node": "^18.7.3",
10
+ "@types/react": "^18.0.17",
11
+ "@types/react-dom": "^18.0.6",
12
+ "react": "^18.2.0",
13
+ "react-dom": "^18.2.0",
14
+ "react-redux": "^8.0.2",
15
+ "react-scripts": "5.0.1",
16
+ "styled-components": "^5.3.5",
17
+ "typescript": "^4.7.4",
18
+ "web-vitals": "^2.1.4"
19
+ },
20
+ "scripts": {
21
+ "buildOLD": "react-scripts build",
22
+ "build": "tsc",
23
+ "build4jest": "npm build:esm && npm build:cjs",
24
+ "build:esm": "tsc",
25
+ "build:cjs": "tsc --module commonjs --outDir dist/cjs",
26
+ "lint": "eslint \"{**/*,*}.{js,ts,jsx,tsx}\"",
27
+ "prettier": "prettier --write \"{src,tests,example/src}/**/*.{js,ts,jsx,tsx}\"",
28
+ "test": "jest --config jestconfig.json"
29
+ },
30
+ "eslintConfig": {
31
+ "extends": [
32
+ "react-app",
33
+ "react-app/jest"
34
+ ]
35
+ },
36
+ "browserslist": {
37
+ "production": [
38
+ ">0.2%",
39
+ "not dead",
40
+ "not op_mini all"
14
41
  ],
15
- "scripts": {
16
- "build": "rm -rf dist/ && prettier --write src/ && npm run build:esm && npm run build:cjs",
17
- "build:esm": "tsc",
18
- "build:cjs": "tsc --module CommonJS --outDir dist/cjs"
19
- },
20
- "author": "mdnelles",
21
- "license": "MIT",
22
- "devDependencies": {
23
- "@types/node": "^17.0.21",
24
- "@types/react": "^17.0.37",
25
- "@types/react-dom": "^17.0.11",
26
- "@types/styled-components": "^5.1.25",
27
- "react": "^18.2.0",
28
- "react-dom": "^18.2.0",
29
- "typescript": "^4.5.2"
30
- },
31
- "peerDependencies": {
32
- "react": "^18.2.0",
33
- "react-dom": "^18.2.0"
34
- },
35
- "dependencies": {
36
- "styled-components": "^5.3.5"
37
- },
38
- "keywords": [
39
- "React",
40
- "CSS",
41
- "style",
42
- "animation",
43
- "cube",
44
- "cuboid",
45
- "3d",
46
- "webGL"
42
+ "development": [
43
+ "last 1 chrome version",
44
+ "last 1 firefox version",
45
+ "last 1 safari version"
47
46
  ]
47
+ },
48
+ "devDependencies": {
49
+ "@testing-library/react": "^13.3.0",
50
+ "@types/jest": "^28.1.6",
51
+ "@types/styled-components": "^5.1.26",
52
+ "@typescript-eslint/eslint-plugin": "^5.33.0",
53
+ "@typescript-eslint/parser": "^5.33.0",
54
+ "eslint": "^8.22.0",
55
+ "eslint-config-prettier": "^8.5.0",
56
+ "eslint-plugin-prettier": "^4.2.1",
57
+ "eslint-plugin-react": "^7.30.1",
58
+ "eslint-plugin-react-hooks": "^4.6.0",
59
+ "jest": "^28.1.3",
60
+ "jest-canvas-mock": "^2.4.0",
61
+ "jest-environment-jsdom": "^28.1.3",
62
+ "prettier": "^2.7.1",
63
+ "ts-jest": "^28.0.7"
64
+ }
48
65
  }
Binary file
@@ -0,0 +1,43 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <meta name="theme-color" content="#000000" />
8
+ <meta
9
+ name="description"
10
+ content="Web site created using create-react-app"
11
+ />
12
+ <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
13
+ <!--
14
+ manifest.json provides metadata used when your web app is installed on a
15
+ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
16
+ -->
17
+ <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
18
+ <!--
19
+ Notice the use of %PUBLIC_URL% in the tags above.
20
+ It will be replaced with the URL of the `public` folder during the build.
21
+ Only files inside the `public` folder can be referenced from the HTML.
22
+
23
+ Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
24
+ work correctly both with client-side routing and a non-root public URL.
25
+ Learn how to configure a non-root public URL by running `npm run build`.
26
+ -->
27
+ <title>React Redux App</title>
28
+ </head>
29
+ <body>
30
+ <noscript>You need to enable JavaScript to run this app.</noscript>
31
+ <div id="root"></div>
32
+ <!--
33
+ This HTML file is a template.
34
+ If you open it directly in the browser, you will see an empty page.
35
+
36
+ You can add webfonts, meta tags, or analytics to this file.
37
+ The build step will place the bundled scripts into the <body> tag.
38
+
39
+ To begin the development, run `npm start` or `yarn start`.
40
+ To create a production bundle, use `npm run build` or `yarn build`.
41
+ -->
42
+ </body>
43
+ </html>
Binary file
Binary file
@@ -0,0 +1,25 @@
1
+ {
2
+ "short_name": "React App",
3
+ "name": "Create React App Sample",
4
+ "icons": [
5
+ {
6
+ "src": "favicon.ico",
7
+ "sizes": "64x64 32x32 24x24 16x16",
8
+ "type": "image/x-icon"
9
+ },
10
+ {
11
+ "src": "logo192.png",
12
+ "type": "image/png",
13
+ "sizes": "192x192"
14
+ },
15
+ {
16
+ "src": "logo512.png",
17
+ "type": "image/png",
18
+ "sizes": "512x512"
19
+ }
20
+ ],
21
+ "start_url": ".",
22
+ "display": "standalone",
23
+ "theme_color": "#000000",
24
+ "background_color": "#ffffff"
25
+ }
@@ -0,0 +1,3 @@
1
+ # https://www.robotstxt.org/robotstxt.html
2
+ User-agent: *
3
+ Disallow:
@@ -0,0 +1,55 @@
1
+ import { AnimWrap } from './styles/AnimWrap'
2
+ import { SceneStyle } from './styles/Scene'
3
+ import { ObjProps } from './Faces/FaceInter'
4
+ import Face from './Faces/Face'
5
+ import { ObjWrapper } from './styles/Global'
6
+
7
+ export const Card = (props: ObjProps): any => {
8
+ const {
9
+ anim1Specs,
10
+ anim2Specs,
11
+ width = 5,
12
+ height = 5,
13
+ faces,
14
+ global = {},
15
+ custom = {},
16
+ tranz = (+height / 2) | 0,
17
+ perspective,
18
+ perspectiveOrigin,
19
+ zIndex,
20
+ } = props
21
+
22
+ const buildFace = (faceType: any): any => {
23
+ return (
24
+ <Face
25
+ width={width}
26
+ height={height}
27
+ depth={0.1}
28
+ faceType={faceType}
29
+ id={faceType}
30
+ tranz={tranz}
31
+ global={global}
32
+ custom={custom}
33
+ />
34
+ )
35
+ }
36
+
37
+ return (
38
+ <SceneStyle
39
+ width={width}
40
+ height={height}
41
+ perspective={perspective}
42
+ perspectiveOrigin={perspectiveOrigin}
43
+ zIndex={zIndex}
44
+ >
45
+ <AnimWrap animSpecs={anim1Specs}>
46
+ <AnimWrap animSpecs={anim2Specs}>
47
+ <ObjWrapper>
48
+ {faces && faces.front ? buildFace('front') : null}
49
+ {faces && faces.back ? buildFace('back') : null}
50
+ </ObjWrapper>
51
+ </AnimWrap>
52
+ </AnimWrap>
53
+ </SceneStyle>
54
+ )
55
+ }
@@ -0,0 +1,61 @@
1
+ //import React from 'react'
2
+ import { AnimWrap } from './styles/AnimWrap'
3
+ import { SceneStyle } from './styles/Scene'
4
+ import { ObjProps } from './Faces/FaceInter'
5
+ import Face from './Faces/Face'
6
+ import { ObjWrapper } from './styles/Global'
7
+
8
+ export const Cuboid = (props: ObjProps): any => {
9
+ const {
10
+ anim1Specs,
11
+ anim2Specs,
12
+ width = 5,
13
+ height = 5,
14
+ depth = 5,
15
+ faces,
16
+ global = {},
17
+ custom = {},
18
+ tranz = (+height / 2) | 0,
19
+ perspective,
20
+ perspectiveOrigin,
21
+ zIndex,
22
+ } = props
23
+
24
+ const buildFace = (faceType: any): any => {
25
+ return (
26
+ <Face
27
+ width={width}
28
+ height={height}
29
+ depth={depth}
30
+ faceType={faceType}
31
+ id={faceType}
32
+ tranz={tranz}
33
+ global={global}
34
+ custom={custom}
35
+ />
36
+ )
37
+ }
38
+
39
+ return (
40
+ <SceneStyle
41
+ width={width}
42
+ height={height}
43
+ perspective={perspective}
44
+ perspectiveOrigin={perspectiveOrigin}
45
+ zIndex={zIndex}
46
+ >
47
+ <AnimWrap animSpecs={anim1Specs}>
48
+ <AnimWrap animSpecs={anim2Specs}>
49
+ <ObjWrapper>
50
+ {faces && faces.front ? buildFace('front') : null}
51
+ {faces && faces.right ? buildFace('right') : null}
52
+ {faces && faces.back ? buildFace('back') : null}
53
+ {faces && faces.left ? buildFace('left') : null}
54
+ {faces && faces.top ? buildFace('top') : null}
55
+ {faces && faces.bottom ? buildFace('bottom') : null}
56
+ </ObjWrapper>
57
+ </AnimWrap>
58
+ </AnimWrap>
59
+ </SceneStyle>
60
+ )
61
+ }
@@ -0,0 +1,72 @@
1
+ import styled from 'styled-components'
2
+ import { FaceProps } from './FaceInter'
3
+
4
+ const Face = (props: FaceProps): JSX.Element => {
5
+ let { height = 10, tranz = 80, width = 100 } = props
6
+
7
+ const { depth = 10, faceType, global = {}, custom = false } = props
8
+
9
+ let transform
10
+ const styles = custom[faceType] && custom[faceType].css ? custom[faceType].css : global.css
11
+ const body = custom[faceType] && custom[faceType].body ? custom[faceType].body : global.body
12
+ if (faceType === 'bottom') {
13
+ tranz = +height - +depth / 2
14
+ height = +depth
15
+ transform = `transform: rotateX(-90deg) translateZ(${tranz}px);`
16
+ //styles = custom["top"] ? custom : global;
17
+ } else if (faceType === 'top') {
18
+ height = +depth
19
+ if (depth) tranz = +depth / 2
20
+ transform = `transform: rotateX(90deg) translateZ(${tranz}px);`
21
+ } else if (faceType === 'front') {
22
+ if (depth) tranz = +depth / 2
23
+ transform = `transform: rotateY(0deg) translateZ(${tranz}px);`
24
+ } else if (faceType === 'back') {
25
+ if (depth) tranz = +depth / 2
26
+ transform = `transform: rotateY(180deg) translateZ(${tranz}px);`
27
+ } else if (faceType === 'right') {
28
+ if (height > width && !depth) {
29
+ tranz = -(+height / 2 - +width)
30
+ width = +height
31
+ } else if (width > height && !depth) {
32
+ tranz = +height / 2
33
+ height = +width
34
+ } else {
35
+ tranz = +width - +depth / 2
36
+ width = +depth
37
+ }
38
+ transform = `transform: rotateY(90deg) translateZ(${tranz}px);`
39
+ // topr is to of Ribbon which points back
40
+ } else if (faceType === 'topr') {
41
+ height = +depth
42
+ if (depth) tranz = +depth / 2
43
+ //let offset = depth / 2;
44
+ transform = `transform: rotateX(90deg) translateZ(${tranz}px ); `
45
+ } else {
46
+ if (height > width && !depth) {
47
+ tranz = -(+height / 2 - +width)
48
+ width = +height
49
+ } else if (width > height && !depth) {
50
+ tranz = +height / 2
51
+ height = +width
52
+ } else {
53
+ tranz = +depth / 2
54
+ width = +depth
55
+ }
56
+ transform = `transform: rotateY(-90deg) translateZ(${tranz}px);`
57
+ }
58
+
59
+ //const BackFlip: any = styled.section``;
60
+
61
+ const Specs: any = styled.section`
62
+ ${styles}
63
+ width: ${width}px;
64
+ position: absolute;
65
+ height: ${height}px;
66
+ ${transform};
67
+ `
68
+
69
+ return <Specs>{body}</Specs>
70
+ }
71
+
72
+ export default Face
@@ -0,0 +1,39 @@
1
+ export interface FaceProps {
2
+ children?: any
3
+ depth?: number | any
4
+ faceType?: any
5
+ custom?: any
6
+ global?: any
7
+ height?: number | string
8
+ id?: string | number | boolean
9
+ styles?: object | any
10
+ tranz?: any
11
+ width?: number | string
12
+ }
13
+
14
+ export interface ObjProps {
15
+ anim1Specs?: object | undefined
16
+ anim2Specs?: object | undefined
17
+ children?: any
18
+ depth?: number
19
+ global?: { border?: string; bgc?: string; opac?: number | string } | any
20
+ faces?:
21
+ | {
22
+ front: boolean
23
+ back: boolean
24
+ left: boolean
25
+ right: boolean
26
+ top: boolean
27
+ bottom: boolean
28
+ }
29
+ | undefined
30
+
31
+ height?: number | string
32
+ custom?: object | string | undefined
33
+ perspective?: string | number | undefined
34
+ perspectiveOrigin?: string | undefined
35
+ tranz?: number | undefined
36
+ txt?: string | any
37
+ width?: number
38
+ zIndex?: number | undefined
39
+ }
@@ -0,0 +1,57 @@
1
+ import { AnimWrap } from './styles/AnimWrap'
2
+ import { SceneStyle } from './styles/Scene'
3
+ import { ObjProps } from './Faces/FaceInter'
4
+ import Face from './Faces/Face'
5
+ import { ObjWrapper } from './styles/Global'
6
+
7
+ export const Ribbon = (props: ObjProps): any => {
8
+ const {
9
+ anim1Specs,
10
+ anim2Specs,
11
+ width = 5,
12
+ height = 5,
13
+ depth = 5,
14
+ faces,
15
+ global = {},
16
+ custom = {},
17
+ tranz = (+height / 2) | 0,
18
+ perspective,
19
+ perspectiveOrigin,
20
+ zIndex,
21
+ } = props
22
+
23
+ const buildFace = (faceType: any): any => {
24
+ return (
25
+ <Face
26
+ width={width}
27
+ height={height}
28
+ depth={depth}
29
+ faceType={faceType}
30
+ id={faceType}
31
+ tranz={tranz}
32
+ global={global}
33
+ custom={custom}
34
+ />
35
+ )
36
+ }
37
+
38
+ return (
39
+ <SceneStyle
40
+ width={width}
41
+ height={height}
42
+ perspective={perspective}
43
+ perspectiveOrigin={perspectiveOrigin}
44
+ zIndex={zIndex}
45
+ >
46
+ <AnimWrap animSpecs={anim1Specs}>
47
+ <AnimWrap animSpecs={anim2Specs}>
48
+ <ObjWrapper>
49
+ {faces && faces.bottom ? buildFace('bottom') : null}
50
+ {faces && faces.back ? buildFace('back') : null}
51
+ {faces && faces.top ? buildFace('topr') : null}
52
+ </ObjWrapper>
53
+ </AnimWrap>
54
+ </AnimWrap>
55
+ </SceneStyle>
56
+ )
57
+ }
@@ -0,0 +1,16 @@
1
+ export interface AnimStylesProps {
2
+ children?: any
3
+ animSpecs?: any
4
+ }
5
+ export interface AnimSpecsProps {
6
+ border?: string | undefined
7
+ degreesHi?: number | undefined
8
+ degreesLow?: number | undefined
9
+ delay: any
10
+ direction?: string | undefined
11
+ duration?: number | string | undefined
12
+ fillMode?: string | undefined
13
+ iterationCount?: number | string | undefined
14
+ name?: string | undefined
15
+ timing?: string | undefined
16
+ }
@@ -0,0 +1,92 @@
1
+ import styled from 'styled-components'
2
+ //import React from 'react'
3
+ import { AnimStylesProps } from './Anim'
4
+ import { allAnims } from './Anims'
5
+
6
+ export const AnimWrap = (props: AnimStylesProps) => {
7
+ const { children, animSpecs } = props
8
+ const AS: any = animSpecs
9
+
10
+ const {
11
+ X360,
12
+ Y360,
13
+ fadeInkf,
14
+ wobY,
15
+ wobX,
16
+ fwdx018,
17
+ fwdx1836,
18
+ fwdx09,
19
+ fwdx918,
20
+ fwdx1827,
21
+ fwdx2736,
22
+ fwdy018,
23
+ fwdy1836,
24
+ fwdy09,
25
+ fwdy918,
26
+ fwdy1827,
27
+ fwdy2736,
28
+ floatX,
29
+ floatShadow,
30
+ pulseSM,
31
+ pulseMD,
32
+ pulseLG,
33
+ noAnim,
34
+ } = allAnims({
35
+ degreesHi: AS && AS.degreesHi ? AS.degreesHi : 0,
36
+ degreesLow: AS && AS.degreesLow ? AS.degreesLow : 0,
37
+ })
38
+
39
+ let theAnim: any = 'noAnim'
40
+ // need to iterate through all animation posibilities and not use eval() to satisfy TS
41
+ if (AS && AS.name) {
42
+ if (AS.name === 'X360') theAnim = X360
43
+ else if (AS.name === 'Y360') theAnim = Y360
44
+ else if (AS.name === 'fadeInkf') theAnim = fadeInkf
45
+ else if (AS.name === 'wobX') theAnim = wobX
46
+ else if (AS.name === 'wobY') theAnim = wobY
47
+ else if (AS.name === 'fwdx018') theAnim = fwdx018
48
+ else if (AS.name === 'fwdx1836') theAnim = fwdx1836
49
+ else if (AS.name === 'fwdx09') theAnim = fwdx09
50
+ else if (AS.name === 'fwdx918') theAnim = fwdx918
51
+ else if (AS.name === 'fwdx1827') theAnim = fwdx1827
52
+ else if (AS.name === 'fwdx2736') theAnim = fwdx2736
53
+ else if (AS.name === 'fwdy018') theAnim = fwdy018
54
+ else if (AS.name === 'fwdy1836') theAnim = fwdy1836
55
+ else if (AS.name === 'fwdy09') theAnim = fwdy09
56
+ else if (AS.name === 'fwdy918') theAnim = fwdy918
57
+ else if (AS.name === 'fwdy1827') theAnim = fwdy1827
58
+ else if (AS.name === 'fwdy2736') theAnim = fwdy2736
59
+ else if (AS.name === 'floatX') theAnim = floatX
60
+ else if (AS.name === 'floatShadow') theAnim = floatShadow
61
+ else if (AS.name === 'pulseSM') theAnim = pulseSM
62
+ else if (AS.name === 'pulseMD') theAnim = pulseMD
63
+ else if (AS.name === 'pulseLG') theAnim = pulseLG
64
+ } else theAnim = noAnim
65
+
66
+ let AnimWrapDiv: any = styled.div``
67
+ if (AS) {
68
+ AnimWrapDiv = styled.div`
69
+ width: 100%;
70
+ height: 100%;
71
+ position: relative;
72
+ transform-style: preserve-3d;
73
+ border: ${AS.border || ''};
74
+ -webkit-animation-duration: ${AS.duration || 1}s;
75
+ animation-duration: ${AS.duration || 1}s;
76
+ -webkit-animation-iteration-count: ${AS.iterationCount || 1};
77
+ animation-iteration-count: ${AS.iterationCount || 1};
78
+ -webkit-animation-name: ${theAnim || 'noAnim'};
79
+ animation-name: ${theAnim || 'noAnim'};
80
+ -webkit-animation-fill-mode: ${AS.fillMode || 'forwards'};
81
+ animation-fill-mode: ${AS.fillMode || 'forwards'};
82
+ animation-direction: ${AS.direction || 'normal'};
83
+ -webkit-animation-direction: ${AS.direction || 'normal'};
84
+ -webkit-animation-timing-function: ${AS.timing || 'linear'};
85
+ animation-timing-function: ${AS.timing || 'linear'};
86
+ -webkit-animation-delay: ${AS.delay || 0}s;
87
+ animation-delay: ${AS.delay || 0}s;
88
+ `
89
+ }
90
+
91
+ return <AnimWrapDiv>{children}</AnimWrapDiv>
92
+ }
@@ -0,0 +1,290 @@
1
+ import { keyframes } from 'styled-components'
2
+
3
+ interface AllAnimsProps {
4
+ degreesLow?: number
5
+ degreesHi?: number
6
+ }
7
+
8
+ export const allAnims = (props: AllAnimsProps) => {
9
+ const { degreesLow = 0, degreesHi = 0 } = props
10
+
11
+ const X360 = keyframes`
12
+ from {
13
+ -webkit-transform: rotateX(360deg);
14
+ transform: rotateX(360deg);
15
+ }
16
+ to {
17
+ -webkit-transform: rotateX(0deg);
18
+ transform: rotateX(0deg);
19
+ }
20
+ }`
21
+
22
+ //////// Y360
23
+ const Y360 = keyframes`
24
+ from {
25
+ -webkit-transform: rotateY(360deg);
26
+ transform: rotateY(360deg);
27
+ }
28
+ to {
29
+ -webkit-transform: rotateY(0deg);
30
+ transform: rotateY(0deg);
31
+ }`
32
+
33
+ const fadeInkf = keyframes`
34
+ from {
35
+ opacity: 0;
36
+ }
37
+ to {
38
+ opacity: 1;
39
+ }`
40
+
41
+ const wobY = keyframes`
42
+ 0% {
43
+ -webkit-transform: rotateY(${degreesLow}deg);
44
+ transform: rotateY(${degreesLow}deg);
45
+ }
46
+ 50% {
47
+ -webkit-transform: rotateY(${degreesHi}deg);
48
+ transform: rotateY(${degreesHi}deg);
49
+ }
50
+ 100% {
51
+ -webkit-transform: rotateY(${degreesLow}deg);
52
+ transform: rotateY(${degreesLow}deg);
53
+ }`
54
+
55
+ const wobX = keyframes`
56
+ 0% {
57
+ -webkit-transform: rotateX(${degreesLow}deg);
58
+ transform: rotateX(${degreesLow}deg);
59
+ }
60
+ 50% {
61
+ -webkit-transform: rotateX(${degreesHi}deg);
62
+ transform: rotateX(${degreesHi}deg);
63
+ }
64
+ 100% {
65
+ -webkit-transform: rotateX(${degreesLow}deg);
66
+ transform: rotateX(${degreesLow}deg);
67
+ }`
68
+ /* ============================== x-axis 0-180 >180 - 360 */
69
+ const fwdx018 = keyframes`
70
+ from {
71
+ -webkit-transform: rotateX(360deg);
72
+ transform: rotateX(360deg);
73
+ }
74
+ to {
75
+ -webkit-transform: rotateX(180deg);
76
+ transform: rotateX(180deg);
77
+ }`
78
+ const fwdx1836 = keyframes`
79
+ from {
80
+ -webkit-transform: rotateX(180deg);
81
+ transform: rotateX(180deg);
82
+ }
83
+ to {
84
+ -webkit-transform: rotateX(0deg);
85
+ transform: rotateX(0deg);
86
+ }`
87
+ /* ============================= x-axis 0-90, 90-180, 180-270, 270-360 */
88
+ const fwdx09 = keyframes`
89
+ from {
90
+ -webkit-transform: rotateX(360deg);
91
+ transform: rotateX(360deg);
92
+ }
93
+ to {
94
+ -webkit-transform: rotateX(90deg);
95
+ transform: rotateX(90deg);
96
+ }`
97
+ const fwdx918 = keyframes`
98
+ from {
99
+ -webkit-transform: rotateX(-90deg);
100
+ transform: rotateX(-90deg);
101
+ }
102
+ to {
103
+ -webkit-transform: rotateX(-180deg);
104
+ transform: rotateX(-180deg);
105
+ }`
106
+ const fwdx1827 = keyframes`
107
+ from {
108
+ -webkit-transform: rotateX(-180deg);
109
+ transform: rotateX(-180deg);
110
+ }
111
+ to {
112
+ -webkit-transform: rotateX(-270deg);
113
+ transform: rotateX(-270deg);
114
+ }`
115
+ const fwdx2736 = keyframes`
116
+ from {
117
+ -webkit-transform: rotateX(-270deg);
118
+ transform: rotateX(-270deg);
119
+ }
120
+ to {
121
+ -webkit-transform: rotateX(-360deg);
122
+ transform: rotateX(-360deg);
123
+ }`
124
+
125
+ /* ============================== y-axis 0-180 >180 - 360 */
126
+ const fwdy018 = keyframes`
127
+ from {
128
+ -webkit-transform: rotateY(360deg);
129
+ transform: rotateY(360deg);
130
+ }
131
+ to {
132
+ -webkit-transform: rotateY(180deg);
133
+ transform: rotateY(180deg);
134
+ }`
135
+ const fwdy1836 = keyframes`
136
+ from {
137
+ -webkit-transform: rotateY(180deg);
138
+ transform: rotateY(180deg);
139
+ }
140
+ to {
141
+ -webkit-transform: rotateY(0deg);
142
+ transform: rotateY(0deg);
143
+ }`
144
+
145
+ /* ============================= y-axis 0-90, 90-180, 180-270, 270-360 */
146
+ const fwdy09 = keyframes`
147
+ from {
148
+ -webkit-transform: rotateY(360deg);
149
+ transform: rotateY(360deg);
150
+ }
151
+ to {
152
+ -webkit-transform: rotateY(90deg);
153
+ transform: rotateY(90deg);
154
+ }`
155
+ const fwdy918 = keyframes`
156
+ from {
157
+ -webkit-transform: rotateY(-90deg);
158
+ transform: rotateY(-90deg);
159
+ }
160
+ to {
161
+ -webkit-transform: rotateY(-180deg);
162
+ transform: rotateY(-180deg);
163
+ }`
164
+ const fwdy1827 = keyframes`
165
+ from {
166
+ -webkit-transform: rotateY(-180deg);
167
+ transform: rotateY(-180deg);
168
+ }
169
+ to {
170
+ -webkit-transform: rotateY(-270deg);
171
+ transform: rotateY(-270deg);
172
+ }`
173
+ const fwdy2736 = keyframes`
174
+ from {
175
+ -webkit-transform: rotateY(-270deg);
176
+ transform: rotateY(-270deg);
177
+ }
178
+ to {
179
+ -webkit-transform: rotateY(-360deg);
180
+ transform: rotateY(-360deg);
181
+ }`
182
+
183
+ /* ============================= floating */
184
+ const floatX = keyframes`
185
+ 0% { -webkit-transform: translate(0, 0px); -ms-transform: translate(0, 0px); transform: translate(0, 0px); }
186
+ 50% { -webkit-transform: translate(0, 15px); -ms-transform: translate(0, 15px); transform: translate(0, 15px); }
187
+ 100% { -webkit-transform: translate(0, -0px); -ms-transform: translate(0, -0px); transform: translate(0, -0px); }`
188
+
189
+ const floatShadow = keyframes`
190
+ 0% {
191
+ -webkit-box-shadow: 0 5px 15px 0px rgba(0,0,0,0.6);
192
+ box-shadow: 0 5px 15px 0px rgba(0,0,0,0.6);
193
+ -webkit-transform: translateY(0px);
194
+ -ms-transform: translateY(0px);
195
+ transform: translateY(0px);
196
+ }
197
+ 50% {
198
+ -webkit-box-shadow: 0 25px 15px 0px rgba(0,0,0,0.2);
199
+ box-shadow: 0 25px 15px 0px rgba(0,0,0,0.2);
200
+ -webkit-transform: translateY(-20px);
201
+ -ms-transform: translateY(-20px);
202
+ transform: translateY(-20px);
203
+ }
204
+ 100% {
205
+ -webkit-box-shadow: 0 5px 15px 0px rgba(0,0,0,0.6);
206
+ box-shadow: 0 5px 15px 0px rgba(0,0,0,0.6);
207
+ -webkit-transform: translateY(0px);
208
+ -ms-transform: translateY(0px);
209
+ transform: translateY(0px);
210
+ }`
211
+
212
+ const pulseSM = keyframes`
213
+ 0% {
214
+ -webkit-transform: scale(0.9);
215
+ -ms-transform: scale(0.9);
216
+ transform: scale(0.9);
217
+ }
218
+ 70% {
219
+ -webkit-transform: scale(1);
220
+ -ms-transform: scale(1);
221
+ transform: scale(1);
222
+ }
223
+ 100% {
224
+ -webkit-transform: scale(0.9);
225
+ -ms-transform: scale(0.9);
226
+ transform: scale(0.9);
227
+ }`
228
+
229
+ const pulseMD = keyframes`
230
+ 0% {
231
+ -webkit-transform: scale(0.7);
232
+ -ms-transform: scale(0.7);
233
+ transform: scale(0.7);
234
+ }
235
+ 70% {
236
+ -webkit-transform: scale(1);
237
+ -ms-transform: scale(1);
238
+ transform: scale(1);
239
+ }
240
+ 100% {
241
+ -webkit-transform: scale(0.7);
242
+ -ms-transform: scale(0.7);
243
+ transform: scale(0.7);
244
+ }`
245
+
246
+ const pulseLG = keyframes`
247
+ 0% {
248
+ -webkit-transform: scale(0.5);
249
+ -ms-transform: scale(0.5);
250
+ transform: scale(0.5);
251
+ }
252
+ 70% {
253
+ -webkit-transform: scale(1);
254
+ -ms-transform: scale(1);
255
+ transform: scale(1);
256
+ }
257
+ 100% {
258
+ -webkit-transform: scale(0.5);
259
+ -ms-transform: scale(0.5);
260
+ transform: scale(0.5);
261
+ }`
262
+
263
+ const noAnim = keyframes``
264
+
265
+ return {
266
+ X360,
267
+ Y360,
268
+ fadeInkf,
269
+ wobY,
270
+ wobX,
271
+ fwdx018,
272
+ fwdx1836,
273
+ fwdx09,
274
+ fwdx918,
275
+ fwdx1827,
276
+ fwdx2736,
277
+ fwdy018,
278
+ fwdy1836,
279
+ fwdy09,
280
+ fwdy918,
281
+ fwdy1827,
282
+ fwdy2736,
283
+ floatX,
284
+ floatShadow,
285
+ pulseSM,
286
+ pulseMD,
287
+ pulseLG,
288
+ noAnim,
289
+ }
290
+ }
@@ -0,0 +1,7 @@
1
+ import styled from 'styled-components'
2
+ export const ObjWrapper = styled.div`
3
+ width: 100%;
4
+ height: 100%;
5
+ position: relative;
6
+ transform-style: preserve-3d;
7
+ `
@@ -0,0 +1,30 @@
1
+ import styled from 'styled-components'
2
+ //import React from 'react'
3
+
4
+ interface SceneStyleProps {
5
+ width?: number | string
6
+ height?: number | string
7
+ perspective?: number | string | undefined
8
+ perspectiveOrigin?: string | undefined
9
+ zIndex?: number | undefined
10
+ children: any
11
+ }
12
+
13
+ export const SceneStyle = (props: SceneStyleProps) => {
14
+ const { width = 0, height = 0, perspective = 600, perspectiveOrigin = '50% 50%', zIndex = 10, children = {} } = props
15
+
16
+ const SceneStyleDiv: any = styled.div`
17
+ width: ${width}px;
18
+ height: ${height}px;
19
+ -webkit-perspective: ${perspective}px;
20
+ perspective: ${perspective}px;
21
+ -webkit-perspective-origin: ${perspectiveOrigin};
22
+ perspective-origin: ${perspectiveOrigin};
23
+ `
24
+
25
+ return (
26
+ <div style={{ zIndex }}>
27
+ <SceneStyleDiv>{children}</SceneStyleDiv>
28
+ </div>
29
+ )
30
+ }
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ //import MyCounter from './components/App'
2
+ //export { MyCounter }
3
+
4
+ import Face from './components/Faces/Face'
5
+ import { Cuboid } from './components/Cuboid'
6
+ import { Ribbon } from './components/Ribbon'
7
+ import { Card } from './components/Card'
8
+
9
+ export { Face, Cuboid, Ribbon, Card }
@@ -0,0 +1,29 @@
1
+ //import * as React from 'react'
2
+ import { render } from '@testing-library/react'
3
+
4
+ import 'jest-canvas-mock'
5
+
6
+ import { Face, Cuboid, Ribbon, Card } from '../src'
7
+
8
+ describe('Common render', () => {
9
+ it('renders without crashing', () => {
10
+ render(
11
+ <div>
12
+ <Cuboid />
13
+ <Face />
14
+ <Ribbon />
15
+ <Card />
16
+ </div>,
17
+ )
18
+ })
19
+ })
20
+
21
+ /*
22
+ import { MyCounter } from '../src'
23
+
24
+ describe('Common render', () => {
25
+ it('renders without crashing', () => {
26
+ render(<MyCounter />)
27
+ })
28
+ })
29
+ */
package/tsconfig.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es5",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "esModuleInterop": true,
8
+ "allowSyntheticDefaultImports": true,
9
+ "strict": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "noFallthroughCasesInSwitch": true,
12
+ "module": "esnext",
13
+ "moduleResolution": "node",
14
+ "resolveJsonModule": true,
15
+ "isolatedModules": true,
16
+ "noEmit": true,
17
+ "jsx": "react-jsx",
18
+ "importHelpers": true,
19
+ "declaration": true,
20
+ "sourceMap": true,
21
+ "rootDir": "./src",
22
+ "outDir": "./dist/esm",
23
+ "noImplicitReturns": true,
24
+ "noUnusedLocals": true,
25
+ "noUnusedParameters": true
26
+ },
27
+ "include": ["src"],
28
+ "exclude": ["dist", "node_modules"]
29
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2022 JTL (Saman)
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.