@khesira/textflow 1.0.2 → 1.0.4
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/README.md +13 -12
- package/dist/src/Direction.d.ts +16 -0
- package/dist/src/TextElement.d.ts +6 -4
- package/dist/src/TextWriter.d.ts +1 -1
- package/dist/src/World.d.ts +3 -2
- package/dist/src/types.d.ts +6 -0
- package/dist/textflow.es.js +127 -78
- package/dist/textflow.umd.js +2 -2
- package/package.json +1 -1
- package/dist/src/directions.d.ts +0 -71
package/README.md
CHANGED
|
@@ -95,18 +95,19 @@ const settings: Settings = {
|
|
|
95
95
|
|
|
96
96
|
## Configuration (Settings)
|
|
97
97
|
|
|
98
|
-
| Property
|
|
99
|
-
|
|
100
|
-
| `width`
|
|
101
|
-
| `height`
|
|
102
|
-
| `font`
|
|
103
|
-
| `color`
|
|
104
|
-
| `background`
|
|
105
|
-
| `maxTexts`
|
|
106
|
-
| `maxAcceleration` | `number`
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
98
|
+
| Property | Type | Default Value | Description |
|
|
99
|
+
|:------------------|:-----------|:------------------|:-----------------------------------------------------------------------|
|
|
100
|
+
| `width` | `string` | `"100%"` | CSS width of the slider component (e.g., `"100%"`, `"400px"`). |
|
|
101
|
+
| `height` | `string` | `"150px"` | CSS height of the slider component. |
|
|
102
|
+
| `font` | `string` | `"sans-serif"` | Font family used inside the Canvas rendering context. |
|
|
103
|
+
| `color` | `string` | `"#ffffff"` | Text color (accepts hex, rgb, rgba, or CSS color names). |
|
|
104
|
+
| `background` | `string` | `"transparent"` | Background color of the canvas container. |
|
|
105
|
+
| `maxTexts` | `number` | `10` | Maximum number of text elements allowed on screen simultaneously. |
|
|
106
|
+
| `maxAcceleration` | `number` | `3` | Maximum velocity cap for the text particles. |
|
|
107
|
+
| `headings` | `string[]` | `['EAST','WEST']` | Flow directions of the texts picked randomly on each page load. |
|
|
108
|
+
| `marginTop` | `number` | `0` | Top boundary padding (in pixels) to restrict the spawn area. |
|
|
109
|
+
| `marginBottom` | `number` | `0` | Bottom boundary padding (in pixels) to restrict the spawn area. |
|
|
110
|
+
| `debug` | `boolean` | `false` | Enables red AABB bounding boxes and highlights the canvas clear zones. |
|
|
110
111
|
|
|
111
112
|
## Architecture
|
|
112
113
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type Heading = 'NORTH' | 'NORTHEAST' | 'EAST' | 'SOUTHEAST' | 'SOUTH' | 'SOUTHWEST' | 'WEST' | 'NORTHWEST' | 'NONE';
|
|
2
|
+
export declare const VECTOR_MAPPING: Record<Heading, {
|
|
3
|
+
readonly x: number;
|
|
4
|
+
readonly y: number;
|
|
5
|
+
}>;
|
|
6
|
+
export declare class Direction {
|
|
7
|
+
readonly heading: Heading;
|
|
8
|
+
private constructor();
|
|
9
|
+
static from(heading: Heading): Direction;
|
|
10
|
+
static randomDirection(availableDirections?: readonly Heading[]): Direction;
|
|
11
|
+
get x(): number;
|
|
12
|
+
get y(): number;
|
|
13
|
+
get isVertical(): boolean;
|
|
14
|
+
get isHorizontal(): boolean;
|
|
15
|
+
get isDiagonal(): boolean;
|
|
16
|
+
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { BoundingBox, Settings } from './types';
|
|
2
|
-
import { Direction } from './
|
|
2
|
+
import { Direction } from './Direction';
|
|
3
3
|
export declare class TextElement {
|
|
4
4
|
private _positionX;
|
|
5
5
|
private _positionY;
|
|
6
|
-
private readonly _maxAccelerationX;
|
|
7
6
|
private readonly _width;
|
|
8
7
|
private readonly _height;
|
|
9
8
|
private readonly _text;
|
|
@@ -19,7 +18,8 @@ export declare class TextElement {
|
|
|
19
18
|
private _boundingBox;
|
|
20
19
|
private readonly _font;
|
|
21
20
|
private readonly _color;
|
|
22
|
-
|
|
21
|
+
private readonly _maxAcceleration;
|
|
22
|
+
constructor(_positionX: number, _positionY: number, maxAcceleration: number, _width: number, _height: number, _text: string, _fontSize: number, _textDirection: Direction, _settings: Settings);
|
|
23
23
|
get width(): number;
|
|
24
24
|
get height(): number;
|
|
25
25
|
get positionX(): number;
|
|
@@ -29,11 +29,13 @@ export declare class TextElement {
|
|
|
29
29
|
get boundingBox(): BoundingBox;
|
|
30
30
|
set boundingBox(value: BoundingBox);
|
|
31
31
|
get accelerationX(): number;
|
|
32
|
+
get accelerationY(): number;
|
|
32
33
|
get fontSize(): number;
|
|
33
34
|
get font(): string;
|
|
34
35
|
get color(): string;
|
|
35
36
|
get text(): string;
|
|
36
|
-
|
|
37
|
+
isCollidingWithBorderX(direction: number, width: number): boolean;
|
|
38
|
+
isCollidingWithBorderY(direction: number, height: number): boolean;
|
|
37
39
|
private calculateBoundingBox;
|
|
38
40
|
private accelerate;
|
|
39
41
|
private breakDown;
|
package/dist/src/TextWriter.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Settings } from './types';
|
|
2
2
|
import { World } from './World';
|
|
3
3
|
import { TextFlowView } from './TextFlowView';
|
|
4
|
-
import { Direction } from './
|
|
4
|
+
import { Direction } from './Direction';
|
|
5
5
|
export declare class TextWriter {
|
|
6
6
|
private readonly _settings;
|
|
7
7
|
private readonly _textDirection;
|
package/dist/src/World.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Direction } from './
|
|
1
|
+
import { Direction } from './Direction';
|
|
2
2
|
import { TextElement } from './TextElement';
|
|
3
3
|
export declare class World {
|
|
4
4
|
private readonly _textDirection;
|
|
@@ -6,10 +6,11 @@ export declare class World {
|
|
|
6
6
|
private _isRunning;
|
|
7
7
|
private _elements;
|
|
8
8
|
private _width;
|
|
9
|
+
private _height;
|
|
9
10
|
constructor(_textDirection: Direction);
|
|
10
11
|
get elements(): TextElement[];
|
|
11
12
|
addElement(element: TextElement): void;
|
|
12
|
-
resize(width: number): void;
|
|
13
|
+
resize(width: number, height: number): void;
|
|
13
14
|
start(): void;
|
|
14
15
|
stop(): void;
|
|
15
16
|
private areObjectsColliding;
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { Heading } from './Direction.ts';
|
|
2
|
+
export declare enum CollisionAxis {
|
|
3
|
+
Horizontal = 0,
|
|
4
|
+
Vertical = 1
|
|
5
|
+
}
|
|
1
6
|
export interface BoundingBox {
|
|
2
7
|
top: number;
|
|
3
8
|
right: number;
|
|
@@ -9,6 +14,7 @@ export interface Settings {
|
|
|
9
14
|
height: string;
|
|
10
15
|
maxTexts: number;
|
|
11
16
|
maxAcceleration: number;
|
|
17
|
+
headings: Heading[];
|
|
12
18
|
marginTop: number;
|
|
13
19
|
marginBottom: number;
|
|
14
20
|
texts: string[];
|
package/dist/textflow.es.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
//#region src/
|
|
2
|
-
var e =
|
|
1
|
+
//#region src/types.ts
|
|
2
|
+
var e = /* @__PURE__ */ function(e) {
|
|
3
|
+
return e[e.Horizontal = 0] = "Horizontal", e[e.Vertical = 1] = "Vertical", e;
|
|
4
|
+
}({}), t = class {
|
|
3
5
|
_textDirection;
|
|
4
6
|
updateId = void 0;
|
|
5
7
|
_isRunning = !1;
|
|
6
8
|
_elements = [];
|
|
7
9
|
_width = 0;
|
|
10
|
+
_height = 0;
|
|
8
11
|
constructor(e) {
|
|
9
12
|
this._textDirection = e;
|
|
10
13
|
}
|
|
@@ -14,8 +17,8 @@ var e = class {
|
|
|
14
17
|
addElement(e) {
|
|
15
18
|
this._elements.push(e);
|
|
16
19
|
}
|
|
17
|
-
resize(e) {
|
|
18
|
-
this._width = e;
|
|
20
|
+
resize(e, t) {
|
|
21
|
+
this._width = e, this._height = t;
|
|
19
22
|
}
|
|
20
23
|
start() {
|
|
21
24
|
this._isRunning || (this._isRunning = !0, this.updateWorld());
|
|
@@ -27,22 +30,29 @@ var e = class {
|
|
|
27
30
|
let n = e.boundingBox.left > t.boundingBox.right || t.boundingBox.left > e.boundingBox.right, r = e.boundingBox.top > t.boundingBox.bottom || t.boundingBox.top > e.boundingBox.bottom;
|
|
28
31
|
return !(n || r);
|
|
29
32
|
}
|
|
30
|
-
getCollisionAxis(
|
|
31
|
-
let
|
|
32
|
-
e.positionX,
|
|
33
|
-
e.positionX + e.width,
|
|
33
|
+
getCollisionAxis(t, n) {
|
|
34
|
+
let r = [
|
|
34
35
|
t.positionX,
|
|
35
|
-
t.positionX + t.width
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
t.positionX + t.width,
|
|
37
|
+
n.positionX,
|
|
38
|
+
n.positionX + n.width
|
|
39
|
+
], i = [
|
|
39
40
|
t.positionY,
|
|
40
|
-
t.positionY + t.height
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
t.positionY + t.height,
|
|
42
|
+
n.positionY,
|
|
43
|
+
n.positionY + n.height
|
|
44
|
+
], a = (e, t) => e - t;
|
|
45
|
+
return r.sort(a), i.sort(a), r[2] - r[1] < i[2] - i[1] ? e.Horizontal : e.Vertical;
|
|
46
|
+
}
|
|
47
|
+
handleCollision(t, n) {
|
|
48
|
+
switch (this.getCollisionAxis(t, n)) {
|
|
49
|
+
case e.Horizontal:
|
|
50
|
+
this.handleXCollision(t, n);
|
|
51
|
+
break;
|
|
52
|
+
case e.Vertical:
|
|
53
|
+
this.handleYCollision(t, n);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
46
56
|
}
|
|
47
57
|
handleXCollision(e, t) {
|
|
48
58
|
if (this._textDirection.x === 0) return;
|
|
@@ -66,13 +76,15 @@ var e = class {
|
|
|
66
76
|
updateElements() {
|
|
67
77
|
for (let e = this._elements.length - 1; e >= 0; e--) {
|
|
68
78
|
let t = this._elements[e];
|
|
69
|
-
t.move()
|
|
79
|
+
t.move();
|
|
80
|
+
let n = !1;
|
|
81
|
+
this._textDirection.x !== 0 && (n = t.isCollidingWithBorderX(this._textDirection.x, this._width)), !n && this._textDirection.y !== 0 && (n = t.isCollidingWithBorderY(this._textDirection.y, this._height)), n && this._elements.splice(e, 1);
|
|
70
82
|
}
|
|
71
83
|
}
|
|
72
84
|
updateWorld() {
|
|
73
85
|
this._isRunning && (this.detectCollisions(), this.updateElements(), this.updateId = window.setTimeout(() => this.updateWorld(), 1e3 / 60));
|
|
74
86
|
}
|
|
75
|
-
},
|
|
87
|
+
}, n = class {
|
|
76
88
|
_settings;
|
|
77
89
|
_target;
|
|
78
90
|
_canvas;
|
|
@@ -110,10 +122,9 @@ var e = class {
|
|
|
110
122
|
this._renderId = requestAnimationFrame(this.renderView);
|
|
111
123
|
}
|
|
112
124
|
};
|
|
113
|
-
},
|
|
125
|
+
}, r = class {
|
|
114
126
|
_positionX;
|
|
115
127
|
_positionY;
|
|
116
|
-
_maxAccelerationX;
|
|
117
128
|
_width;
|
|
118
129
|
_height;
|
|
119
130
|
_text;
|
|
@@ -129,8 +140,9 @@ var e = class {
|
|
|
129
140
|
_boundingBox;
|
|
130
141
|
_font;
|
|
131
142
|
_color;
|
|
143
|
+
_maxAcceleration;
|
|
132
144
|
constructor(e, t, n, r, i, a, o, s, c) {
|
|
133
|
-
this._positionX = e, this._positionY = t, this.
|
|
145
|
+
this._positionX = e, this._positionY = t, this._width = r, this._height = i, this._text = a, this._fontSize = o, this._textDirection = s, this._maxAcceleration = n, this._acceleration = 1 / this._fontSize, this._boundingBox = this.calculateBoundingBox(), this._font = `${o}pt ${c.font}`, this._color = c.color;
|
|
134
146
|
}
|
|
135
147
|
get width() {
|
|
136
148
|
return this._width;
|
|
@@ -159,6 +171,9 @@ var e = class {
|
|
|
159
171
|
get accelerationX() {
|
|
160
172
|
return this._accelerationX;
|
|
161
173
|
}
|
|
174
|
+
get accelerationY() {
|
|
175
|
+
return this._accelerationY;
|
|
176
|
+
}
|
|
162
177
|
get fontSize() {
|
|
163
178
|
return this._fontSize;
|
|
164
179
|
}
|
|
@@ -171,12 +186,18 @@ var e = class {
|
|
|
171
186
|
get text() {
|
|
172
187
|
return this._text;
|
|
173
188
|
}
|
|
174
|
-
|
|
189
|
+
isCollidingWithBorderX(e, t) {
|
|
175
190
|
if (e < 0) {
|
|
176
191
|
if (this._boundingBox.right < 0) return !0;
|
|
177
192
|
} else if (this._boundingBox.left > t) return !0;
|
|
178
193
|
return !1;
|
|
179
194
|
}
|
|
195
|
+
isCollidingWithBorderY(e, t) {
|
|
196
|
+
if (e < 0) {
|
|
197
|
+
if (this._boundingBox.bottom < 0) return !0;
|
|
198
|
+
} else if (this._boundingBox.top > t) return !0;
|
|
199
|
+
return !1;
|
|
200
|
+
}
|
|
180
201
|
calculateBoundingBox() {
|
|
181
202
|
return {
|
|
182
203
|
top: this._positionY - this._height,
|
|
@@ -186,16 +207,16 @@ var e = class {
|
|
|
186
207
|
};
|
|
187
208
|
}
|
|
188
209
|
accelerate() {
|
|
189
|
-
this._accelerationX += this._acceleration * this._textDirection.x, Math.
|
|
210
|
+
this._accelerationX += this._acceleration * this._textDirection.x, this._accelerationY += this._acceleration * this._textDirection.y, Math.sqrt(this._accelerationX ** 2 + this._accelerationY ** 2) < this._maxAcceleration ? this._accelerateId = window.setTimeout(() => this.accelerate(), 40) : (this._accelerationX = this._maxAcceleration * this._textDirection.x, this._accelerationY = this._maxAcceleration * this._textDirection.y, this._accelerateId = void 0);
|
|
190
211
|
}
|
|
191
212
|
breakDown() {
|
|
192
|
-
this._accelerationX += .1 * this._textDirection.x, Math.
|
|
213
|
+
this._accelerationX += .1 * this._textDirection.x, this._accelerationY += .1 * this._textDirection.y, Math.sqrt(this._accelerationX ** 2 + this._accelerationY ** 2) > this._maxAcceleration ? this._breakDownId = window.setTimeout(() => this.breakDown(), 40) : (this._accelerationX = this._maxAcceleration * this._textDirection.x, this._accelerationY = this._maxAcceleration * this._textDirection.y, this._breakDownId = void 0, this._accelerateId = void 0);
|
|
193
214
|
}
|
|
194
215
|
boostUpByCollision = (e) => {
|
|
195
|
-
this._accelerationX += (e.accelerationX - this._accelerationX) * (e.fontSize / this._fontSize), clearTimeout(this._accelerateId), clearTimeout(this._breakDownId), this.breakDown();
|
|
216
|
+
this._textDirection.x !== 0 && (this._accelerationX += (e.accelerationX - this._accelerationX) * (e.fontSize / this._fontSize)), this._textDirection.y !== 0 && (this._accelerationY += (e.accelerationY - this._accelerationY) * (e.fontSize / this._fontSize)), clearTimeout(this._accelerateId), clearTimeout(this._breakDownId), this.breakDown();
|
|
196
217
|
};
|
|
197
218
|
breakDownByCollision = (e) => {
|
|
198
|
-
this._accelerationX -= this._accelerationX * (e.fontSize / this._fontSize), clearTimeout(this._accelerateId), clearTimeout(this._breakDownId), this.accelerate();
|
|
219
|
+
this._textDirection.x !== 0 && (this._accelerationX -= this._accelerationX * (e.fontSize / this._fontSize)), this._textDirection.y !== 0 && (this._accelerationY -= this._accelerationY * (e.fontSize / this._fontSize)), clearTimeout(this._accelerateId), clearTimeout(this._breakDownId), this.accelerate();
|
|
199
220
|
};
|
|
200
221
|
start() {
|
|
201
222
|
this.accelerate();
|
|
@@ -203,7 +224,7 @@ var e = class {
|
|
|
203
224
|
move() {
|
|
204
225
|
this._velocityX = this._accelerationX, this._velocityY = this._accelerationY, this._positionX += this._velocityX, this._positionY += this._velocityY, this._boundingBox = this.calculateBoundingBox();
|
|
205
226
|
}
|
|
206
|
-
},
|
|
227
|
+
}, i = class {
|
|
207
228
|
_settings;
|
|
208
229
|
_textDirection;
|
|
209
230
|
_width;
|
|
@@ -227,10 +248,12 @@ var e = class {
|
|
|
227
248
|
this._textId = this.randomSetTimeout(() => this.addText(), 1e3, 2500);
|
|
228
249
|
return;
|
|
229
250
|
}
|
|
230
|
-
let e = this.random(this._minFontSize, this._maxFontSize), t = this._texts[this.random(this._texts.length)]
|
|
251
|
+
let e = this.random(this._minFontSize, this._maxFontSize), t = this._texts[this.random(this._texts.length)];
|
|
231
252
|
this._view.setFontSize(e);
|
|
232
|
-
let
|
|
233
|
-
this.
|
|
253
|
+
let n = this._view.measureText(t), i = this.random(1, this._settings.maxAcceleration + 1), a, o, s = this._textDirection.x, c = this._textDirection.y;
|
|
254
|
+
a = s > 0 ? -n : s < 0 ? this._width : this.random(0, this._width - n), o = c > 0 ? -e + this._marginTop : c < 0 ? this._height - this._marginBottom : this.random(this._marginTop, this._height - this._marginBottom - e), this._textDirection.isDiagonal && (Math.random() > .5 ? o = this.random(this._marginTop, this._height - this._marginBottom - e) : a = this.random(0, this._width - n));
|
|
255
|
+
let l = new r(a, o, i, n, e, t, e, this._textDirection, this._settings);
|
|
256
|
+
this._world.addElement(l), l.start(), this._textId = this.randomSetTimeout(() => this.addText(), 1e3, 2500);
|
|
234
257
|
}
|
|
235
258
|
resize(e, t) {
|
|
236
259
|
this._width = e, this._height = t, this.updateFontSizes();
|
|
@@ -250,71 +273,97 @@ var e = class {
|
|
|
250
273
|
randomSetTimeout(e, t, n) {
|
|
251
274
|
return window.setTimeout(() => e(), this.random(t, n));
|
|
252
275
|
}
|
|
253
|
-
},
|
|
254
|
-
|
|
255
|
-
height: "200px",
|
|
256
|
-
maxTexts: 15,
|
|
257
|
-
maxAcceleration: 15,
|
|
258
|
-
marginTop: 0,
|
|
259
|
-
marginBottom: 0,
|
|
260
|
-
texts: [
|
|
261
|
-
"Add",
|
|
262
|
-
"your",
|
|
263
|
-
"own",
|
|
264
|
-
"texts",
|
|
265
|
-
"here"
|
|
266
|
-
],
|
|
267
|
-
color: "#333",
|
|
268
|
-
background: "rgba(255, 255, 255, 1)",
|
|
269
|
-
font: "sans-serif",
|
|
270
|
-
debug: !1
|
|
271
|
-
};
|
|
272
|
-
function a(e) {
|
|
273
|
-
let t = { ...i };
|
|
274
|
-
return typeof e.maxTexts == "number" && e.maxTexts > 0 ? t.maxTexts = Math.floor(e.maxTexts) : e.maxTexts !== void 0 && console.warn(`[textflow] Invalid maxTexts "${e.maxTexts}". Using default: ${i.maxTexts}`), typeof e.maxAcceleration == "number" && e.maxAcceleration > 0 && (t.maxAcceleration = e.maxAcceleration), typeof e.marginTop == "number" && e.marginTop >= 0 && (t.marginTop = e.marginTop), typeof e.marginBottom == "number" && e.marginBottom >= 0 && (t.marginBottom = e.marginBottom), typeof e.font == "string" && e.font.trim() !== "" && (t.font = e.font), typeof e.color == "string" && e.color.trim() !== "" && (t.color = e.color), typeof e.background == "string" && e.background.trim() !== "" && (t.background = e.background), e.debug !== void 0 && (t.debug = !!e.debug), t;
|
|
275
|
-
}
|
|
276
|
-
//#endregion
|
|
277
|
-
//#region src/directions.ts
|
|
278
|
-
var o = {
|
|
279
|
-
none: {
|
|
280
|
-
x: 0,
|
|
281
|
-
y: 0
|
|
282
|
-
},
|
|
283
|
-
north: {
|
|
276
|
+
}, a = {
|
|
277
|
+
NORTH: {
|
|
284
278
|
x: 0,
|
|
285
279
|
y: -1
|
|
286
280
|
},
|
|
287
|
-
|
|
281
|
+
NORTHEAST: {
|
|
288
282
|
x: 1,
|
|
289
283
|
y: -1
|
|
290
284
|
},
|
|
291
|
-
|
|
285
|
+
EAST: {
|
|
292
286
|
x: 1,
|
|
293
287
|
y: 0
|
|
294
288
|
},
|
|
295
|
-
|
|
289
|
+
SOUTHEAST: {
|
|
296
290
|
x: 1,
|
|
297
291
|
y: 1
|
|
298
292
|
},
|
|
299
|
-
|
|
293
|
+
SOUTH: {
|
|
300
294
|
x: 0,
|
|
301
295
|
y: 1
|
|
302
296
|
},
|
|
303
|
-
|
|
297
|
+
SOUTHWEST: {
|
|
304
298
|
x: -1,
|
|
305
299
|
y: 1
|
|
306
300
|
},
|
|
307
|
-
|
|
301
|
+
WEST: {
|
|
308
302
|
x: -1,
|
|
309
303
|
y: 0
|
|
310
304
|
},
|
|
311
|
-
|
|
305
|
+
NORTHWEST: {
|
|
312
306
|
x: -1,
|
|
313
307
|
y: -1
|
|
308
|
+
},
|
|
309
|
+
NONE: {
|
|
310
|
+
x: 0,
|
|
311
|
+
y: 0
|
|
312
|
+
}
|
|
313
|
+
}, o = class e {
|
|
314
|
+
heading;
|
|
315
|
+
constructor(e) {
|
|
316
|
+
this.heading = e;
|
|
317
|
+
}
|
|
318
|
+
static from(t) {
|
|
319
|
+
return new e(t);
|
|
320
|
+
}
|
|
321
|
+
static randomDirection(t = ["EAST", "WEST"]) {
|
|
322
|
+
let n = t[Math.floor(Math.random() * t.length)];
|
|
323
|
+
return e.from(n);
|
|
324
|
+
}
|
|
325
|
+
get x() {
|
|
326
|
+
return a[this.heading].x;
|
|
327
|
+
}
|
|
328
|
+
get y() {
|
|
329
|
+
return a[this.heading].y;
|
|
330
|
+
}
|
|
331
|
+
get isVertical() {
|
|
332
|
+
return this.x === 0 && this.y !== 0;
|
|
333
|
+
}
|
|
334
|
+
get isHorizontal() {
|
|
335
|
+
return this.y === 0 && this.x !== 0;
|
|
336
|
+
}
|
|
337
|
+
get isDiagonal() {
|
|
338
|
+
return this.x !== 0 && this.y !== 0;
|
|
339
|
+
}
|
|
340
|
+
}, s = {
|
|
341
|
+
width: "100%",
|
|
342
|
+
height: "200px",
|
|
343
|
+
maxTexts: 15,
|
|
344
|
+
maxAcceleration: 15,
|
|
345
|
+
headings: ["EAST", "WEST"],
|
|
346
|
+
marginTop: 0,
|
|
347
|
+
marginBottom: 0,
|
|
348
|
+
texts: [
|
|
349
|
+
"Add",
|
|
350
|
+
"your",
|
|
351
|
+
"own",
|
|
352
|
+
"texts",
|
|
353
|
+
"here"
|
|
354
|
+
],
|
|
355
|
+
color: "#333",
|
|
356
|
+
background: "rgba(255, 255, 255, 1)",
|
|
357
|
+
font: "sans-serif",
|
|
358
|
+
debug: !1
|
|
359
|
+
};
|
|
360
|
+
function c(e) {
|
|
361
|
+
let t = { ...s };
|
|
362
|
+
if (typeof e.maxTexts == "number" && e.maxTexts > 0 ? t.maxTexts = Math.floor(e.maxTexts) : e.maxTexts !== void 0 && console.warn(`[textflow] Invalid maxTexts "${e.maxTexts}". Using default: ${s.maxTexts}`), typeof e.maxAcceleration == "number" && e.maxAcceleration > 0 && (t.maxAcceleration = e.maxAcceleration), Array.isArray(e.headings)) {
|
|
363
|
+
let n = e.headings.filter((e) => typeof e == "string" && e.toUpperCase() in a);
|
|
364
|
+
n.length > 0 && (t.headings = n);
|
|
314
365
|
}
|
|
315
|
-
|
|
316
|
-
function c(e = s) {
|
|
317
|
-
return e[Math.floor(Math.random() * e.length)];
|
|
366
|
+
return typeof e.marginTop == "number" && e.marginTop >= 0 && (t.marginTop = e.marginTop), typeof e.marginBottom == "number" && e.marginBottom >= 0 && (t.marginBottom = e.marginBottom), typeof e.font == "string" && e.font.trim() !== "" && (t.font = e.font), typeof e.color == "string" && e.color.trim() !== "" && (t.color = e.color), typeof e.background == "string" && e.background.trim() !== "" && (t.background = e.background), e.debug !== void 0 && (t.debug = !!e.debug), t;
|
|
318
367
|
}
|
|
319
368
|
//#endregion
|
|
320
369
|
//#region src/index.ts
|
|
@@ -327,13 +376,13 @@ var l = class extends HTMLElement {
|
|
|
327
376
|
animationFrameId = null;
|
|
328
377
|
connectedCallback() {
|
|
329
378
|
this.innerHTML = "\n <div class=\"slider-container\">\n <canvas class=\"physics-canvas\"></canvas>\n </div>\n ";
|
|
330
|
-
let
|
|
331
|
-
if (!
|
|
379
|
+
let e = this.querySelector(".physics-canvas"), r = e.getContext("2d");
|
|
380
|
+
if (!r) {
|
|
332
381
|
console.error("Could not get context2d");
|
|
333
382
|
return;
|
|
334
383
|
}
|
|
335
|
-
let
|
|
336
|
-
this.world = new
|
|
384
|
+
let a = this.dataset.settings, l = c(a ? JSON.parse(a) : s), u = this.dataset.texts, d = u ? JSON.parse(u) : l.texts, f = o.randomDirection(l.headings);
|
|
385
|
+
this.world = new t(f), this.view = new n(l, this, e, r, this.world), this.textWriter = new i(l, f, this.offsetWidth, this.offsetHeight, this.world, this.view, d), this.startLoop(), document.addEventListener("visibilitychange", this.visibilityChange), this.resizeObserver = new ResizeObserver(() => {
|
|
337
386
|
this.resize();
|
|
338
387
|
}), this.resizeObserver.observe(this);
|
|
339
388
|
}
|
|
@@ -350,7 +399,7 @@ var l = class extends HTMLElement {
|
|
|
350
399
|
this.active && (this.view.stop(), this.world.stop(), this.textWriter.stop(), this.active = !1, this.animationFrameId &&= (window.cancelAnimationFrame(this.animationFrameId), null));
|
|
351
400
|
}
|
|
352
401
|
resize() {
|
|
353
|
-
this.view.resize(), this.world.resize(this.offsetWidth), this.textWriter.resize(this.offsetWidth, this.offsetHeight);
|
|
402
|
+
this.view.resize(), this.world.resize(this.offsetWidth, this.offsetHeight), this.textWriter.resize(this.offsetWidth, this.offsetHeight);
|
|
354
403
|
}
|
|
355
404
|
visibilityChange = () => {
|
|
356
405
|
document.hidden ? this.stopLoop() : this.startLoop();
|
package/dist/textflow.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.TextFlow={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=class{_textDirection;updateId=void 0;_isRunning=!1;_elements=[];_width=0;constructor(e){this._textDirection=e}get elements(){return this._elements}addElement(e){this._elements.push(e)}resize(e){this._width=e}start(){this._isRunning||(this._isRunning=!0,this.updateWorld())}stop(){this._isRunning=!1,this.updateId!==void 0&&(window.clearTimeout(this.updateId),this.updateId=void 0)}areObjectsColliding(e,t){let n=e.boundingBox.left>t.boundingBox.right||t.boundingBox.left>e.boundingBox.right,r=e.boundingBox.top>t.boundingBox.bottom||t.boundingBox.top>e.boundingBox.bottom;return!(n||r)}getCollisionAxis(e,t){let n=[e.positionX,e.positionX+e.width,t.positionX,t.positionX+t.width],r=[e.positionY,e.positionY+e.height,t.positionY,t.positionY+t.height],i=(e,t)=>e-t;return n.sort(i),r.sort(i),n[2]-n[1]<r[2]-r[1]?`x`:`y`}handleCollision(e,t){this.getCollisionAxis(e,t)===`x`?this.handleXCollision(e,t):this.handleYCollision(e,t)}handleXCollision(e,t){if(this._textDirection.x===0)return;let n=e.boundingBox.left<t.boundingBox.left,r=n?e:t,i=n?t:e;this._textDirection.x<0?(r.boostUpByCollision(i),i.breakDownByCollision(r)):(i.boostUpByCollision(r),r.breakDownByCollision(i))}handleYCollision(e,t){if(this._textDirection.y===0)return;let n=e.boundingBox.top<t.boundingBox.top,r=n?e:t,i=n?t:e;this._textDirection.y<0?(r.boostUpByCollision(i),i.breakDownByCollision(r)):(i.boostUpByCollision(r),r.breakDownByCollision(i))}detectCollisions(){for(let e=0;e<this._elements.length;e++){let t=this._elements[e];for(let n=e+1;n<this._elements.length;n++){let e=this._elements[n];this.areObjectsColliding(t,e)&&this.handleCollision(t,e)}}}updateElements(){for(let e=this._elements.length-1;e>=0;e--){let t=this._elements[e];t.move(),t.isCollidingWithBorder(this._textDirection.x,this._width)&&this._elements.splice(e,1)}}updateWorld(){this._isRunning&&(this.detectCollisions(),this.updateElements(),this.updateId=window.setTimeout(()=>this.updateWorld(),1e3/60))}},n=class{_settings;_target;_canvas;_context2d;_world;_renderId=0;constructor(e,t,n,r,i){this._settings=e,this._target=t,this._canvas=n,this._context2d=r,this._world=i,this._target.style.display=`block`,this._target.style.width=this._settings.width,this._target.style.height=this._settings.height,this._target.style.background=this._settings.background}setFontSize(e){this._context2d.font=`${e}pt ${this._settings.font}`}measureText(e){return this._context2d.measureText(e).width}resize(){let e=typeof window<`u`&&window.devicePixelRatio||1;this._canvas.width=this._target.clientWidth*e,this._canvas.height=this._target.clientHeight*e,this._canvas.style.width=`${this._target.clientWidth}px`,this._canvas.style.height=`${this._target.clientHeight}px`,this._context2d.scale(e,e)}clear(){if(!this._context2d)return;let e=this._context2d.fillStyle;this._context2d.fillStyle=this._settings.debug?`rgba(255, 255, 0, 1)`:this._settings.background,this._context2d.fillRect(0,0,this._target.clientWidth,this._target.clientHeight),this._context2d.fillStyle=e}start(){this._context2d&&(this._context2d.textAlign=`start`,this._renderId===0&&this.renderView())}stop(){this._renderId!==0&&(cancelAnimationFrame(this._renderId),this._renderId=0),this.clear()}renderView=()=>{if(this._context2d){this.clear();for(let e of this._world.elements)this._context2d.font=e.font,this._settings.debug&&(this._context2d.fillStyle=`#ff0000`,this._context2d.fillRect(e.positionX,e.positionY-e.height,e.width,e.height)),this._context2d.fillStyle=e.color,this._context2d.fillText(e.text,e.positionX,e.positionY);this._renderId=requestAnimationFrame(this.renderView)}}},r=class{_positionX;_positionY;_maxAccelerationX;_width;_height;_text;_fontSize;_textDirection;_accelerateId=void 0;_breakDownId=void 0;_accelerationX=0;_accelerationY=0;_velocityX=0;_velocityY=0;_acceleration=0;_boundingBox;_font;_color;constructor(e,t,n,r,i,a,o,s,c){this._positionX=e,this._positionY=t,this._maxAccelerationX=n,this._width=r,this._height=i,this._text=a,this._fontSize=o,this._textDirection=s,this._acceleration=1/this._fontSize,this._boundingBox=this.calculateBoundingBox(),this._font=`${o}pt ${c.font}`,this._color=c.color}get width(){return this._width}get height(){return this._height}get positionX(){return this._positionX}set positionX(e){this._positionX=e}get positionY(){return this._positionY}set positionY(e){this._positionY=e}get boundingBox(){return this._boundingBox}set boundingBox(e){this._boundingBox=e}get accelerationX(){return this._accelerationX}get fontSize(){return this._fontSize}get font(){return this._font}get color(){return this._color}get text(){return this._text}isCollidingWithBorder(e,t){if(e<0){if(this._boundingBox.right<0)return!0}else if(this._boundingBox.left>t)return!0;return!1}calculateBoundingBox(){return{top:this._positionY-this._height,right:this._positionX+this._width,bottom:this._positionY,left:this._positionX}}accelerate(){this._accelerationX+=this._acceleration*this._textDirection.x,Math.abs(this._accelerationX)<Math.abs(this._maxAccelerationX)?this._accelerateId=window.setTimeout(()=>this.accelerate(),40):(this._accelerationX=this._maxAccelerationX,this._accelerateId=void 0)}breakDown(){this._accelerationX+=.1*this._textDirection.x,Math.abs(this._accelerationX)>Math.abs(this._maxAccelerationX)?this._breakDownId=window.setTimeout(()=>this.breakDown(),40):(this._accelerationX=this._maxAccelerationX,this._breakDownId=void 0,this._accelerateId=void 0)}boostUpByCollision=e=>{this._accelerationX+=(e.accelerationX-this._accelerationX)*(e.fontSize/this._fontSize),clearTimeout(this._accelerateId),clearTimeout(this._breakDownId),this.breakDown()};breakDownByCollision=e=>{this._accelerationX-=this._accelerationX*(e.fontSize/this._fontSize),clearTimeout(this._accelerateId),clearTimeout(this._breakDownId),this.accelerate()};start(){this.accelerate()}move(){this._velocityX=this._accelerationX,this._velocityY=this._accelerationY,this._positionX+=this._velocityX,this._positionY+=this._velocityY,this._boundingBox=this.calculateBoundingBox()}},i=class{_settings;_textDirection;_width;_height;_world;_view;_texts;_textId=void 0;_isRunning=!1;_minFontSize=16;_maxFontSize=20;_marginTop;_marginBottom;_maxTexts;constructor(e,t,n,r,i,a,o){this._settings=e,this._textDirection=t,this._width=n,this._height=r,this._world=i,this._view=a,this._texts=o,this._marginTop=this._settings.marginTop,this._marginBottom=this._settings.marginBottom,this._maxTexts=this._settings.maxTexts,this.updateFontSizes()}addText(){if(!this._isRunning)return;if(this._world.elements.length>=this._maxTexts){this._textId=this.randomSetTimeout(()=>this.addText(),1e3,2500);return}let e=this.random(this._minFontSize,this._maxFontSize),t=this._texts[this.random(this._texts.length)],n=this.random(1,this._settings.maxAcceleration+1)*this._textDirection.x;this._view.setFontSize(e);let i=this._view.measureText(t),a=new r(this._textDirection.x<0?this._width:-i,this.random(this._marginTop,this._height-this._marginBottom-this._marginTop),n,i,e,t,e,this._textDirection,this._settings);this._world.addElement(a),a.start(),this._textId=this.randomSetTimeout(()=>this.addText(),1e3,2500)}resize(e,t){this._width=e,this._height=t,this.updateFontSizes()}start(){this._isRunning||(this._isRunning=!0,this.addText())}stop(){this._isRunning=!1,this._textId!==void 0&&(window.clearTimeout(this._textId),this._textId=void 0)}updateFontSizes(){typeof window<`u`&&(this._minFontSize=window.innerWidth<=800?12:16,this._maxFontSize=window.innerWidth<=800?16:20)}random(e,t){return t===void 0?Math.floor(Math.random()*e):e+Math.floor(Math.random()*(t-e+1))}randomSetTimeout(e,t,n){return window.setTimeout(()=>e(),this.random(t,n))}},a={width:`100%`,height:`200px`,maxTexts:15,maxAcceleration:15,marginTop:0,marginBottom:0,texts:[`Add`,`your`,`own`,`texts`,`here`],color:`#333`,background:`rgba(255, 255, 255, 1)`,font:`sans-serif`,debug:!1};function o(e){let t={...a};return typeof e.maxTexts==`number`&&e.maxTexts>0?t.maxTexts=Math.floor(e.maxTexts):e.maxTexts!==void 0&&console.warn(`[textflow] Invalid maxTexts "${e.maxTexts}". Using default: ${a.maxTexts}`),typeof e.maxAcceleration==`number`&&e.maxAcceleration>0&&(t.maxAcceleration=e.maxAcceleration),typeof e.marginTop==`number`&&e.marginTop>=0&&(t.marginTop=e.marginTop),typeof e.marginBottom==`number`&&e.marginBottom>=0&&(t.marginBottom=e.marginBottom),typeof e.font==`string`&&e.font.trim()!==``&&(t.font=e.font),typeof e.color==`string`&&e.color.trim()!==``&&(t.color=e.color),typeof e.background==`string`&&e.background.trim()!==``&&(t.background=e.background),e.debug!==void 0&&(t.debug=!!e.debug),t}var s={none:{x:0,y:0},north:{x:0,y:-1},northEast:{x:1,y:-1},east:{x:1,y:0},southEast:{x:1,y:1},south:{x:0,y:1},southWest:{x:-1,y:1},west:{x:-1,y:0},northWest:{x:-1,y:-1}},c=Object.values(s);function l(e=c){return e[Math.floor(Math.random()*e.length)]}var u=class extends HTMLElement{active=!1;resizeObserver=null;world;view;textWriter;animationFrameId=null;connectedCallback(){this.innerHTML=`
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.TextFlow={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=function(e){return e[e.Horizontal=0]=`Horizontal`,e[e.Vertical=1]=`Vertical`,e}({}),n=class{_textDirection;updateId=void 0;_isRunning=!1;_elements=[];_width=0;_height=0;constructor(e){this._textDirection=e}get elements(){return this._elements}addElement(e){this._elements.push(e)}resize(e,t){this._width=e,this._height=t}start(){this._isRunning||(this._isRunning=!0,this.updateWorld())}stop(){this._isRunning=!1,this.updateId!==void 0&&(window.clearTimeout(this.updateId),this.updateId=void 0)}areObjectsColliding(e,t){let n=e.boundingBox.left>t.boundingBox.right||t.boundingBox.left>e.boundingBox.right,r=e.boundingBox.top>t.boundingBox.bottom||t.boundingBox.top>e.boundingBox.bottom;return!(n||r)}getCollisionAxis(e,n){let r=[e.positionX,e.positionX+e.width,n.positionX,n.positionX+n.width],i=[e.positionY,e.positionY+e.height,n.positionY,n.positionY+n.height],a=(e,t)=>e-t;return r.sort(a),i.sort(a),r[2]-r[1]<i[2]-i[1]?t.Horizontal:t.Vertical}handleCollision(e,n){switch(this.getCollisionAxis(e,n)){case t.Horizontal:this.handleXCollision(e,n);break;case t.Vertical:this.handleYCollision(e,n);break}}handleXCollision(e,t){if(this._textDirection.x===0)return;let n=e.boundingBox.left<t.boundingBox.left,r=n?e:t,i=n?t:e;this._textDirection.x<0?(r.boostUpByCollision(i),i.breakDownByCollision(r)):(i.boostUpByCollision(r),r.breakDownByCollision(i))}handleYCollision(e,t){if(this._textDirection.y===0)return;let n=e.boundingBox.top<t.boundingBox.top,r=n?e:t,i=n?t:e;this._textDirection.y<0?(r.boostUpByCollision(i),i.breakDownByCollision(r)):(i.boostUpByCollision(r),r.breakDownByCollision(i))}detectCollisions(){for(let e=0;e<this._elements.length;e++){let t=this._elements[e];for(let n=e+1;n<this._elements.length;n++){let e=this._elements[n];this.areObjectsColliding(t,e)&&this.handleCollision(t,e)}}}updateElements(){for(let e=this._elements.length-1;e>=0;e--){let t=this._elements[e];t.move();let n=!1;this._textDirection.x!==0&&(n=t.isCollidingWithBorderX(this._textDirection.x,this._width)),!n&&this._textDirection.y!==0&&(n=t.isCollidingWithBorderY(this._textDirection.y,this._height)),n&&this._elements.splice(e,1)}}updateWorld(){this._isRunning&&(this.detectCollisions(),this.updateElements(),this.updateId=window.setTimeout(()=>this.updateWorld(),1e3/60))}},r=class{_settings;_target;_canvas;_context2d;_world;_renderId=0;constructor(e,t,n,r,i){this._settings=e,this._target=t,this._canvas=n,this._context2d=r,this._world=i,this._target.style.display=`block`,this._target.style.width=this._settings.width,this._target.style.height=this._settings.height,this._target.style.background=this._settings.background}setFontSize(e){this._context2d.font=`${e}pt ${this._settings.font}`}measureText(e){return this._context2d.measureText(e).width}resize(){let e=typeof window<`u`&&window.devicePixelRatio||1;this._canvas.width=this._target.clientWidth*e,this._canvas.height=this._target.clientHeight*e,this._canvas.style.width=`${this._target.clientWidth}px`,this._canvas.style.height=`${this._target.clientHeight}px`,this._context2d.scale(e,e)}clear(){if(!this._context2d)return;let e=this._context2d.fillStyle;this._context2d.fillStyle=this._settings.debug?`rgba(255, 255, 0, 1)`:this._settings.background,this._context2d.fillRect(0,0,this._target.clientWidth,this._target.clientHeight),this._context2d.fillStyle=e}start(){this._context2d&&(this._context2d.textAlign=`start`,this._renderId===0&&this.renderView())}stop(){this._renderId!==0&&(cancelAnimationFrame(this._renderId),this._renderId=0),this.clear()}renderView=()=>{if(this._context2d){this.clear();for(let e of this._world.elements)this._context2d.font=e.font,this._settings.debug&&(this._context2d.fillStyle=`#ff0000`,this._context2d.fillRect(e.positionX,e.positionY-e.height,e.width,e.height)),this._context2d.fillStyle=e.color,this._context2d.fillText(e.text,e.positionX,e.positionY);this._renderId=requestAnimationFrame(this.renderView)}}},i=class{_positionX;_positionY;_width;_height;_text;_fontSize;_textDirection;_accelerateId=void 0;_breakDownId=void 0;_accelerationX=0;_accelerationY=0;_velocityX=0;_velocityY=0;_acceleration=0;_boundingBox;_font;_color;_maxAcceleration;constructor(e,t,n,r,i,a,o,s,c){this._positionX=e,this._positionY=t,this._width=r,this._height=i,this._text=a,this._fontSize=o,this._textDirection=s,this._maxAcceleration=n,this._acceleration=1/this._fontSize,this._boundingBox=this.calculateBoundingBox(),this._font=`${o}pt ${c.font}`,this._color=c.color}get width(){return this._width}get height(){return this._height}get positionX(){return this._positionX}set positionX(e){this._positionX=e}get positionY(){return this._positionY}set positionY(e){this._positionY=e}get boundingBox(){return this._boundingBox}set boundingBox(e){this._boundingBox=e}get accelerationX(){return this._accelerationX}get accelerationY(){return this._accelerationY}get fontSize(){return this._fontSize}get font(){return this._font}get color(){return this._color}get text(){return this._text}isCollidingWithBorderX(e,t){if(e<0){if(this._boundingBox.right<0)return!0}else if(this._boundingBox.left>t)return!0;return!1}isCollidingWithBorderY(e,t){if(e<0){if(this._boundingBox.bottom<0)return!0}else if(this._boundingBox.top>t)return!0;return!1}calculateBoundingBox(){return{top:this._positionY-this._height,right:this._positionX+this._width,bottom:this._positionY,left:this._positionX}}accelerate(){this._accelerationX+=this._acceleration*this._textDirection.x,this._accelerationY+=this._acceleration*this._textDirection.y,Math.sqrt(this._accelerationX**2+this._accelerationY**2)<this._maxAcceleration?this._accelerateId=window.setTimeout(()=>this.accelerate(),40):(this._accelerationX=this._maxAcceleration*this._textDirection.x,this._accelerationY=this._maxAcceleration*this._textDirection.y,this._accelerateId=void 0)}breakDown(){this._accelerationX+=.1*this._textDirection.x,this._accelerationY+=.1*this._textDirection.y,Math.sqrt(this._accelerationX**2+this._accelerationY**2)>this._maxAcceleration?this._breakDownId=window.setTimeout(()=>this.breakDown(),40):(this._accelerationX=this._maxAcceleration*this._textDirection.x,this._accelerationY=this._maxAcceleration*this._textDirection.y,this._breakDownId=void 0,this._accelerateId=void 0)}boostUpByCollision=e=>{this._textDirection.x!==0&&(this._accelerationX+=(e.accelerationX-this._accelerationX)*(e.fontSize/this._fontSize)),this._textDirection.y!==0&&(this._accelerationY+=(e.accelerationY-this._accelerationY)*(e.fontSize/this._fontSize)),clearTimeout(this._accelerateId),clearTimeout(this._breakDownId),this.breakDown()};breakDownByCollision=e=>{this._textDirection.x!==0&&(this._accelerationX-=this._accelerationX*(e.fontSize/this._fontSize)),this._textDirection.y!==0&&(this._accelerationY-=this._accelerationY*(e.fontSize/this._fontSize)),clearTimeout(this._accelerateId),clearTimeout(this._breakDownId),this.accelerate()};start(){this.accelerate()}move(){this._velocityX=this._accelerationX,this._velocityY=this._accelerationY,this._positionX+=this._velocityX,this._positionY+=this._velocityY,this._boundingBox=this.calculateBoundingBox()}},a=class{_settings;_textDirection;_width;_height;_world;_view;_texts;_textId=void 0;_isRunning=!1;_minFontSize=16;_maxFontSize=20;_marginTop;_marginBottom;_maxTexts;constructor(e,t,n,r,i,a,o){this._settings=e,this._textDirection=t,this._width=n,this._height=r,this._world=i,this._view=a,this._texts=o,this._marginTop=this._settings.marginTop,this._marginBottom=this._settings.marginBottom,this._maxTexts=this._settings.maxTexts,this.updateFontSizes()}addText(){if(!this._isRunning)return;if(this._world.elements.length>=this._maxTexts){this._textId=this.randomSetTimeout(()=>this.addText(),1e3,2500);return}let e=this.random(this._minFontSize,this._maxFontSize),t=this._texts[this.random(this._texts.length)];this._view.setFontSize(e);let n=this._view.measureText(t),r=this.random(1,this._settings.maxAcceleration+1),a,o,s=this._textDirection.x,c=this._textDirection.y;a=s>0?-n:s<0?this._width:this.random(0,this._width-n),o=c>0?-e+this._marginTop:c<0?this._height-this._marginBottom:this.random(this._marginTop,this._height-this._marginBottom-e),this._textDirection.isDiagonal&&(Math.random()>.5?o=this.random(this._marginTop,this._height-this._marginBottom-e):a=this.random(0,this._width-n));let l=new i(a,o,r,n,e,t,e,this._textDirection,this._settings);this._world.addElement(l),l.start(),this._textId=this.randomSetTimeout(()=>this.addText(),1e3,2500)}resize(e,t){this._width=e,this._height=t,this.updateFontSizes()}start(){this._isRunning||(this._isRunning=!0,this.addText())}stop(){this._isRunning=!1,this._textId!==void 0&&(window.clearTimeout(this._textId),this._textId=void 0)}updateFontSizes(){typeof window<`u`&&(this._minFontSize=window.innerWidth<=800?12:16,this._maxFontSize=window.innerWidth<=800?16:20)}random(e,t){return t===void 0?Math.floor(Math.random()*e):e+Math.floor(Math.random()*(t-e+1))}randomSetTimeout(e,t,n){return window.setTimeout(()=>e(),this.random(t,n))}},o={NORTH:{x:0,y:-1},NORTHEAST:{x:1,y:-1},EAST:{x:1,y:0},SOUTHEAST:{x:1,y:1},SOUTH:{x:0,y:1},SOUTHWEST:{x:-1,y:1},WEST:{x:-1,y:0},NORTHWEST:{x:-1,y:-1},NONE:{x:0,y:0}},s=class e{heading;constructor(e){this.heading=e}static from(t){return new e(t)}static randomDirection(t=[`EAST`,`WEST`]){let n=t[Math.floor(Math.random()*t.length)];return e.from(n)}get x(){return o[this.heading].x}get y(){return o[this.heading].y}get isVertical(){return this.x===0&&this.y!==0}get isHorizontal(){return this.y===0&&this.x!==0}get isDiagonal(){return this.x!==0&&this.y!==0}},c={width:`100%`,height:`200px`,maxTexts:15,maxAcceleration:15,headings:[`EAST`,`WEST`],marginTop:0,marginBottom:0,texts:[`Add`,`your`,`own`,`texts`,`here`],color:`#333`,background:`rgba(255, 255, 255, 1)`,font:`sans-serif`,debug:!1};function l(e){let t={...c};if(typeof e.maxTexts==`number`&&e.maxTexts>0?t.maxTexts=Math.floor(e.maxTexts):e.maxTexts!==void 0&&console.warn(`[textflow] Invalid maxTexts "${e.maxTexts}". Using default: ${c.maxTexts}`),typeof e.maxAcceleration==`number`&&e.maxAcceleration>0&&(t.maxAcceleration=e.maxAcceleration),Array.isArray(e.headings)){let n=e.headings.filter(e=>typeof e==`string`&&e.toUpperCase()in o);n.length>0&&(t.headings=n)}return typeof e.marginTop==`number`&&e.marginTop>=0&&(t.marginTop=e.marginTop),typeof e.marginBottom==`number`&&e.marginBottom>=0&&(t.marginBottom=e.marginBottom),typeof e.font==`string`&&e.font.trim()!==``&&(t.font=e.font),typeof e.color==`string`&&e.color.trim()!==``&&(t.color=e.color),typeof e.background==`string`&&e.background.trim()!==``&&(t.background=e.background),e.debug!==void 0&&(t.debug=!!e.debug),t}var u=class extends HTMLElement{active=!1;resizeObserver=null;world;view;textWriter;animationFrameId=null;connectedCallback(){this.innerHTML=`
|
|
2
2
|
<div class="slider-container">
|
|
3
3
|
<canvas class="physics-canvas"></canvas>
|
|
4
4
|
</div>
|
|
5
|
-
`;let e=this.querySelector(`.physics-canvas`),
|
|
5
|
+
`;let e=this.querySelector(`.physics-canvas`),t=e.getContext(`2d`);if(!t){console.error(`Could not get context2d`);return}let i=this.dataset.settings,o=l(i?JSON.parse(i):c),u=this.dataset.texts,d=u?JSON.parse(u):o.texts,f=s.randomDirection(o.headings);this.world=new n(f),this.view=new r(o,this,e,t,this.world),this.textWriter=new a(o,f,this.offsetWidth,this.offsetHeight,this.world,this.view,d),this.startLoop(),document.addEventListener(`visibilitychange`,this.visibilityChange),this.resizeObserver=new ResizeObserver(()=>{this.resize()}),this.resizeObserver.observe(this)}disconnectedCallback(){this.stopLoop(),document.removeEventListener(`visibilitychange`,this.visibilityChange),this.resizeObserver&&this.resizeObserver.disconnect()}loop=()=>{this.active&&(this.animationFrameId=window.requestAnimationFrame(this.loop))};startLoop=()=>{this.active||(this.view.start(),this.world.start(),this.textWriter.start(),this.active=!0,this.animationFrameId=window.requestAnimationFrame(this.loop))};stopLoop(){this.active&&(this.view.stop(),this.world.stop(),this.textWriter.stop(),this.active=!1,this.animationFrameId&&=(window.cancelAnimationFrame(this.animationFrameId),null))}resize(){this.view.resize(),this.world.resize(this.offsetWidth,this.offsetHeight),this.textWriter.resize(this.offsetWidth,this.offsetHeight)}visibilityChange=()=>{document.hidden?this.stopLoop():this.startLoop()}};function d(e=`textflow-container`){typeof window<`u`&&!customElements.get(e)&&customElements.define(e,u)}e.TextFlowElement=u,e.registerTextFlowSlider=d});
|
package/package.json
CHANGED
package/dist/src/directions.d.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
export interface Direction {
|
|
2
|
-
x: number;
|
|
3
|
-
y: number;
|
|
4
|
-
}
|
|
5
|
-
export declare const directions: {
|
|
6
|
-
readonly none: {
|
|
7
|
-
readonly x: 0;
|
|
8
|
-
readonly y: 0;
|
|
9
|
-
};
|
|
10
|
-
readonly north: {
|
|
11
|
-
readonly x: 0;
|
|
12
|
-
readonly y: -1;
|
|
13
|
-
};
|
|
14
|
-
readonly northEast: {
|
|
15
|
-
readonly x: 1;
|
|
16
|
-
readonly y: -1;
|
|
17
|
-
};
|
|
18
|
-
readonly east: {
|
|
19
|
-
readonly x: 1;
|
|
20
|
-
readonly y: 0;
|
|
21
|
-
};
|
|
22
|
-
readonly southEast: {
|
|
23
|
-
readonly x: 1;
|
|
24
|
-
readonly y: 1;
|
|
25
|
-
};
|
|
26
|
-
readonly south: {
|
|
27
|
-
readonly x: 0;
|
|
28
|
-
readonly y: 1;
|
|
29
|
-
};
|
|
30
|
-
readonly southWest: {
|
|
31
|
-
readonly x: -1;
|
|
32
|
-
readonly y: 1;
|
|
33
|
-
};
|
|
34
|
-
readonly west: {
|
|
35
|
-
readonly x: -1;
|
|
36
|
-
readonly y: 0;
|
|
37
|
-
};
|
|
38
|
-
readonly northWest: {
|
|
39
|
-
readonly x: -1;
|
|
40
|
-
readonly y: -1;
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
|
-
export declare const defaultDirections: ({
|
|
44
|
-
readonly x: 0;
|
|
45
|
-
readonly y: 0;
|
|
46
|
-
} | {
|
|
47
|
-
readonly x: 0;
|
|
48
|
-
readonly y: -1;
|
|
49
|
-
} | {
|
|
50
|
-
readonly x: 1;
|
|
51
|
-
readonly y: -1;
|
|
52
|
-
} | {
|
|
53
|
-
readonly x: 1;
|
|
54
|
-
readonly y: 0;
|
|
55
|
-
} | {
|
|
56
|
-
readonly x: 1;
|
|
57
|
-
readonly y: 1;
|
|
58
|
-
} | {
|
|
59
|
-
readonly x: 0;
|
|
60
|
-
readonly y: 1;
|
|
61
|
-
} | {
|
|
62
|
-
readonly x: -1;
|
|
63
|
-
readonly y: 1;
|
|
64
|
-
} | {
|
|
65
|
-
readonly x: -1;
|
|
66
|
-
readonly y: 0;
|
|
67
|
-
} | {
|
|
68
|
-
readonly x: -1;
|
|
69
|
-
readonly y: -1;
|
|
70
|
-
})[];
|
|
71
|
-
export declare function randomDirection(availableDirections?: readonly Direction[]): Direction;
|