├── sound-cropped.mp4
├── boss-fight-sound-cropped.mp4
├── README.md
├── LICENSE.txt
├── src
├── index.html
├── style.scss
└── script.js
├── index.html
├── dist
├── index.html
├── style.css
└── script.js
├── style.scss
├── style.css
├── script.js
└── SplitText.min.js
/sound-cropped.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kibibit/boss-fight/main/sound-cropped.mp4
--------------------------------------------------------------------------------
/boss-fight-sound-cropped.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kibibit/boss-fight/main/boss-fight-sound-cropped.mp4
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # achievibit - Boss Battle
2 |
3 | A Pen created on CodePen.io. Original URL: [https://codepen.io/thatkookooguy/pen/JoPKVPO](https://codepen.io/thatkookooguy/pen/JoPKVPO).
4 |
5 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2024 neil kalman (https://codepen.io/thatkookooguy/pen/JoPKVPO)
4 | Fork of an original work GSAP Starter Template (https://codepen.io/GreenSock/pen/aYYOdN)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Made with Pixels to Svg https://codepen.io/shshaw/pen/XbxvNj
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ARE YOU READY TO BATTLE??
22 |
23 |
24 | I REALLY HOPE YOU DO...
25 |
26 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | achievibit: Boss Battle
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Made with Pixels to Svg https://codepen.io/shshaw/pen/XbxvNj
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | ARE YOU READY TO BATTLE??
34 |
35 |
36 | I REALLY HOPE YOU DO...
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | achievibit - Boss Battle
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Made with Pixels to Svg https://codepen.io/shshaw/pen/XbxvNj
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | ARE YOU READY TO BATTLE??
32 |
33 |
34 | I REALLY HOPE YOU DO...
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/dist/style.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Comfortaa:wght@700&family=Press+Start+2P&family=Righteous&display=swap");
2 | :root {
3 | --bar-fill: #57e705;
4 | --bar-top: #6aff03;
5 | --pixel-size: 7;
6 | }
7 |
8 | .healthbar {
9 | z-index: 10;
10 | position: fixed;
11 | left: 0;
12 | right: 0;
13 | width: calc(30px * var(--pixel-size));
14 | margin: 0 auto calc(2px * var(--pixel-size)) auto;
15 | display: block;
16 | }
17 |
18 | .healthbar_fill {
19 | width: 0%;
20 | fill: var(--bar-fill);
21 | transition: width 0.1s ease-in, fill 0.2s linear;
22 | }
23 |
24 | .healthbar_fill-top {
25 | width: 0%;
26 | fill: var(--bar-top);
27 | }
28 |
29 | .fill-bar-animation {
30 | animation: fill-bar 4s ease-out forwards;
31 | }
32 |
33 | html,
34 | body {
35 | margin: 0;
36 | padding: 0;
37 | }
38 |
39 | body {
40 | font-family: Avenir, sans-serif;
41 | background-color: #212121;
42 | color: #fffce1;
43 | display: flex;
44 | align-items: center;
45 | justify-content: center;
46 | height: 100vh;
47 | flex-direction: column;
48 | }
49 |
50 | p {
51 | max-width: 70ch;
52 | font-size: 1.4rem;
53 | text-align: center;
54 | line-height: 1.3;
55 | }
56 |
57 | .game {
58 | position: absolute;
59 | width: 100dvw;
60 | height: 100dvh;
61 | overflow: hidden;
62 | bottom: 0;
63 | }
64 |
65 | .rpg-text-box {
66 | color: #ff3860;
67 | height: 100px;
68 | left: 50%;
69 | position: absolute;
70 | bottom: 0;
71 | transform: translate(-50%, calc(100% + 50px + 50px));
72 | max-width: 500px;
73 | width: 80vw;
74 | line-height: 1.5em;
75 | margin: 2em 0;
76 | background: white;
77 | border: 1px solid white;
78 | padding: 1em;
79 | font-size: 0.7rem;
80 | font-family: "Press Start 2P", cursive;
81 | font-weight: bolder;
82 | border-radius: 0.2em;
83 | box-shadow: 0 1px 0 1px black, inset 0 1px 0 1px black, 0 0 0 1px black, inset 0 0 0 1px black, 3px 5px 0px 1px rgba(0, 0, 0, 0.25);
84 | opacity: 0;
85 | transition: all 250ms;
86 | z-index: 10;
87 | }
88 |
89 | .rpg-text-box.visible {
90 | opacity: 1;
91 | transform: translate(-50%);
92 | }
93 |
94 | .code-editor {
95 | position: absolute;
96 | top: 0;
97 | /* bottom: 0; */
98 | left: 0;
99 | right: 0;
100 | background: black;
101 | transition: all 500ms cubic-bezier(0.47, 1.64, 0.41, 0.8);
102 | height: 0;
103 | }
104 |
105 | .code-editor.reveal {
106 | height: 100%;
107 | }
108 |
109 | .monster {
110 | width: 100%;
111 | height: 100%;
112 | position: absolute;
113 | bottom: 25px;
114 | display: flex;
115 | align-items: center;
116 | justify-content: center;
117 | position: relative;
118 | /* Keep relative positioning for better layout control */
119 | animation: rise-up 4s ease-out forwards, shake-constant 2s infinite;
120 | }
121 | .monster img {
122 | width: 100%;
123 | max-width: 700px;
124 | }
125 |
126 | @keyframes fill-bar {
127 | from {
128 | width: 0%;
129 | }
130 | to {
131 | width: 100%;
132 | }
133 | }
134 | /* Keyframes for rising up */
135 | @keyframes rise-up {
136 | from {
137 | transform: translateY(100%);
138 | /* Start below the original position */
139 | }
140 | to {
141 | transform: translateY(0);
142 | /* End at the original position */
143 | }
144 | }
145 | .monster .shake-constant {
146 | animation-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
147 | /* Smooth timing */
148 | animation-duration: 2s;
149 | /* Slower shake timing */
150 | }
151 |
152 | #textbox2 {
153 | display: flex;
154 | align-items: center;
155 | justify-content: center;
156 | }
157 |
158 | #canvas {
159 | position: fixed;
160 | z-index: 5;
161 | pointer-events: none;
162 | }
--------------------------------------------------------------------------------
/src/style.scss:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Comfortaa:wght@700&family=Press+Start+2P&family=Righteous&display=swap");
2 |
3 | :root {
4 | --bar-fill: #57e705;
5 | --bar-top: #6aff03;
6 | --pixel-size: 7;
7 | }
8 |
9 | .healthbar {
10 | z-index: 10;
11 | position: fixed;
12 | left: 0;
13 | right: 0;
14 | width: calc(30px * var(--pixel-size));
15 | margin: 0 auto calc(2px * var(--pixel-size)) auto;
16 | display: block;
17 | }
18 |
19 | .healthbar_fill {
20 | width: 0%;
21 | fill: var(--bar-fill);
22 | transition: width 0.1s ease-in, fill 0.2s linear;
23 | }
24 | .healthbar_fill-top {
25 | width: 0%;
26 | fill: var(--bar-top);
27 | }
28 |
29 | .fill-bar-animation {
30 | animation: fill-bar 4s ease-out forwards;
31 | }
32 |
33 | html,
34 | body {
35 | margin: 0;
36 | padding: 0;
37 | }
38 |
39 | body {
40 | font-family: Avenir, sans-serif;
41 | background-color: #212121;
42 | color: #fffce1;
43 | display: flex;
44 | align-items: center;
45 | justify-content: center;
46 | height: 100vh;
47 | flex-direction: column;
48 | }
49 |
50 | p {
51 | max-width: 70ch;
52 | font-size: 1.4rem;
53 | text-align: center;
54 | line-height: 1.3;
55 | }
56 |
57 | .game {
58 | position: absolute;
59 | width: 100dvw;
60 | height: 100dvh;
61 | overflow: hidden;
62 | bottom: 0;
63 | }
64 |
65 | .rpg-text-box {
66 | color: hsl(348, 100%, 61%);
67 | height: 100px;
68 | left: 50%;
69 | position: absolute;
70 | bottom: 0;
71 | transform: translate(-50%, calc(100% + 50px + 50px));
72 | max-width: 500px;
73 | width: 80vw;
74 | line-height: 1.5em;
75 | margin: 2em 0;
76 | background: white;
77 | border: 1px solid white;
78 | padding: 1em;
79 | font-size: 0.7rem;
80 | font-family: "Press Start 2P", cursive;
81 | font-weight: bolder;
82 | border-radius: 0.2em;
83 | box-shadow: 0 1px 0 1px black, inset 0 1px 0 1px black, 0 0 0 1px black,
84 | inset 0 0 0 1px black, 3px 5px 0px 1px rgba(0, 0, 0, 0.25);
85 | opacity: 0;
86 | transition: all 250ms;
87 | z-index: 10;
88 | }
89 |
90 | .rpg-text-box.visible {
91 | opacity: 1;
92 | transform: translate(-50%);
93 | }
94 |
95 | .code-editor {
96 | position: absolute;
97 | top: 0;
98 | /* bottom: 0; */
99 | left: 0;
100 | right: 0;
101 | background: black;
102 | transition: all 500ms cubic-bezier(0.47, 1.64, 0.41, 0.8);
103 | height: 0;
104 | }
105 |
106 | .code-editor.reveal {
107 | height: 100%;
108 | }
109 |
110 | .monster {
111 | width: 100%;
112 | height: 100%;
113 | position: absolute;
114 | bottom: 25px;
115 | display: flex;
116 | align-items: center;
117 | justify-content: center;
118 | position: relative; /* Keep relative positioning for better layout control */
119 | animation: rise-up 4s ease-out forwards, shake-constant 2s infinite;
120 |
121 | img {
122 | width: 100%;
123 | max-width: 700px;
124 | }
125 | }
126 |
127 | @keyframes fill-bar {
128 | from {
129 | width: 0%;
130 | }
131 | to {
132 | width: 100%;
133 | }
134 | }
135 |
136 | /* Keyframes for rising up */
137 | @keyframes rise-up {
138 | from {
139 | transform: translateY(100%); /* Start below the original position */
140 | }
141 | to {
142 | transform: translateY(0); /* End at the original position */
143 | }
144 | }
145 |
146 | .monster .shake-constant {
147 | animation-timing-function: cubic-bezier(
148 | 0.25,
149 | 0.1,
150 | 0.25,
151 | 1
152 | ); /* Smooth timing */
153 | animation-duration: 2s; /* Slower shake timing */
154 | }
155 |
156 | #textbox2 {
157 | display: flex;
158 | align-items: center;
159 | justify-content: center;
160 | }
161 |
162 | #canvas {
163 | position: fixed;
164 | z-index: 5;
165 | pointer-events: none;
166 | }
167 |
--------------------------------------------------------------------------------
/style.scss:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Comfortaa:wght@700&family=Press+Start+2P&family=Righteous&display=swap");
2 |
3 | :root {
4 | --bar-fill: #57e705;
5 | --bar-top: #6aff03;
6 | --pixel-size: 7;
7 | }
8 |
9 | .healthbar {
10 | z-index: 10;
11 | position: fixed;
12 | left: 0;
13 | right: 0;
14 | width: calc(30px * var(--pixel-size));
15 | margin: 0 auto calc(2px * var(--pixel-size)) auto;
16 | display: block;
17 | }
18 |
19 | .healthbar_fill {
20 | width: 0%;
21 | fill: var(--bar-fill);
22 | transition: width 0.1s ease-in, fill 0.2s linear;
23 | }
24 | .healthbar_fill-top {
25 | width: 0%;
26 | fill: var(--bar-top);
27 | }
28 |
29 | .fill-bar-animation {
30 | animation: fill-bar 4s ease-out forwards;
31 | }
32 |
33 | html,
34 | body {
35 | margin: 0;
36 | padding: 0;
37 | }
38 |
39 | body {
40 | font-family: Avenir, sans-serif;
41 | background-color: #212121;
42 | color: #fffce1;
43 | display: flex;
44 | align-items: center;
45 | justify-content: center;
46 | height: 100vh;
47 | flex-direction: column;
48 | }
49 |
50 | p {
51 | max-width: 70ch;
52 | font-size: 1.4rem;
53 | text-align: center;
54 | line-height: 1.3;
55 | }
56 |
57 | .game {
58 | position: absolute;
59 | width: 100dvw;
60 | height: 100dvh;
61 | overflow: hidden;
62 | bottom: 0;
63 | }
64 |
65 | .rpg-text-box {
66 | color: hsl(348, 100%, 61%);
67 | height: 100px;
68 | left: 50%;
69 | position: absolute;
70 | bottom: 0;
71 | transform: translate(-50%, calc(100% + 50px + 50px));
72 | max-width: 500px;
73 | width: 80vw;
74 | line-height: 1.5em;
75 | margin: 2em 0;
76 | background: white;
77 | border: 1px solid white;
78 | padding: 1em;
79 | font-size: 0.7rem;
80 | font-family: "Press Start 2P", cursive;
81 | font-weight: bolder;
82 | border-radius: 0.2em;
83 | box-shadow: 0 1px 0 1px black, inset 0 1px 0 1px black, 0 0 0 1px black,
84 | inset 0 0 0 1px black, 3px 5px 0px 1px rgba(0, 0, 0, 0.25);
85 | opacity: 0;
86 | transition: all 250ms;
87 | z-index: 10;
88 | }
89 |
90 | .rpg-text-box.visible {
91 | opacity: 1;
92 | transform: translate(-50%);
93 | }
94 |
95 | .code-editor {
96 | position: absolute;
97 | top: 0;
98 | /* bottom: 0; */
99 | left: 0;
100 | right: 0;
101 | background: black;
102 | transition: all 500ms cubic-bezier(0.47, 1.64, 0.41, 0.8);
103 | height: 0;
104 | }
105 |
106 | .code-editor.reveal {
107 | height: 100%;
108 | }
109 |
110 | .monster {
111 | width: 100%;
112 | height: 100%;
113 | position: absolute;
114 | bottom: 25px;
115 | display: flex;
116 | align-items: center;
117 | justify-content: center;
118 | position: relative; /* Keep relative positioning for better layout control */
119 | animation: rise-up 4s ease-out forwards, shake-constant 2s infinite;
120 |
121 | img {
122 | width: 100%;
123 | max-width: 700px;
124 | }
125 | }
126 |
127 | @keyframes fill-bar {
128 | from {
129 | width: 0%;
130 | }
131 | to {
132 | width: 100%;
133 | }
134 | }
135 |
136 | /* Keyframes for rising up */
137 | @keyframes rise-up {
138 | from {
139 | transform: translateY(100%); /* Start below the original position */
140 | }
141 | to {
142 | transform: translateY(0); /* End at the original position */
143 | }
144 | }
145 |
146 | .monster .shake-constant {
147 | animation-timing-function: cubic-bezier(
148 | 0.25,
149 | 0.1,
150 | 0.25,
151 | 1
152 | ); /* Smooth timing */
153 | animation-duration: 2s; /* Slower shake timing */
154 | }
155 |
156 | #textbox2 {
157 | display: flex;
158 | align-items: center;
159 | justify-content: center;
160 | }
161 |
162 | #canvas {
163 | position: fixed;
164 | z-index: 5;
165 | pointer-events: none;
166 | }
167 |
--------------------------------------------------------------------------------
/dist/script.js:
--------------------------------------------------------------------------------
1 | // Testing animation concepts for boss battle
2 |
3 | const textBoxText = document.getElementById("textbox");
4 | const textBoxText2 = document.getElementById("textbox2");
5 |
6 | const split = new SplitText(textBoxText, {
7 | charsClass: "kb-char shake-constant",
8 | linesClass: "kb-line"
9 | });
10 |
11 | const chars = split.chars;
12 |
13 | const nextSplit = new SplitText(textBoxText2, {
14 | charsClass: "kb-char shake-constant",
15 | linesClass: "kb-line"
16 | });
17 |
18 | const chars2 = nextSplit.chars;
19 |
20 | const codeEditorDiv = document.createElement("div");
21 | codeEditorDiv.className = "code-editor";
22 |
23 | const codeEditorDiv2 = document.createElement("div");
24 | codeEditorDiv2.className = "code-editor reveal";
25 |
26 | // Insert it at the beginning of textBoxText
27 | textBoxText.prepend(codeEditorDiv);
28 | textBoxText2.prepend(codeEditorDiv2);
29 |
30 | chars.forEach((char, index) => {
31 | char.classList.add("shake-little");
32 |
33 | // Calculate a pseudo-random delay based on the index
34 | const delay = Math.random() * 0.2 + index * 0.05; // Adjust randomness and staggering here
35 |
36 | // Set the delay as an inline style
37 | char.style.animationDelay = `${delay}s`;
38 | });
39 |
40 | chars2.forEach((char, index) => {
41 | char.classList.add("shake-little");
42 |
43 | // Calculate a pseudo-random delay based on the index
44 | const delay = Math.random() * 0.2 + index * 0.05; // Adjust randomness and staggering here
45 |
46 | // Set the delay as an inline style
47 | char.style.animationDelay = `${delay}s`;
48 | });
49 |
50 | let currentLine;
51 |
52 | var tl = new TimelineMax({
53 | // onComplete: () => {
54 | // codeEditorDiv.classList.add("reveal");
55 | // }
56 | });
57 |
58 | tl.delay(2);
59 |
60 | tl.call(
61 | function () {
62 | textBoxText.classList.add("visible");
63 | },
64 | null,
65 | null,
66 | 0
67 | )
68 | .staggerFrom(
69 | chars,
70 | 0.8,
71 | {
72 | opacity: 0,
73 | ease: SteppedEase.config(1)
74 | },
75 | 0.08,
76 | "+=0"
77 | )
78 | .call(
79 | function () {
80 | codeEditorDiv.classList.add("reveal");
81 | },
82 | null,
83 | "+=0.5",
84 | 0
85 | )
86 | .call(
87 | function () {
88 | textBoxText.style.display = "none";
89 | textBoxText2.style.display = "flex";
90 | },
91 | null,
92 | "+=0.5",
93 | 0
94 | )
95 | .staggerFrom(
96 | chars2,
97 | 0.8,
98 | {
99 | opacity: 0,
100 | ease: SteppedEase.config(1)
101 | },
102 | 0.08,
103 | "+=0"
104 | )
105 | .pause();
106 |
107 | tl.play();
108 |
109 | ///////
110 |
111 | console.clear();
112 |
113 | var canvasLightning = function (c, cw, ch) {
114 | this.init = function () {
115 | this.loop();
116 | };
117 |
118 | var _this = this;
119 | this.c = c;
120 | this.ctx = c.getContext("2d");
121 | this.cw = cw;
122 | this.ch = ch;
123 | this.mx = 0;
124 | this.my = 0;
125 |
126 | this.now = Date.now();
127 | this.delta = 0;
128 | this.then = this.now;
129 |
130 | this.lightning = [];
131 | this.lightTimeCurrent = 0;
132 | this.lightTimeTotal = 50;
133 |
134 | this.rand = function (rMi, rMa) {
135 | return ~~(Math.random() * (rMa - rMi + 1) + rMi);
136 | };
137 |
138 | this.createL = function (x, y, canSpawn) {
139 | this.lightning.push({
140 | x: x,
141 | y: y,
142 | xRange: this.rand(5, 30),
143 | yRange: this.rand(5, 25),
144 | path: [
145 | {
146 | x: x,
147 | y: y
148 | }
149 | ],
150 | pathLimit: this.rand(10, 35),
151 | canSpawn: canSpawn,
152 | hasFired: false,
153 | grower: 0,
154 | growerLimit: 5 //this.rand(5, 15)
155 | });
156 | };
157 |
158 | this.updateL = function () {
159 | var i = this.lightning.length;
160 | while (i--) {
161 | var light = this.lightning[i];
162 |
163 | light.grower += this.delta;
164 |
165 | if (light.grower >= light.growerLimit) {
166 | light.grower = 0;
167 | light.growerLimit *= 1.05;
168 |
169 | light.path.push({
170 | x:
171 | light.path[light.path.length - 1].x +
172 | (this.rand(0, light.xRange) - light.xRange / 2),
173 | y: light.path[light.path.length - 1].y + this.rand(0, light.yRange)
174 | });
175 |
176 | if (light.path.length > light.pathLimit) {
177 | this.lightning.splice(i, 1);
178 | }
179 | light.hasFired = true;
180 | }
181 | }
182 | };
183 |
184 | this.renderL = function () {
185 | var i = this.lightning.length;
186 | while (i--) {
187 | var light = this.lightning[i];
188 |
189 | const randomColor = Math.random();
190 | this.ctx.strokeStyle =
191 | "hsla(0, 100%, 100%, " + this.rand(10, 100) / 100 + ")";
192 | if (randomColor >= 0.33 && randomColor < 0.8) {
193 | this.ctx.strokeStyle =
194 | "hsla(248, 53%, 58%, " + this.rand(10, 100) / 100 + ")";
195 | }
196 |
197 | if (randomColor >= 0.8) {
198 | this.ctx.strokeStyle =
199 | "hsla(204, 86%, 53%, " + this.rand(10, 100) / 100 + ")";
200 | }
201 |
202 | this.ctx.lineWidth = 4;
203 | if (this.rand(0, 30) == 0) {
204 | this.ctx.lineWidth = 5;
205 | }
206 | if (this.rand(0, 60) == 0) {
207 | this.ctx.lineWidth = 6;
208 | }
209 | if (this.rand(0, 90) == 0) {
210 | this.ctx.lineWidth = 7;
211 | }
212 |
213 | this.ctx.beginPath();
214 |
215 | var pathCount = light.path.length;
216 | this.ctx.moveTo(light.x, light.y);
217 | for (var pc = 0; pc < pathCount; pc++) {
218 | this.ctx.lineTo(light.path[pc].x, light.path[pc].y);
219 |
220 | if (light.canSpawn) {
221 | if (this.rand(0, 100) == 0) {
222 | light.canSpawn = false;
223 | this.createL(light.path[pc].x, light.path[pc].y, false);
224 | }
225 | }
226 | }
227 |
228 | if (!light.hasFired) {
229 | this.ctx.fillStyle =
230 | "rgba(255, 255, 255, " + this.rand(4, 12) / 100 + ")";
231 | this.ctx.fillRect(0, 0, this.cw, this.ch);
232 | }
233 |
234 | if (this.rand(0, 60) == 0) {
235 | this.ctx.fillStyle =
236 | "rgba(255, 255, 255, " + this.rand(1, 3) / 100 + ")";
237 | this.ctx.fillRect(0, 0, this.cw, this.ch);
238 | }
239 |
240 | this.ctx.stroke();
241 | }
242 | };
243 |
244 | this.lightningTimer = function () {
245 | this.lightTimeCurrent += this.delta;
246 | if (this.lightTimeCurrent >= this.lightTimeTotal) {
247 | var newX = this.rand(100, cw - 100);
248 | var newY = this.rand(0, ch / 2);
249 | var createCount = this.rand(1, 3);
250 | while (createCount--) {
251 | this.createL(newX, newY, true);
252 | }
253 | this.lightTimeCurrent = 0;
254 | this.lightTimeTotal = this.rand(200, 1500);
255 | }
256 | };
257 |
258 | this.clearCanvas = function () {
259 | this.ctx.globalCompositeOperation = "destination-out";
260 | this.ctx.fillStyle = "rgba(0,0,0," + this.rand(1, 30) / 100 + ")";
261 | this.ctx.fillRect(0, 0, this.cw, this.ch);
262 | this.ctx.globalCompositeOperation = "source-over";
263 | };
264 |
265 | window.addEventListener("resize", () => {
266 | this.cw = this.c.width = window.innerWidth;
267 | this.ch = this.c.height = window.innerHeight;
268 | });
269 |
270 | this.loop = function () {
271 | requestAnimationFrame(this.loop.bind(this));
272 |
273 | this.now = Date.now();
274 | this.delta = this.now - this.then;
275 | this.then = this.now;
276 |
277 | this.clearCanvas();
278 | this.updateL();
279 | this.lightningTimer();
280 | this.renderL();
281 | };
282 | };
283 |
284 | var c = document.getElementById("canvas");
285 | var cw = (c.width = window.innerWidth);
286 | var ch = (c.height = window.innerHeight);
287 | var cl = new canvasLightning(c, cw, ch);
288 |
289 | cl.init();
--------------------------------------------------------------------------------
/src/script.js:
--------------------------------------------------------------------------------
1 | // Testing animation concepts for boss battle
2 |
3 | const textBoxText = document.getElementById("textbox");
4 | const textBoxText2 = document.getElementById("textbox2");
5 |
6 | const split = new SplitText(textBoxText, {
7 | charsClass: "kb-char shake-constant",
8 | linesClass: "kb-line"
9 | });
10 |
11 | const chars = split.chars;
12 |
13 | const nextSplit = new SplitText(textBoxText2, {
14 | charsClass: "kb-char shake-constant",
15 | linesClass: "kb-line"
16 | });
17 |
18 | const chars2 = nextSplit.chars;
19 |
20 | const codeEditorDiv = document.createElement("div");
21 | codeEditorDiv.className = "code-editor";
22 |
23 | const codeEditorDiv2 = document.createElement("div");
24 | codeEditorDiv2.className = "code-editor reveal";
25 |
26 | // Insert it at the beginning of textBoxText
27 | textBoxText.prepend(codeEditorDiv);
28 | textBoxText2.prepend(codeEditorDiv2);
29 |
30 | chars.forEach((char, index) => {
31 | char.classList.add("shake-little");
32 |
33 | // Calculate a pseudo-random delay based on the index
34 | const delay = Math.random() * 0.2 + index * 0.05; // Adjust randomness and staggering here
35 |
36 | // Set the delay as an inline style
37 | char.style.animationDelay = `${delay}s`;
38 | });
39 |
40 | chars2.forEach((char, index) => {
41 | char.classList.add("shake-little");
42 |
43 | // Calculate a pseudo-random delay based on the index
44 | const delay = Math.random() * 0.2 + index * 0.05; // Adjust randomness and staggering here
45 |
46 | // Set the delay as an inline style
47 | char.style.animationDelay = `${delay}s`;
48 | });
49 |
50 | let currentLine;
51 |
52 | var tl = new TimelineMax({
53 | // onComplete: () => {
54 | // codeEditorDiv.classList.add("reveal");
55 | // }
56 | });
57 |
58 | tl.delay(2);
59 |
60 | tl.call(
61 | function () {
62 | textBoxText.classList.add("visible");
63 | },
64 | null,
65 | null,
66 | 0
67 | )
68 | .staggerFrom(
69 | chars,
70 | 0.8,
71 | {
72 | opacity: 0,
73 | ease: SteppedEase.config(1)
74 | },
75 | 0.08,
76 | "+=0"
77 | )
78 | .call(
79 | function () {
80 | codeEditorDiv.classList.add("reveal");
81 | },
82 | null,
83 | "+=0.5",
84 | 0
85 | )
86 | .call(
87 | function () {
88 | textBoxText.style.display = "none";
89 | textBoxText2.style.display = "flex";
90 | },
91 | null,
92 | "+=0.5",
93 | 0
94 | )
95 | .staggerFrom(
96 | chars2,
97 | 0.8,
98 | {
99 | opacity: 0,
100 | ease: SteppedEase.config(1)
101 | },
102 | 0.08,
103 | "+=0"
104 | )
105 | .pause();
106 |
107 | tl.play();
108 |
109 | ///////
110 |
111 | console.clear();
112 |
113 | var canvasLightning = function (c, cw, ch) {
114 | this.init = function () {
115 | this.loop();
116 | };
117 |
118 | var _this = this;
119 | this.c = c;
120 | this.ctx = c.getContext("2d");
121 | this.cw = cw;
122 | this.ch = ch;
123 | this.mx = 0;
124 | this.my = 0;
125 |
126 | this.now = Date.now();
127 | this.delta = 0;
128 | this.then = this.now;
129 |
130 | this.lightning = [];
131 | this.lightTimeCurrent = 0;
132 | this.lightTimeTotal = 50;
133 |
134 | this.rand = function (rMi, rMa) {
135 | return ~~(Math.random() * (rMa - rMi + 1) + rMi);
136 | };
137 |
138 | this.createL = function (x, y, canSpawn) {
139 | this.lightning.push({
140 | x: x,
141 | y: y,
142 | xRange: this.rand(5, 30),
143 | yRange: this.rand(5, 25),
144 | path: [
145 | {
146 | x: x,
147 | y: y
148 | }
149 | ],
150 | pathLimit: this.rand(10, 35),
151 | canSpawn: canSpawn,
152 | hasFired: false,
153 | grower: 0,
154 | growerLimit: 5 //this.rand(5, 15)
155 | });
156 | };
157 |
158 | this.updateL = function () {
159 | var i = this.lightning.length;
160 | while (i--) {
161 | var light = this.lightning[i];
162 |
163 | light.grower += this.delta;
164 |
165 | if (light.grower >= light.growerLimit) {
166 | light.grower = 0;
167 | light.growerLimit *= 1.05;
168 |
169 | light.path.push({
170 | x:
171 | light.path[light.path.length - 1].x +
172 | (this.rand(0, light.xRange) - light.xRange / 2),
173 | y: light.path[light.path.length - 1].y + this.rand(0, light.yRange)
174 | });
175 |
176 | if (light.path.length > light.pathLimit) {
177 | this.lightning.splice(i, 1);
178 | }
179 | light.hasFired = true;
180 | }
181 | }
182 | };
183 |
184 | this.renderL = function () {
185 | var i = this.lightning.length;
186 | while (i--) {
187 | var light = this.lightning[i];
188 |
189 | const randomColor = Math.random();
190 | this.ctx.strokeStyle =
191 | "hsla(0, 100%, 100%, " + this.rand(10, 100) / 100 + ")";
192 | if (randomColor >= 0.33 && randomColor < 0.8) {
193 | this.ctx.strokeStyle =
194 | "hsla(248, 53%, 58%, " + this.rand(10, 100) / 100 + ")";
195 | }
196 |
197 | if (randomColor >= 0.8) {
198 | this.ctx.strokeStyle =
199 | "hsla(204, 86%, 53%, " + this.rand(10, 100) / 100 + ")";
200 | }
201 |
202 | this.ctx.lineWidth = 4;
203 | if (this.rand(0, 30) == 0) {
204 | this.ctx.lineWidth = 5;
205 | }
206 | if (this.rand(0, 60) == 0) {
207 | this.ctx.lineWidth = 6;
208 | }
209 | if (this.rand(0, 90) == 0) {
210 | this.ctx.lineWidth = 7;
211 | }
212 |
213 | this.ctx.beginPath();
214 |
215 | var pathCount = light.path.length;
216 | this.ctx.moveTo(light.x, light.y);
217 | for (var pc = 0; pc < pathCount; pc++) {
218 | this.ctx.lineTo(light.path[pc].x, light.path[pc].y);
219 |
220 | if (light.canSpawn) {
221 | if (this.rand(0, 100) == 0) {
222 | light.canSpawn = false;
223 | this.createL(light.path[pc].x, light.path[pc].y, false);
224 | }
225 | }
226 | }
227 |
228 | if (!light.hasFired) {
229 | this.ctx.fillStyle =
230 | "rgba(255, 255, 255, " + this.rand(4, 12) / 100 + ")";
231 | this.ctx.fillRect(0, 0, this.cw, this.ch);
232 | }
233 |
234 | if (this.rand(0, 60) == 0) {
235 | this.ctx.fillStyle =
236 | "rgba(255, 255, 255, " + this.rand(1, 3) / 100 + ")";
237 | this.ctx.fillRect(0, 0, this.cw, this.ch);
238 | }
239 |
240 | this.ctx.stroke();
241 | }
242 | };
243 |
244 | this.lightningTimer = function () {
245 | this.lightTimeCurrent += this.delta;
246 | if (this.lightTimeCurrent >= this.lightTimeTotal) {
247 | var newX = this.rand(100, cw - 100);
248 | var newY = this.rand(0, ch / 2);
249 | var createCount = this.rand(1, 3);
250 | while (createCount--) {
251 | this.createL(newX, newY, true);
252 | }
253 | this.lightTimeCurrent = 0;
254 | this.lightTimeTotal = this.rand(200, 1500);
255 | }
256 | };
257 |
258 | this.clearCanvas = function () {
259 | this.ctx.globalCompositeOperation = "destination-out";
260 | this.ctx.fillStyle = "rgba(0,0,0," + this.rand(1, 30) / 100 + ")";
261 | this.ctx.fillRect(0, 0, this.cw, this.ch);
262 | this.ctx.globalCompositeOperation = "source-over";
263 | };
264 |
265 | window.addEventListener("resize", () => {
266 | this.cw = this.c.width = window.innerWidth;
267 | this.ch = this.c.height = window.innerHeight;
268 | });
269 |
270 | this.loop = function () {
271 | requestAnimationFrame(this.loop.bind(this));
272 |
273 | this.now = Date.now();
274 | this.delta = this.now - this.then;
275 | this.then = this.now;
276 |
277 | this.clearCanvas();
278 | this.updateL();
279 | this.lightningTimer();
280 | this.renderL();
281 | };
282 | };
283 |
284 | var c = document.getElementById("canvas");
285 | var cw = (c.width = window.innerWidth);
286 | var ch = (c.height = window.innerHeight);
287 | var cl = new canvasLightning(c, cw, ch);
288 |
289 | cl.init();
290 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Comfortaa:wght@700&family=Press+Start+2P&family=Righteous&display=swap");
2 | :root {
3 | --bar-fill: #57e705;
4 | --bar-top: #6aff03;
5 | --pixel-size: 7;
6 | }
7 |
8 | .healthbar {
9 | z-index: 10;
10 | position: fixed;
11 | left: 0;
12 | right: 0;
13 | width: calc(30px * var(--pixel-size));
14 | margin: 0 auto calc(2px * var(--pixel-size)) auto;
15 | display: block;
16 | }
17 |
18 | .healthbar_fill {
19 | width: 0%;
20 | fill: var(--bar-fill);
21 | transition: width 0.1s ease-in, fill 0.2s linear;
22 | }
23 |
24 | .healthbar_fill-top {
25 | width: 0%;
26 | fill: var(--bar-top);
27 | }
28 |
29 | .fill-bar-animation {
30 | animation: fill-bar 6s ease-out forwards;
31 | }
32 |
33 | html,
34 | body {
35 | margin: 0;
36 | padding: 0;
37 | }
38 |
39 | body {
40 | font-family: Avenir, sans-serif;
41 | background-color: #212121;
42 | color: #fffce1;
43 | display: flex;
44 | align-items: center;
45 | justify-content: center;
46 | height: 100vh;
47 | flex-direction: column;
48 | }
49 |
50 | p {
51 | max-width: 70ch;
52 | font-size: 1.4rem;
53 | text-align: center;
54 | line-height: 1.3;
55 | }
56 |
57 | .game {
58 | position: absolute;
59 | width: 100dvw;
60 | height: 100dvh;
61 | overflow: hidden;
62 | bottom: 0;
63 | }
64 |
65 | .rpg-text-box {
66 | overflow: hidden;
67 | color: #ff3860;
68 | height: 100px;
69 | left: 50%;
70 | position: absolute;
71 | bottom: 0;
72 | transform: translate(-50%, calc(100% + 50px + 50px));
73 | max-width: 500px;
74 | width: 80vw;
75 | line-height: 1.5em;
76 | margin: 2em 0;
77 | background: white;
78 | border: 1px solid white;
79 | padding: 1em;
80 | font-size: 0.7rem;
81 | font-family: "Press Start 2P", cursive;
82 | font-weight: bolder;
83 | border-radius: 0.2em;
84 | box-shadow: 0 1px 0 1px black, inset 0 1px 0 1px black, 0 0 0 1px black, inset 0 0 0 1px black, 3px 5px 0px 1px rgba(0, 0, 0, 0.25);
85 | opacity: 0;
86 | transition: all 250ms;
87 | z-index: 10;
88 | }
89 | .rpg-text-box.cont-dot:after {
90 | opacity: 1;
91 | }
92 | .rpg-text-box:after {
93 | opacity: 0;
94 | content: "";
95 | display: block;
96 | position: absolute;
97 | width: 10px;
98 | height: 10px;
99 | background-color: currentColor;
100 | bottom: 1em;
101 | right: 1em;
102 | animation: gelatine 1s infinite;
103 | transition: 250ms opacity;
104 | }
105 |
106 | .gelatine {
107 | animation: gelatine 0.5s infinite;
108 | }
109 |
110 | @keyframes gelatine {
111 | from, to {
112 | transform: scale(1, 1);
113 | }
114 | 25% {
115 | transform: scale(0.9, 1.1);
116 | }
117 | 50% {
118 | transform: scale(1.1, 0.9);
119 | }
120 | 75% {
121 | transform: scale(0.95, 1.05);
122 | }
123 | }
124 | .rpg-text-box.visible {
125 | opacity: 1;
126 | transform: translate(-50%);
127 | }
128 |
129 | .code-editor {
130 | position: absolute;
131 | top: 0;
132 | /* bottom: 0; */
133 | left: 0;
134 | right: 0;
135 | background: black;
136 | height: 0;
137 | }
138 |
139 | .code-editor.reveal {
140 | height: 100%;
141 | transition: all 500ms cubic-bezier(0.47, 1.64, 0.41, 0.8);
142 | }
143 |
144 | .monster {
145 | width: 100%;
146 | height: 100%;
147 | position: absolute;
148 | bottom: 25px;
149 | display: flex;
150 | align-items: center;
151 | justify-content: center;
152 | position: relative;
153 | /* Keep relative positioning for better layout control */
154 | animation: rise-up 6s ease-out forwards, shake-constant 2s infinite;
155 | }
156 | .monster img {
157 | width: 100%;
158 | max-width: 700px;
159 | }
160 |
161 | @keyframes fill-bar {
162 | from {
163 | width: 0%;
164 | }
165 | to {
166 | width: 100%;
167 | }
168 | }
169 | /* Keyframes for rising up */
170 | @keyframes rise-up {
171 | from {
172 | transform: translateY(100%);
173 | /* Start below the original position */
174 | }
175 | to {
176 | transform: translateY(0);
177 | /* End at the original position */
178 | }
179 | }
180 | .monster .shake-constant {
181 | animation-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
182 | /* Smooth timing */
183 | animation-duration: 2s;
184 | /* Slower shake timing */
185 | }
186 |
187 | #textbox2 {
188 | display: flex;
189 | align-items: center;
190 | justify-content: center;
191 | }
192 |
193 | #canvas {
194 | position: fixed;
195 | z-index: 5;
196 | pointer-events: none;
197 | }
198 |
199 | .cont {
200 | --angle: 180deg;
201 | --color: #ff5233;
202 | top: 0;
203 | left: 0;
204 | width: 100%;
205 | bottom: -15px;
206 | position: absolute;
207 | overflow: hidden;
208 | border-top: 2px solid var(--color);
209 | border-bottom: 15px solid var(--color);
210 | filter: url("#goo");
211 | animation: fill-up 1s ease-out forwards;
212 | }
213 | .cont .drip {
214 | height: 30px;
215 | width: 30px;
216 | border-radius: 50%;
217 | background: black;
218 | position: absolute;
219 | top: -100%;
220 | animation: falling 500ms linear infinite;
221 | }
222 | @keyframes fill-up {
223 | from {
224 | border-bottom-width: 15px;
225 | }
226 | to {
227 | border-bottom-width: 150px;
228 | }
229 | }
230 | @keyframes falling {
231 | 0% {
232 | top: -100%;
233 | }
234 | 50% {
235 | top: 0%;
236 | }
237 | 80% {
238 | top: 80%;
239 | }
240 | 100% {
241 | top: 100%;
242 | }
243 | }
244 | .cont .drip:nth-child(1) {
245 | border-color: var(--color);
246 | height: 14px;
247 | width: 14px;
248 | animation-delay: -0.2s;
249 | background: var(--color);
250 | left: 234px;
251 | margin-left: 60px;
252 | }
253 | .cont .drip:nth-child(2) {
254 | border-color: var(--color);
255 | height: 2px;
256 | width: 2px;
257 | animation-delay: -0.4s;
258 | background: var(--color);
259 | left: 75px;
260 | margin-left: 60px;
261 | }
262 | .cont .drip:nth-child(3) {
263 | border-color: var(--color);
264 | height: 39px;
265 | width: 39px;
266 | animation-delay: -0.6s;
267 | background: var(--color);
268 | left: 15px;
269 | margin-left: 60px;
270 | }
271 | .cont .drip:nth-child(4) {
272 | border-color: var(--color);
273 | height: 33px;
274 | width: 33px;
275 | animation-delay: -0.8s;
276 | background: var(--color);
277 | left: 88px;
278 | margin-left: 60px;
279 | }
280 | .cont .drip:nth-child(5) {
281 | border-color: var(--color);
282 | height: 40px;
283 | width: 40px;
284 | animation-delay: -1s;
285 | background: var(--color);
286 | left: 133px;
287 | margin-left: 60px;
288 | }
289 | .cont .drip:nth-child(6) {
290 | border-color: var(--color);
291 | height: 39px;
292 | width: 39px;
293 | animation-delay: -1.2s;
294 | background: var(--color);
295 | left: 185px;
296 | margin-left: 60px;
297 | }
298 | .cont .drip:nth-child(7) {
299 | border-color: var(--color);
300 | height: 20px;
301 | width: 20px;
302 | animation-delay: -1.4s;
303 | background: var(--color);
304 | left: 38px;
305 | margin-left: 60px;
306 | }
307 | .cont .drip:nth-child(8) {
308 | border-color: var(--color);
309 | height: 2px;
310 | width: 2px;
311 | animation-delay: -1.6s;
312 | background: var(--color);
313 | left: 211px;
314 | margin-left: 60px;
315 | }
316 | .cont .drip:nth-child(9) {
317 | border-color: var(--color);
318 | height: 3px;
319 | width: 3px;
320 | animation-delay: -1.8s;
321 | background: var(--color);
322 | left: 174px;
323 | margin-left: 60px;
324 | }
325 | .cont .drip:nth-child(10) {
326 | border-color: var(--color);
327 | height: 17px;
328 | width: 17px;
329 | animation-delay: -2s;
330 | background: var(--color);
331 | left: 60px;
332 | margin-left: 60px;
333 | }
334 | .cont .drip:nth-child(11) {
335 | border-color: var(--color);
336 | height: 39px;
337 | width: 39px;
338 | animation-delay: -2.2s;
339 | background: var(--color);
340 | left: 206px;
341 | margin-left: 60px;
342 | }
343 | .cont .drip:nth-child(12) {
344 | border-color: var(--color);
345 | height: 14px;
346 | width: 14px;
347 | animation-delay: -2.4s;
348 | background: var(--color);
349 | left: 232px;
350 | margin-left: 60px;
351 | }
352 | .cont .drip:nth-child(13) {
353 | border-color: var(--color);
354 | height: 21px;
355 | width: 21px;
356 | animation-delay: -2.6s;
357 | background: var(--color);
358 | left: 175px;
359 | margin-left: 60px;
360 | }
361 | .cont .drip:nth-child(14) {
362 | border-color: var(--color);
363 | height: 15px;
364 | width: 15px;
365 | animation-delay: -2.8s;
366 | background: var(--color);
367 | left: 300px;
368 | margin-left: 60px;
369 | }
370 | .cont .drip:nth-child(15) {
371 | border-color: var(--color);
372 | height: 5px;
373 | width: 5px;
374 | animation-delay: -3s;
375 | background: var(--color);
376 | left: 178px;
377 | margin-left: 60px;
378 | }
379 | .cont .drip:nth-child(16) {
380 | border-color: var(--color);
381 | height: 30px;
382 | width: 30px;
383 | animation-delay: -3.2s;
384 | background: var(--color);
385 | left: 297px;
386 | margin-left: 60px;
387 | }
388 | .cont .drip:nth-child(17) {
389 | border-color: var(--color);
390 | height: 9px;
391 | width: 9px;
392 | animation-delay: -3.4s;
393 | background: var(--color);
394 | left: 223px;
395 | margin-left: 60px;
396 | }
397 | .cont .drip:nth-child(18) {
398 | border-color: var(--color);
399 | height: 28px;
400 | width: 28px;
401 | animation-delay: -3.6s;
402 | background: var(--color);
403 | left: 240px;
404 | margin-left: 60px;
405 | }
406 | .cont .drip:nth-child(19) {
407 | border-color: var(--color);
408 | height: 2px;
409 | width: 2px;
410 | animation-delay: -3.8s;
411 | background: var(--color);
412 | left: 9px;
413 | margin-left: 60px;
414 | }
415 | .cont .drip:nth-child(20) {
416 | border-color: var(--color);
417 | height: 27px;
418 | width: 27px;
419 | animation-delay: -4s;
420 | background: var(--color);
421 | left: 118px;
422 | margin-left: 60px;
423 | }
--------------------------------------------------------------------------------
/script.js:
--------------------------------------------------------------------------------
1 | // Testing animation concepts for boss battle
2 |
3 | const textBoxText = document.getElementById("textbox");
4 | const textBoxText2 = document.getElementById("textbox2");
5 |
6 | const split = new SplitText(textBoxText, {
7 | charsClass: "kb-char shake-constant",
8 | linesClass: "kb-line"
9 | });
10 |
11 | const chars = split.chars;
12 |
13 | const nextSplit = new SplitText(textBoxText2, {
14 | charsClass: "kb-char shake-constant",
15 | linesClass: "kb-line"
16 | });
17 |
18 | const chars2 = nextSplit.chars;
19 |
20 | const codeEditorDiv = document.createElement("div");
21 | codeEditorDiv.className = "code-editor";
22 |
23 | const codeEditorDiv2 = document.createElement("div");
24 | codeEditorDiv2.className = "code-editor reveal";
25 |
26 | // Insert it at the beginning of textBoxText
27 | textBoxText.prepend(codeEditorDiv);
28 | textBoxText2.prepend(codeEditorDiv2);
29 |
30 | chars.forEach((char, index) => {
31 | char.classList.add("shake-little");
32 |
33 | // Calculate a pseudo-random delay based on the index
34 | const delay = Math.random() * 0.2 + index * 0.05; // Adjust randomness and staggering here
35 |
36 | // Set the delay as an inline style
37 | char.style.animationDelay = `${delay}s`;
38 | });
39 |
40 | chars2.forEach((char, index) => {
41 | char.classList.add("shake-little");
42 |
43 | // Calculate a pseudo-random delay based on the index
44 | const delay = Math.random() * 0.2 + index * 0.05; // Adjust randomness and staggering here
45 |
46 | // Set the delay as an inline style
47 | char.style.animationDelay = `${delay}s`;
48 | });
49 |
50 | let currentLine;
51 |
52 | var tl = new TimelineMax({
53 | // onComplete: () => {
54 | // codeEditorDiv.classList.add("reveal");
55 | // }
56 | });
57 |
58 | tl.delay(3);
59 |
60 | tl.call(
61 | function () {
62 | textBoxText.classList.add("visible");
63 | },
64 | null,
65 | null,
66 | 0
67 | )
68 | .staggerFrom(
69 | chars,
70 | 0.8,
71 | {
72 | opacity: 0,
73 | ease: SteppedEase.config(1)
74 | },
75 | 0.08,
76 | "+=0"
77 | )
78 | .call(
79 | function () {
80 | textBoxText.classList.add("cont-dot");
81 | },
82 | null,
83 | "+=0",
84 | 0
85 | )
86 | .call(
87 | function () {
88 | codeEditorDiv.classList.add("reveal");
89 | },
90 | null,
91 | "+=2",
92 | 0
93 | )
94 | .call(
95 | function () {
96 | textBoxText.style.display = "none";
97 | textBoxText2.style.display = "flex";
98 | },
99 | null,
100 | "+=2",
101 | 0
102 | )
103 | .staggerFrom(
104 | chars2,
105 | 0.8,
106 | {
107 | opacity: 0,
108 | ease: SteppedEase.config(1)
109 | },
110 | 0.08,
111 | "+=0"
112 | )
113 | .call(
114 | function () {
115 | textBoxText2.classList.add("cont-dot");
116 | },
117 | null,
118 | "+=0",
119 | 0
120 | )
121 | // .call(
122 | // function () {
123 | // textBoxText2.innerHTML += LiquidHTML();
124 | // },
125 | // null,
126 | // "+=3",
127 | // 0
128 | // )
129 | // .call(
130 | // function () {
131 | // const textBox2Code = document
132 | // .getElementById("textbox2")
133 | // .querySelector(".code-editor");
134 | // textBox2Code.classList.remove("reveal");
135 | // textBox2Code.style.zIndex = "10";
136 | // },
137 | // null,
138 | // "+=0",
139 | // 0
140 | // )
141 | // .call(
142 | // function () {
143 | // const textBox2Code = document
144 | // .getElementById("textbox2")
145 | // .querySelector(".code-editor");
146 | // textBox2Code.classList.add("reveal");
147 | // },
148 | // null,
149 | // "+=3",
150 | // 0
151 | // )
152 | .pause();
153 |
154 | tl.play();
155 |
156 | ///////
157 |
158 | console.clear();
159 |
160 | var canvasLightning = function (c, cw, ch) {
161 | this.init = function () {
162 | this.loop();
163 | };
164 |
165 | var _this = this;
166 | this.c = c;
167 | this.ctx = c.getContext("2d");
168 | this.cw = cw;
169 | this.ch = ch;
170 | this.mx = 0;
171 | this.my = 0;
172 |
173 | this.now = Date.now();
174 | this.delta = 0;
175 | this.then = this.now;
176 |
177 | this.lightning = [];
178 | this.lightTimeCurrent = 0;
179 | this.lightTimeTotal = 50;
180 |
181 | this.rand = function (rMi, rMa) {
182 | return ~~(Math.random() * (rMa - rMi + 1) + rMi);
183 | };
184 |
185 | this.createL = function (x, y, canSpawn) {
186 | this.lightning.push({
187 | x: x,
188 | y: y,
189 | xRange: this.rand(5, 30),
190 | yRange: this.rand(5, 25),
191 | path: [
192 | {
193 | x: x,
194 | y: y
195 | }
196 | ],
197 | pathLimit: this.rand(10, 35),
198 | canSpawn: canSpawn,
199 | hasFired: false,
200 | grower: 0,
201 | growerLimit: 5 //this.rand(5, 15)
202 | });
203 | };
204 |
205 | this.updateL = function () {
206 | var i = this.lightning.length;
207 | while (i--) {
208 | var light = this.lightning[i];
209 |
210 | light.grower += this.delta;
211 |
212 | if (light.grower >= light.growerLimit) {
213 | light.grower = 0;
214 | light.growerLimit *= 1.05;
215 |
216 | light.path.push({
217 | x:
218 | light.path[light.path.length - 1].x +
219 | (this.rand(0, light.xRange) - light.xRange / 2),
220 | y: light.path[light.path.length - 1].y + this.rand(0, light.yRange)
221 | });
222 |
223 | if (light.path.length > light.pathLimit) {
224 | this.lightning.splice(i, 1);
225 | }
226 | light.hasFired = true;
227 | }
228 | }
229 | };
230 |
231 | this.renderL = function () {
232 | var i = this.lightning.length;
233 | while (i--) {
234 | var light = this.lightning[i];
235 |
236 | const randomColor = Math.random();
237 | this.ctx.strokeStyle =
238 | "hsla(0, 100%, 100%, " + this.rand(10, 100) / 100 + ")";
239 | if (randomColor >= 0.33 && randomColor < 0.8) {
240 | this.ctx.strokeStyle =
241 | "hsla(248, 53%, 58%, " + this.rand(10, 100) / 100 + ")";
242 | }
243 |
244 | if (randomColor >= 0.8) {
245 | this.ctx.strokeStyle =
246 | "hsla(204, 86%, 53%, " + this.rand(10, 100) / 100 + ")";
247 | }
248 |
249 | this.ctx.lineWidth = 4;
250 | if (this.rand(0, 30) == 0) {
251 | this.ctx.lineWidth = 5;
252 | }
253 | if (this.rand(0, 60) == 0) {
254 | this.ctx.lineWidth = 6;
255 | }
256 | if (this.rand(0, 90) == 0) {
257 | this.ctx.lineWidth = 7;
258 | }
259 |
260 | this.ctx.beginPath();
261 |
262 | var pathCount = light.path.length;
263 | this.ctx.moveTo(light.x, light.y);
264 | for (var pc = 0; pc < pathCount; pc++) {
265 | this.ctx.lineTo(light.path[pc].x, light.path[pc].y);
266 |
267 | if (light.canSpawn) {
268 | if (this.rand(0, 100) == 0) {
269 | light.canSpawn = false;
270 | this.createL(light.path[pc].x, light.path[pc].y, false);
271 | }
272 | }
273 | }
274 |
275 | if (!light.hasFired) {
276 | this.ctx.fillStyle =
277 | "rgba(255, 255, 255, " + this.rand(4, 12) / 100 + ")";
278 | this.ctx.fillRect(0, 0, this.cw, this.ch);
279 | }
280 |
281 | if (this.rand(0, 60) == 0) {
282 | this.ctx.fillStyle =
283 | "rgba(255, 255, 255, " + this.rand(1, 3) / 100 + ")";
284 | this.ctx.fillRect(0, 0, this.cw, this.ch);
285 | }
286 |
287 | this.ctx.stroke();
288 | }
289 | };
290 |
291 | this.lightningTimer = function () {
292 | this.lightTimeCurrent += this.delta;
293 | if (this.lightTimeCurrent >= this.lightTimeTotal) {
294 | var newX = this.rand(100, cw - 100);
295 | var newY = this.rand(0, ch / 2);
296 | var createCount = this.rand(1, 3);
297 | while (createCount--) {
298 | this.createL(newX, newY, true);
299 | }
300 | this.lightTimeCurrent = 0;
301 | this.lightTimeTotal = this.rand(200, 1500);
302 | }
303 | };
304 |
305 | this.clearCanvas = function () {
306 | this.ctx.globalCompositeOperation = "destination-out";
307 | this.ctx.fillStyle = "rgba(0,0,0," + this.rand(1, 30) / 100 + ")";
308 | this.ctx.fillRect(0, 0, this.cw, this.ch);
309 | this.ctx.globalCompositeOperation = "source-over";
310 | };
311 |
312 | window.addEventListener("resize", () => {
313 | this.cw = this.c.width = window.innerWidth;
314 | this.ch = this.c.height = window.innerHeight;
315 | });
316 |
317 | this.loop = function () {
318 | requestAnimationFrame(this.loop.bind(this));
319 |
320 | this.now = Date.now();
321 | this.delta = this.now - this.then;
322 | this.then = this.now;
323 |
324 | this.clearCanvas();
325 | this.updateL();
326 | this.lightningTimer();
327 | this.renderL();
328 | };
329 | };
330 |
331 | var c = document.getElementById("canvas");
332 | var cw = (c.width = window.innerWidth);
333 | var ch = (c.height = window.innerHeight);
334 | var cl = new canvasLightning(c, cw, ch);
335 |
336 | cl.init();
337 |
338 | function LiquidHTML() {
339 | return `
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 | `.trim();
373 | }
--------------------------------------------------------------------------------
/SplitText.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * SplitText 3.12.5
3 | * https://gsap.com
4 | *
5 | * @license Copyright 2024, GreenSock. All rights reserved.
6 | * This plugin is a membership benefit of Club GSAP and is only authorized for use in sites/apps/products developed by individuals/companies with an active Club GSAP membership. See https://gsap.com/pricing
7 | * @author: Jack Doyle, jack@greensock.com
8 | */
9 |
10 | !function(D,u){"object"==typeof exports&&"undefined"!=typeof module?u(exports):"function"==typeof define&&define.amd?define(["exports"],u):u((D=D||self).window=D.window||{})}(this,function(D){"use strict";var b=/([\uD800-\uDBFF][\uDC00-\uDFFF](?:[\u200D\uFE0F][\uD800-\uDBFF][\uDC00-\uDFFF]){2,}|\uD83D\uDC69(?:\u200D(?:(?:\uD83D\uDC69\u200D)?\uD83D\uDC67|(?:\uD83D\uDC69\u200D)?\uD83D\uDC66)|\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D(?:\uD83D\uDC69\u200D)?\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D(?:\uD83D\uDC69\u200D)?\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]\uFE0F|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC6F\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3C-\uDD3E\uDDD6-\uDDDF])\u200D[\u2640\u2642]\uFE0F|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F\u200D[\u2640\u2642]|(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642])\uFE0F|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2695\u2696\u2708]|\uD83D\uDC69\u200D[\u2695\u2696\u2708]|\uD83D\uDC68(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708]))\uFE0F|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83D\uDC69\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|\uD83D\uDC68(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC66\u200D\uD83D\uDC66|(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|(?:\uD83C[\uDFFB-\uDFFF])\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDD1-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\u200D(?:(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC67|(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC66)|\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC69\uDC6E\uDC70-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD18-\uDD1C\uDD1E\uDD1F\uDD26\uDD30-\uDD39\uDD3D\uDD3E\uDDD1-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])?|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDEEB\uDEEC\uDEF4-\uDEF8]|\uD83E[\uDD10-\uDD3A\uDD3C-\uDD3E\uDD40-\uDD45\uDD47-\uDD4C\uDD50-\uDD6B\uDD80-\uDD97\uDDC0\uDDD0-\uDDE6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267B\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEF8]|\uD83E[\uDD10-\uDD3A\uDD3C-\uDD3E\uDD40-\uDD45\uDD47-\uDD4C\uDD50-\uDD6B\uDD80-\uDD97\uDDC0\uDDD0-\uDDE6])\uFE0F)/;function n(D){X=document,e=window,(C=C||D||e.gsap||console.warn("Please gsap.registerPlugin(SplitText)"))&&(E=C.utils.toArray,i=C.core.context||function(){},F=1)}function o(D){return e.getComputedStyle(D)}function p(D){return"absolute"===D.position||!0===D.absolute}function q(D,u){for(var e,t=u.length;-1<--t;)if(e=u[t],D.substr(0,e.length)===e)return e.length}function s(D,u){void 0===D&&(D="");var e=~D.indexOf("++"),t=1;return e&&(D=D.split("++").join("")),function(){return"<"+u+" style='position:relative;display:inline-block;'"+(D?" class='"+D+(e?t++:"")+"'>":">")}}function t(D,u,e){var F=D.nodeType;if(1===F||9===F||11===F)for(D=D.firstChild;D;D=D.nextSibling)t(D,u,e);else 3!==F&&4!==F||(D.nodeValue=D.nodeValue.split(u).join(e))}function u(D,u){for(var e=u.length;-1<--e;)D.push(u[e])}function v(D,u,e){for(var t;D&&D!==u;){if(t=D._next||D.nextSibling)return t.textContent.charAt(0)===e;D=D.parentNode||D._parent}}function w(D){var u,e,t=E(D.childNodes),F=t.length;for(u=0;uW&&("BR"!==d.nodeName||0===E)&&(B=[],P.push(B),S=y),G&&(d._x=d.offsetLeft,d._y=y,d._w=d.offsetWidth,d._h=d.offsetHeight),P&&((d._isSplit&&h||!q&&h||z&&h||!z&&d.parentNode.parentNode===D&&!d.parentNode._isSplit)&&(B.push(d),d._x-=_,v(d,D,R)&&(d._wordEnd=!0)),"BR"===d.nodeName&&(d.nextSibling&&"BR"===d.nextSibling.nodeName||0===E)&&P.push([])));for(E=0;ED.clientHeight&&(D.style.height=s-N+"px",D.clientHeightD.clientWidth&&(D.style.width=n-L+"px",D.clientWidth",c=1,x=u.specialChars?"function"==typeof u.specialChars?u.specialChars:q:null,g=X.createElement("div"),y=D.parentNode;for(y.insertBefore(g,D),g.textContent=D.nodeValue,y.removeChild(D),l=-1!==(C=function getText(D){var u=D.nodeType,e="";if(1===u||9===u||11===u){if("string"==typeof D.textContent)return D.textContent;for(D=D.firstChild;D;D=D.nextSibling)e+=getText(D)}else if(3===u||4===u)return D.nodeValue;return e}(D=g)).indexOf("<"),!1!==u.reduceWhiteSpace&&(C=C.replace(S," ").replace(_,"")),l&&(C=C.split("<").join("{{LT}}")),E=C.length,i=(" "===C.charAt(0)?f:"")+e(),n=0;n":r,n+=o-1;else if(eb(r)&&!eb(C.charAt(n-1))&&n){for(i+=c?A:"",c=0;eb(C.charAt(n+1));)i+=f,n++;n===E-1?i+=f:")"!==C.charAt(n+1)&&(i+=f+e(),c=1)}else"{"===r&&"{{LT}}"===C.substr(n,6)?(i+=a?F()+"{{LT}}"+d+">":"{{LT}}",n+=5):55296<=r.charCodeAt(0)&&r.charCodeAt(0)<=56319||65024<=C.charCodeAt(n+1)&&C.charCodeAt(n+1)<=65039?(s=((C.substr(n,12).split(b)||[])[1]||"").length||2,i+=a&&" "!==r?F()+C.substr(n,s)+""+d+">":C.substr(n,s),n+=s-1):i+=a&&" "!==r?F()+r+""+d+">":r;D.outerHTML=i+(c?A:""),l&&t(y,"{{LT}}","<")}function A(D,u,e,t){var F,C,i=E(D.childNodes),n=i.length,s=p(u);if(3!==D.nodeType||1