tosijs-ui 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/iife.js +70 -60
- package/dist/iife.js.map +42 -42
- package/dist/index.js +15 -37
- package/dist/index.js.map +39 -39
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
- package/dist/ab-test.js +0 -116
- package/dist/babylon-3d.js +0 -292
- package/dist/bodymovin-player.js +0 -172
- package/dist/bp-loader.js +0 -26
- package/dist/carousel.js +0 -308
- package/dist/code-editor.js +0 -102
- package/dist/color-input.js +0 -112
- package/dist/data-table.js +0 -774
- package/dist/drag-and-drop.js +0 -386
- package/dist/editable-rect.js +0 -450
- package/dist/filter-builder.js +0 -468
- package/dist/float.js +0 -170
- package/dist/form.js +0 -466
- package/dist/gamepad.js +0 -115
- package/dist/icon-data.js +0 -308
- package/dist/icon-types.js +0 -1
- package/dist/icons.js +0 -374
- package/dist/index-iife.js +0 -4
- package/dist/live-example.js +0 -611
- package/dist/localize.js +0 -381
- package/dist/make-sorter.js +0 -119
- package/dist/make-sorter.test.d.ts +0 -1
- package/dist/make-sorter.test.js +0 -48
- package/dist/mapbox.js +0 -161
- package/dist/markdown-viewer.js +0 -173
- package/dist/match-shortcut.js +0 -13
- package/dist/match-shortcut.test.d.ts +0 -1
- package/dist/match-shortcut.test.js +0 -194
- package/dist/menu.js +0 -614
- package/dist/notifications.js +0 -308
- package/dist/password-strength.js +0 -302
- package/dist/playwright.config.d.ts +0 -9
- package/dist/playwright.config.js +0 -73
- package/dist/pop-float.js +0 -231
- package/dist/rating.js +0 -192
- package/dist/rich-text.js +0 -296
- package/dist/segmented.js +0 -298
- package/dist/select.js +0 -427
- package/dist/side-nav.js +0 -106
- package/dist/size-break.js +0 -118
- package/dist/sizer.js +0 -92
- package/dist/src/ab-test.d.ts +0 -14
- package/dist/src/babylon-3d.d.ts +0 -53
- package/dist/src/bodymovin-player.d.ts +0 -32
- package/dist/src/bp-loader.d.ts +0 -0
- package/dist/src/carousel.d.ts +0 -113
- package/dist/src/code-editor.d.ts +0 -27
- package/dist/src/color-input.d.ts +0 -41
- package/dist/src/data-table.d.ts +0 -79
- package/dist/src/drag-and-drop.d.ts +0 -2
- package/dist/src/editable-rect.d.ts +0 -97
- package/dist/src/filter-builder.d.ts +0 -64
- package/dist/src/float.d.ts +0 -18
- package/dist/src/form.d.ts +0 -68
- package/dist/src/gamepad.d.ts +0 -34
- package/dist/src/icon-data.d.ts +0 -309
- package/dist/src/icon-types.d.ts +0 -7
- package/dist/src/icons.d.ts +0 -17
- package/dist/src/index.d.ts +0 -37
- package/dist/src/live-example.d.ts +0 -51
- package/dist/src/localize.d.ts +0 -30
- package/dist/src/make-sorter.d.ts +0 -3
- package/dist/src/mapbox.d.ts +0 -24
- package/dist/src/markdown-viewer.d.ts +0 -15
- package/dist/src/match-shortcut.d.ts +0 -9
- package/dist/src/menu.d.ts +0 -60
- package/dist/src/notifications.d.ts +0 -106
- package/dist/src/password-strength.d.ts +0 -35
- package/dist/src/pop-float.d.ts +0 -10
- package/dist/src/rating.d.ts +0 -62
- package/dist/src/rich-text.d.ts +0 -28
- package/dist/src/segmented.d.ts +0 -80
- package/dist/src/select.d.ts +0 -43
- package/dist/src/side-nav.d.ts +0 -36
- package/dist/src/size-break.d.ts +0 -18
- package/dist/src/sizer.d.ts +0 -34
- package/dist/src/tab-selector.d.ts +0 -91
- package/dist/src/tag-list.d.ts +0 -37
- package/dist/src/track-drag.d.ts +0 -5
- package/dist/src/version.d.ts +0 -1
- package/dist/src/via-tag.d.ts +0 -2
- package/dist/tab-selector.js +0 -326
- package/dist/tag-list.js +0 -375
- package/dist/track-drag.js +0 -143
- package/dist/version.js +0 -1
- package/dist/via-tag.js +0 -102
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.0.
|
|
1
|
+
export declare const version = "1.0.2";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tosijs-ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "simple robust web-components for use with xinjs or anything else",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "bun --watch bin/dev.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@playwright/test": "^1.54.1",
|
|
29
29
|
"@types/jsdom": "^21.1.7",
|
|
30
|
-
"@types/node": "^22.16.
|
|
30
|
+
"@types/node": "^22.16.4",
|
|
31
31
|
"@types/react": "^19.1.8",
|
|
32
32
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
33
33
|
"@typescript-eslint/parser": "^5.62.0",
|
package/dist/ab-test.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/*#
|
|
2
|
-
# ab-test
|
|
3
|
-
|
|
4
|
-
`<xin-ab>` provides a simple method for implementing A|B-testing.
|
|
5
|
-
|
|
6
|
-
```js
|
|
7
|
-
const { AbTest } = xinjsui
|
|
8
|
-
|
|
9
|
-
function randomize() {
|
|
10
|
-
const conditions = {
|
|
11
|
-
testA: Math.random() < 0.5,
|
|
12
|
-
testB: Math.random() < 0.5,
|
|
13
|
-
testC: Math.random() < 0.5
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
AbTest.conditions = conditions
|
|
17
|
-
|
|
18
|
-
preview.querySelector('pre').innerText = JSON.stringify(conditions, null, 2)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
preview.querySelector('.randomize-conditions').addEventListener('click', randomize)
|
|
22
|
-
|
|
23
|
-
randomize()
|
|
24
|
-
```
|
|
25
|
-
```html
|
|
26
|
-
<div style="display: flex; gap: 10px; align-items: center;">
|
|
27
|
-
<div style="display: flex; flex-direction: column; gap: 10px;">
|
|
28
|
-
<xin-ab class="a" condition="testA">
|
|
29
|
-
<p>testA</p>
|
|
30
|
-
</xin-ab>
|
|
31
|
-
<xin-ab class="not-a" not condition="testA">
|
|
32
|
-
<p>not testA</p>
|
|
33
|
-
</xin-ab>
|
|
34
|
-
<xin-ab class="b" condition="testB">
|
|
35
|
-
<p>testB</p>
|
|
36
|
-
</xin-ab>
|
|
37
|
-
<xin-ab class="not-b" not condition="testB">
|
|
38
|
-
<p>not testB</p>
|
|
39
|
-
</xin-ab>
|
|
40
|
-
<xin-ab class="c" condition="testC">
|
|
41
|
-
<p>testC</p>
|
|
42
|
-
</xin-ab>
|
|
43
|
-
<xin-ab class="not-c" not condition="testC">
|
|
44
|
-
<p>not testC</p>
|
|
45
|
-
</xin-ab>
|
|
46
|
-
</div>
|
|
47
|
-
<pre>
|
|
48
|
-
</pre>
|
|
49
|
-
</div>
|
|
50
|
-
<button class="randomize-conditions">Randomize</button>
|
|
51
|
-
```
|
|
52
|
-
```css
|
|
53
|
-
.preview {
|
|
54
|
-
display: flex;
|
|
55
|
-
flex-direction: column;
|
|
56
|
-
gap: 4px;
|
|
57
|
-
align-items: flex-start;
|
|
58
|
-
}
|
|
59
|
-
.preview p {
|
|
60
|
-
background: #44c;
|
|
61
|
-
color: white;
|
|
62
|
-
display: block;
|
|
63
|
-
border-radius: 99px;
|
|
64
|
-
padding: 4px 10px;
|
|
65
|
-
margin: 0;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.preview xin-ab[not] p {
|
|
69
|
-
background: red;
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
- Set `AbTest.conditions` to anything you like.
|
|
74
|
-
- Use `<xin-ab>` elements to display conditional content.
|
|
75
|
-
- `condition` attribute determines which value in `AbTest.conditions` controls the element
|
|
76
|
-
- `not` reverses the condition (so `<xin-ab not condition="foo">` will be visible if `conditions.foo` is `false`)
|
|
77
|
-
*/
|
|
78
|
-
import { Component, xinProxy } from 'xinjs';
|
|
79
|
-
const { abTestConditions } = xinProxy({
|
|
80
|
-
abTestConditions: {},
|
|
81
|
-
});
|
|
82
|
-
export class AbTest extends Component {
|
|
83
|
-
static set conditions(context) {
|
|
84
|
-
Object.assign(abTestConditions, context);
|
|
85
|
-
for (const abTest of [...AbTest.instances]) {
|
|
86
|
-
abTest.queueRender();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
condition = '';
|
|
90
|
-
not = false;
|
|
91
|
-
static instances = new Set();
|
|
92
|
-
constructor() {
|
|
93
|
-
super();
|
|
94
|
-
this.initAttributes('condition', 'not');
|
|
95
|
-
}
|
|
96
|
-
connectedCallback() {
|
|
97
|
-
super.connectedCallback();
|
|
98
|
-
AbTest.instances.add(this);
|
|
99
|
-
}
|
|
100
|
-
disconnectedCallback() {
|
|
101
|
-
super.disconnectedCallback();
|
|
102
|
-
AbTest.instances.delete(this);
|
|
103
|
-
}
|
|
104
|
-
render() {
|
|
105
|
-
if (this.condition !== '' &&
|
|
106
|
-
(this.not
|
|
107
|
-
? abTestConditions[this.condition] !== true
|
|
108
|
-
: abTestConditions[this.condition] === true)) {
|
|
109
|
-
this.toggleAttribute('hidden', false);
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
this.toggleAttribute('hidden', true);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
export const abTest = AbTest.elementCreator({ tag: 'xin-ab' });
|
package/dist/babylon-3d.js
DELETED
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
/*#
|
|
2
|
-
# 3d
|
|
3
|
-
|
|
4
|
-
A [babylonjs](https://www.babylonjs.com/) wrapper.
|
|
5
|
-
|
|
6
|
-
A `<xin-3d>` element is initialized with an `engine`, `canvas`, `scene`, and an update-loop.
|
|
7
|
-
|
|
8
|
-
If you view this example with an XR-enabled device, such as the
|
|
9
|
-
[Meta Quest 3](https://www.meta.com/quest/quest-3/), then you should be able to view this
|
|
10
|
-
as an AR scene.
|
|
11
|
-
|
|
12
|
-
```js
|
|
13
|
-
const { b3d, gamepadText, xrControllers, xrControllersText } = xinjsui
|
|
14
|
-
|
|
15
|
-
preview.append(b3d({
|
|
16
|
-
async sceneCreated(element, BABYLON) {
|
|
17
|
-
const camera = new BABYLON.FreeCamera(
|
|
18
|
-
'camera',
|
|
19
|
-
new BABYLON.Vector3(0, 1, -4),
|
|
20
|
-
element.scene
|
|
21
|
-
)
|
|
22
|
-
camera.attachControl(element.parts.canvas, true)
|
|
23
|
-
|
|
24
|
-
new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0.25, 1, -0.5))
|
|
25
|
-
|
|
26
|
-
this.loadScene('/', 'xin3d.glb')
|
|
27
|
-
|
|
28
|
-
const size = 1024
|
|
29
|
-
const textTexture = new BABYLON.DynamicTexture('Text', size, element.scene)
|
|
30
|
-
const textContext = textTexture.getContext()
|
|
31
|
-
textTexture.update()
|
|
32
|
-
|
|
33
|
-
const textMaterial = new BABYLON.StandardMaterial('Text', element.scene)
|
|
34
|
-
textMaterial.diffuseTexture = textTexture
|
|
35
|
-
textMaterial.emissiveTexture = textTexture
|
|
36
|
-
textMaterial.backfaceCulling = false
|
|
37
|
-
|
|
38
|
-
const plaque = BABYLON.MeshBuilder.CreatePlane('Plaque', {size: 1}, element.scene)
|
|
39
|
-
plaque.position.x = 0
|
|
40
|
-
plaque.position.y = 2
|
|
41
|
-
plaque.billboardMode = BABYLON.Mesh.BILLBOARDMODE_ALL
|
|
42
|
-
plaque.material = textMaterial
|
|
43
|
-
|
|
44
|
-
let controllers
|
|
45
|
-
if (navigator.xr) {
|
|
46
|
-
const xrHelper = await element.scene.createDefaultXRExperienceAsync({
|
|
47
|
-
uiOptions: {
|
|
48
|
-
sessionMode: 'immersive-ar'
|
|
49
|
-
}
|
|
50
|
-
})
|
|
51
|
-
controllers = xrControllers(xrHelper)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const interval = setInterval(() => {
|
|
55
|
-
if (document.body.contains(element)) {
|
|
56
|
-
textContext.fillStyle = '#204020'
|
|
57
|
-
textContext.fillRect(0, 0, size, size)
|
|
58
|
-
const text = gamepadText() + '\n' + xrControllersText(controllers)
|
|
59
|
-
const lines = text.split('\n')
|
|
60
|
-
textContext.fillStyle = '#afa'
|
|
61
|
-
textContext.font = '32px monospace'
|
|
62
|
-
for(let i = 0; i < lines.length; i++) {
|
|
63
|
-
const line = lines[i]
|
|
64
|
-
textContext.fillText(line, 40, 70 + i * 40)
|
|
65
|
-
}
|
|
66
|
-
textContext.fillStyle = '#bbb'
|
|
67
|
-
textContext.fillText('xinjs-xr — debug info', 40, 984)
|
|
68
|
-
textTexture.update()
|
|
69
|
-
} else {
|
|
70
|
-
clearInterval(interval)
|
|
71
|
-
}
|
|
72
|
-
}, 100)
|
|
73
|
-
},
|
|
74
|
-
}))
|
|
75
|
-
```
|
|
76
|
-
```css
|
|
77
|
-
.preview xin-3d {
|
|
78
|
-
width: 100%;
|
|
79
|
-
height: 100%;
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
You can access the `scene` and `engine` properties. You can also assign `sceneCreated`
|
|
84
|
-
and `update` callbacks that will be executed when the scene is first initialized and
|
|
85
|
-
before each update, respectively. (See the example, it does both.)
|
|
86
|
-
|
|
87
|
-
Both `sceneCreated` and `update` may be `async`. The component will `await` `sceneCreated`
|
|
88
|
-
before starting the renderLoop, but `update` is simply passed to babylon, so be careful.
|
|
89
|
-
|
|
90
|
-
By default, this component loads `babylon.js` from the [babylonjs CDN](https://doc.babylonjs.com/setup/frameworkPackages/CDN),
|
|
91
|
-
but if `BABYLON` is already defined (e.g. if you've bundled it) then it will use that instead.
|
|
92
|
-
|
|
93
|
-
If you need additional libraries, e.g. `https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js` for loading models such as `gltf` and `glb` files, you should load those in `sceneCreated`.
|
|
94
|
-
|
|
95
|
-
Here's a simple example of a terrain mesh comprising 125k triangles, 50% of which is being scaled using a `profileScale` function that
|
|
96
|
-
takes an array of numbers that use a linear profile to change the landform.
|
|
97
|
-
|
|
98
|
-
```js
|
|
99
|
-
const { b3d } = xinjsui
|
|
100
|
-
const { MoreMath } = xinjs
|
|
101
|
-
|
|
102
|
-
const debugCutoff = 0.5
|
|
103
|
-
const defaultProfile = [0, 1, 5, 8, 10].map(x => x/10)
|
|
104
|
-
|
|
105
|
-
const { clamp } = MoreMath
|
|
106
|
-
function profileScale(t = 0, bypass = false, profile = defaultProfile) {
|
|
107
|
-
if (bypass) {
|
|
108
|
-
return t
|
|
109
|
-
}
|
|
110
|
-
const count = profile.length - 1
|
|
111
|
-
if (count < 1) {
|
|
112
|
-
throw new Error('profile must be of length ≥ 2')
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const s = clamp(0, (t + 1) / 2, 1)
|
|
116
|
-
const index = Math.floor(s * count)
|
|
117
|
-
const dt = (s - index / count) * count
|
|
118
|
-
const min = profile[index]
|
|
119
|
-
const max = profile[index + 1]
|
|
120
|
-
const p = dt * (max - min) + min
|
|
121
|
-
return 2 * p - 1
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
preview.append(b3d({
|
|
125
|
-
async sceneCreated(element, BABYLON) {
|
|
126
|
-
const { scene } = element
|
|
127
|
-
const { createNoise2D } = await import('https://cdn.jsdelivr.net/npm/simplex-noise@4.0.1/+esm')
|
|
128
|
-
|
|
129
|
-
new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0.25, 1, 2))
|
|
130
|
-
|
|
131
|
-
const terrain = new BABYLON.Mesh('terrain', scene)
|
|
132
|
-
const vertexData = new BABYLON.VertexData()
|
|
133
|
-
|
|
134
|
-
const noise2D = createNoise2D()
|
|
135
|
-
const positions = []
|
|
136
|
-
const indices = []
|
|
137
|
-
const gridSize = 100
|
|
138
|
-
const gridResolution = 250
|
|
139
|
-
const gridPoints = gridResolution + 1
|
|
140
|
-
const noiseScale = 0.03
|
|
141
|
-
const heightScale = 4.5
|
|
142
|
-
terrain.position.y = -5
|
|
143
|
-
const scale = t => t * gridSize / gridResolution - gridSize * 0.5
|
|
144
|
-
for(let x = 0; x <= gridResolution; x++) {
|
|
145
|
-
for(let z = 0; z <= gridResolution; z++) {
|
|
146
|
-
const y = profileScale(noise2D(scale(x) * noiseScale, scale(z) * noiseScale), x < gridResolution * debugCutoff)
|
|
147
|
-
positions.push(scale(x), y * heightScale, scale(z))
|
|
148
|
-
if (x > 0 && z > 0) {
|
|
149
|
-
const i = x * gridPoints + z
|
|
150
|
-
indices.push(
|
|
151
|
-
i, i - gridPoints - 1, i - 1,
|
|
152
|
-
i, i - gridPoints, i - gridPoints - 1,
|
|
153
|
-
)
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
const normals = []
|
|
158
|
-
BABYLON.VertexData.ComputeNormals(positions, indices, normals);
|
|
159
|
-
|
|
160
|
-
vertexData.positions = positions
|
|
161
|
-
vertexData.indices = indices
|
|
162
|
-
vertexData.normals = normals
|
|
163
|
-
vertexData.applyToMesh(terrain)
|
|
164
|
-
},
|
|
165
|
-
}))
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## loadScene
|
|
169
|
-
|
|
170
|
-
`<xin-3d>.loadScene(path: string, file: string, callBack(meshes: any[]): void)` can
|
|
171
|
-
be used to load `.glb` files.
|
|
172
|
-
|
|
173
|
-
## loadUI
|
|
174
|
-
|
|
175
|
-
`<xin-3d>.loadUI(options: B3dUIOptions)` loads babylonjs guis, which you can create programmatically or using the [babylonjs gui tool](https://gui.babylonjs.com/).
|
|
176
|
-
*/
|
|
177
|
-
import { Component as WebComponent, elements } from 'xinjs';
|
|
178
|
-
import { scriptTag } from './via-tag';
|
|
179
|
-
import { icons, svg2DataUrl } from './icons';
|
|
180
|
-
const noop = () => {
|
|
181
|
-
/* do not care */
|
|
182
|
-
};
|
|
183
|
-
export class B3d extends WebComponent {
|
|
184
|
-
babylonReady;
|
|
185
|
-
BABYLON;
|
|
186
|
-
static styleSpec = {
|
|
187
|
-
':host': {
|
|
188
|
-
display: 'block',
|
|
189
|
-
position: 'relative',
|
|
190
|
-
},
|
|
191
|
-
':host canvas': {
|
|
192
|
-
width: '100%',
|
|
193
|
-
height: '100%',
|
|
194
|
-
},
|
|
195
|
-
':host .babylonVRicon': {
|
|
196
|
-
height: 50,
|
|
197
|
-
width: 80,
|
|
198
|
-
backgroundColor: 'transparent',
|
|
199
|
-
filter: 'drop-shadow(0 0 4px #000c)',
|
|
200
|
-
backgroundImage: svg2DataUrl(icons.xrColor()),
|
|
201
|
-
backgroundPosition: 'center',
|
|
202
|
-
backgroundRepeat: 'no-repeat',
|
|
203
|
-
border: 'none',
|
|
204
|
-
borderRadius: 5,
|
|
205
|
-
borderStyle: 'none',
|
|
206
|
-
outline: 'none',
|
|
207
|
-
transition: 'transform 0.125s ease-out',
|
|
208
|
-
},
|
|
209
|
-
':host .babylonVRicon:hover': {
|
|
210
|
-
transform: 'scale(1.1)',
|
|
211
|
-
},
|
|
212
|
-
};
|
|
213
|
-
content = elements.canvas({ part: 'canvas' });
|
|
214
|
-
constructor() {
|
|
215
|
-
super();
|
|
216
|
-
this.babylonReady = (async () => {
|
|
217
|
-
const { BABYLON } = await scriptTag('https://cdn.babylonjs.com/babylon.js', 'BABYLON');
|
|
218
|
-
return BABYLON;
|
|
219
|
-
})();
|
|
220
|
-
}
|
|
221
|
-
scene;
|
|
222
|
-
engine;
|
|
223
|
-
sceneCreated = noop;
|
|
224
|
-
update = noop;
|
|
225
|
-
_update = () => {
|
|
226
|
-
if (this.scene) {
|
|
227
|
-
if (this.update !== undefined) {
|
|
228
|
-
this.update(this, this.BABYLON);
|
|
229
|
-
}
|
|
230
|
-
if (this.scene.activeCamera !== undefined) {
|
|
231
|
-
this.scene.render();
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
onResize() {
|
|
236
|
-
if (this.engine) {
|
|
237
|
-
this.engine.resize();
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
loadScene = async (path, file, processCallback) => {
|
|
241
|
-
const { BABYLON } = await scriptTag('https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js', 'BABYLON');
|
|
242
|
-
BABYLON.SceneLoader.Append(path, file, this.scene, processCallback);
|
|
243
|
-
};
|
|
244
|
-
loadUI = async (options) => {
|
|
245
|
-
const { BABYLON } = await scriptTag('https://cdn.babylonjs.com/gui/babylon.gui.min.js', 'BABYLON');
|
|
246
|
-
const advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI('GUI', true, this.scene);
|
|
247
|
-
const { snippetId, jsonUrl, data, size } = options;
|
|
248
|
-
if (size) {
|
|
249
|
-
advancedTexture.idealWidth = size;
|
|
250
|
-
advancedTexture.renderAtIdealSize = true;
|
|
251
|
-
}
|
|
252
|
-
// edit or create your own snippet here
|
|
253
|
-
// https://gui.babylonjs.com/
|
|
254
|
-
let gui;
|
|
255
|
-
if (snippetId) {
|
|
256
|
-
gui = await advancedTexture.parseFromSnippetAsync(snippetId);
|
|
257
|
-
}
|
|
258
|
-
else if (jsonUrl) {
|
|
259
|
-
gui = await advancedTexture.parseFromURLAsync(jsonUrl);
|
|
260
|
-
}
|
|
261
|
-
else if (data) {
|
|
262
|
-
gui = advancedTexture.parseContent(data);
|
|
263
|
-
}
|
|
264
|
-
else {
|
|
265
|
-
return null;
|
|
266
|
-
}
|
|
267
|
-
const root = advancedTexture.getChildren()[0];
|
|
268
|
-
const widgets = root.children.reduce((map, widget) => {
|
|
269
|
-
map[widget.name] = widget;
|
|
270
|
-
return map;
|
|
271
|
-
}, {});
|
|
272
|
-
return { advancedTexture, gui, root, widgets };
|
|
273
|
-
};
|
|
274
|
-
connectedCallback() {
|
|
275
|
-
super.connectedCallback();
|
|
276
|
-
const { canvas } = this.parts;
|
|
277
|
-
this.babylonReady.then(async (BABYLON) => {
|
|
278
|
-
this.BABYLON = BABYLON;
|
|
279
|
-
this.engine = new BABYLON.Engine(canvas, true);
|
|
280
|
-
this.scene = new BABYLON.Scene(this.engine);
|
|
281
|
-
if (this.sceneCreated) {
|
|
282
|
-
await this.sceneCreated(this, BABYLON);
|
|
283
|
-
}
|
|
284
|
-
if (this.scene.activeCamera === undefined) {
|
|
285
|
-
const camera = new BABYLON.ArcRotateCamera('default-camera', -Math.PI / 2, Math.PI / 2.5, 3, new BABYLON.Vector3(0, 0, 0));
|
|
286
|
-
camera.attachControl(this.parts.canvas, true);
|
|
287
|
-
}
|
|
288
|
-
this.engine.runRenderLoop(this._update);
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
export const b3d = B3d.elementCreator({ tag: 'xin-3d' });
|
package/dist/bodymovin-player.js
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/*#
|
|
2
|
-
# lottie / bodymovin
|
|
3
|
-
|
|
4
|
-
A [lottie](https://airbnb.io/lottie/#/web) (a.k.a. **bodymovin**) player.
|
|
5
|
-
|
|
6
|
-
It's designed to work like an `<img>` element (just set its `src` attribute).
|
|
7
|
-
|
|
8
|
-
```js
|
|
9
|
-
const { xinProxy } = xinjs
|
|
10
|
-
const { icons, popFloat } = xinjsui
|
|
11
|
-
const { div, label, input, select, option, span } = xinjs.elements
|
|
12
|
-
|
|
13
|
-
const rocket = preview.querySelector('xin-lottie')
|
|
14
|
-
setTimeout(
|
|
15
|
-
() => {
|
|
16
|
-
preview.append(
|
|
17
|
-
popFloat({
|
|
18
|
-
content: [
|
|
19
|
-
{ class: 'panel', drag: true },
|
|
20
|
-
div({ class: 'panel-header' }, 'Player Controls' ),
|
|
21
|
-
label(
|
|
22
|
-
{ class: 'no-drag' },
|
|
23
|
-
'speed',
|
|
24
|
-
input({ type: 'range', min: -1, max: 1, step: 0.1, value: 0, onInput(event) {
|
|
25
|
-
const speed = Math.pow(5, Number(event.target.value))
|
|
26
|
-
rocket.animation.setSpeed(speed)
|
|
27
|
-
event.target.nextSibling.textContent = (speed * 100).toFixed(0) + '%'
|
|
28
|
-
} }),
|
|
29
|
-
span('100%', {style: { textAlign: 'right', width: '40px'}})
|
|
30
|
-
),
|
|
31
|
-
label(
|
|
32
|
-
{ class: 'no-drag' },
|
|
33
|
-
'direction',
|
|
34
|
-
select(
|
|
35
|
-
option('Forwards', {value: 1, selected: true}),
|
|
36
|
-
option('Backwards', {value: -1}),
|
|
37
|
-
{
|
|
38
|
-
onChange(event) {
|
|
39
|
-
rocket.animation.setDirection(event.target.value)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
),
|
|
43
|
-
icons.chevronDown(),
|
|
44
|
-
)
|
|
45
|
-
],
|
|
46
|
-
target: rocket,
|
|
47
|
-
position: 's'
|
|
48
|
-
})
|
|
49
|
-
)
|
|
50
|
-
},
|
|
51
|
-
500
|
|
52
|
-
)
|
|
53
|
-
```
|
|
54
|
-
```html
|
|
55
|
-
<xin-lottie
|
|
56
|
-
style="height: 100%; max-width: 100%"
|
|
57
|
-
src="88140-rocket-livetrade.json"
|
|
58
|
-
></xin-lottie>
|
|
59
|
-
<div class="caption">
|
|
60
|
-
Animation by <a target="_blank" href="https://lottiefiles.com/dvskjbicfc">chiến lê hồng</a>
|
|
61
|
-
</div>
|
|
62
|
-
```
|
|
63
|
-
```css
|
|
64
|
-
.preview {
|
|
65
|
-
padding: var(--spacing);
|
|
66
|
-
text-align: center;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.preview .panel {
|
|
70
|
-
padding: 10px;
|
|
71
|
-
border-radius: 5px;
|
|
72
|
-
gap: 5px;
|
|
73
|
-
background: white;
|
|
74
|
-
box-shadow: 0 2px 8px rgba(0,0,0,0.25);
|
|
75
|
-
display: flex;
|
|
76
|
-
flex-direction: column;
|
|
77
|
-
overflow: hidden;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.preview .caption {
|
|
81
|
-
position: absolute;
|
|
82
|
-
right: 5px;
|
|
83
|
-
bottom: 5px;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.preview .panel-header {
|
|
87
|
-
margin: 0;
|
|
88
|
-
text-align: center;
|
|
89
|
-
font-weight: bold;
|
|
90
|
-
background: var(--brand-color);
|
|
91
|
-
color: white;
|
|
92
|
-
padding: 5px;
|
|
93
|
-
margin: -10px -10px 0 -10px;
|
|
94
|
-
cursor: move;
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
You can also directly set its `json` property to the content of a `lottie.json` file.
|
|
99
|
-
|
|
100
|
-
And of course just access the element's `animation` property to [use the bodymovin API](https://airbnb.io/lottie/#/web).
|
|
101
|
-
|
|
102
|
-
Also see the [documentation for advanced interactions](https://lottiefiles.github.io/lottie-docs/advanced_interactions/)
|
|
103
|
-
*/
|
|
104
|
-
import { Component as WebComponent } from 'xinjs';
|
|
105
|
-
import { scriptTag } from './via-tag';
|
|
106
|
-
export class BodymovinPlayer extends WebComponent {
|
|
107
|
-
content = null;
|
|
108
|
-
src = '';
|
|
109
|
-
json = '';
|
|
110
|
-
config = {
|
|
111
|
-
renderer: 'svg',
|
|
112
|
-
loop: true,
|
|
113
|
-
autoplay: true,
|
|
114
|
-
};
|
|
115
|
-
static bodymovinAvailable;
|
|
116
|
-
animation;
|
|
117
|
-
static styleSpec = {
|
|
118
|
-
':host': {
|
|
119
|
-
width: 400,
|
|
120
|
-
height: 400,
|
|
121
|
-
display: 'inline-block',
|
|
122
|
-
},
|
|
123
|
-
};
|
|
124
|
-
_loading = false;
|
|
125
|
-
get loading() {
|
|
126
|
-
return this._loading;
|
|
127
|
-
}
|
|
128
|
-
constructor() {
|
|
129
|
-
super();
|
|
130
|
-
this.initAttributes('src', 'json');
|
|
131
|
-
if (BodymovinPlayer.bodymovinAvailable === undefined) {
|
|
132
|
-
BodymovinPlayer.bodymovinAvailable = scriptTag('https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.12.2/lottie.min.js', 'bodymovin');
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
doneLoading = () => {
|
|
136
|
-
this._loading = false;
|
|
137
|
-
};
|
|
138
|
-
load = ({ bodymovin }) => {
|
|
139
|
-
this._loading = true;
|
|
140
|
-
this.config.container =
|
|
141
|
-
this.shadowRoot !== null ? this.shadowRoot : undefined;
|
|
142
|
-
if (this.json !== '') {
|
|
143
|
-
this.config.animationData = this.json;
|
|
144
|
-
delete this.config.path;
|
|
145
|
-
}
|
|
146
|
-
else if (this.src !== '') {
|
|
147
|
-
delete this.config.animationData;
|
|
148
|
-
this.config.path = this.src;
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
console.log('%c<xin-lottie>%c expected either %cjson%c (animation data) or %csrc% c(url) but found neither.', 'color: #44f; background: #fff; padding: 0 5px', 'color: default', 'color: #44f; background: #fff; padding: 0 5px', 'color: default', 'color: #44f; background: #fff; padding: 0 5px', 'color: default');
|
|
152
|
-
}
|
|
153
|
-
if (this.animation) {
|
|
154
|
-
this.animation.destroy();
|
|
155
|
-
const root = this.shadowRoot;
|
|
156
|
-
if (root !== null) {
|
|
157
|
-
root.querySelector('svg')?.remove();
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
this.animation = bodymovin.loadAnimation(this.config);
|
|
161
|
-
this.animation.addEventListener('DOMLoaded', this.doneLoading);
|
|
162
|
-
};
|
|
163
|
-
render() {
|
|
164
|
-
super.render();
|
|
165
|
-
BodymovinPlayer.bodymovinAvailable.then(this.load).catch((e) => {
|
|
166
|
-
console.error(e);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
export const bodymovinPlayer = BodymovinPlayer.elementCreator({
|
|
171
|
-
tag: 'xin-lottie',
|
|
172
|
-
});
|
package/dist/bp-loader.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
/*#
|
|
3
|
-
# blueprint loading
|
|
4
|
-
|
|
5
|
-
<center>
|
|
6
|
-
<xin-icon icon="blueprint" class="logo" size=256></xin-icon>
|
|
7
|
-
</center>
|
|
8
|
-
|
|
9
|
-
`<xin-loader>` and `<xin-blueprint>` are simple elements provided by `xinjs` for the dynamic loading
|
|
10
|
-
of component **blueprints**.
|
|
11
|
-
|
|
12
|
-
```html
|
|
13
|
-
<xin-loader>
|
|
14
|
-
<xin-blueprint tag="swiss-clock" src="https://tonioloewald.github.io/xin-clock/dist/blueprint.js"></xin-blueprint>
|
|
15
|
-
</xin-loader>
|
|
16
|
-
<swiss-clock></swiss-clock>
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Attributes
|
|
20
|
-
|
|
21
|
-
- `blueprint` is the url of the `blueprint` javascript module (required)
|
|
22
|
-
- `tag` is the tagName you wish to use. If the name of the blueprint is
|
|
23
|
-
hyphenated, then that will be used by default
|
|
24
|
-
- `property` if the blueprint module exports the blueprint function as
|
|
25
|
-
a property, you can specify the property here.
|
|
26
|
-
*/
|