@operato/property-panel 9.2.1 → 10.0.0-beta.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.
Files changed (77) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/src/index.d.ts +1 -0
  3. package/dist/src/index.js +1 -0
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/ox-property-panel.d.ts +8 -0
  6. package/dist/src/ox-property-panel.js +44 -3
  7. package/dist/src/ox-property-panel.js.map +1 -1
  8. package/dist/src/property-panel/abstract-property.js +1 -0
  9. package/dist/src/property-panel/abstract-property.js.map +1 -1
  10. package/dist/src/property-panel/data-binding/data-binding-mapper.js +1 -1
  11. package/dist/src/property-panel/data-binding/data-binding-mapper.js.map +1 -1
  12. package/dist/src/property-panel/data-binding/data-binding.js.map +1 -1
  13. package/dist/src/property-panel/effects/property-animation.js +1 -1
  14. package/dist/src/property-panel/effects/property-animation.js.map +1 -1
  15. package/dist/src/property-panel/effects/property-event-hover.js +3 -3
  16. package/dist/src/property-panel/effects/property-event-hover.js.map +1 -1
  17. package/dist/src/property-panel/effects/property-event-tap.js +4 -4
  18. package/dist/src/property-panel/effects/property-event-tap.js.map +1 -1
  19. package/dist/src/property-panel/inspector/inspector.js +6 -6
  20. package/dist/src/property-panel/inspector/inspector.js.map +1 -1
  21. package/dist/src/property-panel/shapes/shapes.d.ts +0 -2
  22. package/dist/src/property-panel/shapes/shapes.js +5 -44
  23. package/dist/src/property-panel/shapes/shapes.js.map +1 -1
  24. package/dist/src/property-panel/threed/property-material3d.d.ts +27 -0
  25. package/dist/src/property-panel/threed/property-material3d.js +189 -0
  26. package/dist/src/property-panel/threed/property-material3d.js.map +1 -0
  27. package/dist/src/property-panel/threed/property-scene3d.d.ts +26 -0
  28. package/dist/src/property-panel/threed/property-scene3d.js +314 -0
  29. package/dist/src/property-panel/threed/property-scene3d.js.map +1 -0
  30. package/dist/src/property-panel/threed/threed.d.ts +17 -0
  31. package/dist/src/property-panel/threed/threed.js +98 -0
  32. package/dist/src/property-panel/threed/threed.js.map +1 -0
  33. package/dist/src/types.d.ts +1 -1
  34. package/dist/src/types.js.map +1 -1
  35. package/dist/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +13 -9
  37. package/.editorconfig +0 -29
  38. package/.storybook/main.js +0 -5
  39. package/.storybook/preview.js +0 -52
  40. package/.storybook/server.mjs +0 -8
  41. package/demo/index.html +0 -30
  42. package/dist/stories/index.stories.d.ts +0 -22
  43. package/dist/stories/index.stories.js +0 -121
  44. package/dist/stories/index.stories.js.map +0 -1
  45. package/src/graphql/board.ts +0 -144
  46. package/src/graphql/data-subscription.ts +0 -30
  47. package/src/graphql/favorite-board.ts +0 -25
  48. package/src/graphql/group.ts +0 -138
  49. package/src/graphql/index.ts +0 -4
  50. package/src/graphql/play-group.ts +0 -225
  51. package/src/graphql/scenario.ts +0 -79
  52. package/src/index.ts +0 -8
  53. package/src/ox-property-panel.ts +0 -347
  54. package/src/property-panel/abstract-property.ts +0 -65
  55. package/src/property-panel/data-binding/data-binding-mapper.ts +0 -408
  56. package/src/property-panel/data-binding/data-binding-value-map.ts +0 -19
  57. package/src/property-panel/data-binding/data-binding-value-range.ts +0 -19
  58. package/src/property-panel/data-binding/data-binding.ts +0 -470
  59. package/src/property-panel/effects/effects.ts +0 -77
  60. package/src/property-panel/effects/property-animation.ts +0 -155
  61. package/src/property-panel/effects/property-animations.ts +0 -73
  62. package/src/property-panel/effects/property-event-hover-emphasize.ts +0 -74
  63. package/src/property-panel/effects/property-event-hover.ts +0 -255
  64. package/src/property-panel/effects/property-event-tap.ts +0 -269
  65. package/src/property-panel/effects/property-event.ts +0 -73
  66. package/src/property-panel/effects/property-shadow.ts +0 -77
  67. package/src/property-panel/effects/value-converter.ts +0 -17
  68. package/src/property-panel/inspector/inspector.ts +0 -376
  69. package/src/property-panel/shapes/shapes.ts +0 -379
  70. package/src/property-panel/specifics/specific-properties-builder.ts +0 -160
  71. package/src/property-panel/specifics/specifics.ts +0 -81
  72. package/src/property-panel/styles/styles.ts +0 -285
  73. package/src/types.ts +0 -63
  74. package/stories/index.stories.ts +0 -134
  75. package/tsconfig.json +0 -26
  76. package/web-dev-server.config.mjs +0 -27
  77. package/web-test-runner.config.mjs +0 -41
@@ -1,470 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import '@material/web/icon/icon.js'
6
- import '@operato/help/ox-title-with-help.js'
7
- import '@operato/input/ox-buttons-radio.js'
8
- import '@operato/input/ox-input-data.js'
9
- import '@operato/i18n/ox-i18n.js'
10
-
11
- import { css, html, PropertyValues } from 'lit'
12
- import { property, query, state } from 'lit/decorators.js'
13
-
14
- import { Properties, Scene } from '@hatiolab/things-scene'
15
- import { ScopedElementsMixin } from '@open-wc/scoped-elements'
16
- import { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'
17
-
18
- import { AbstractProperty } from '../abstract-property.js'
19
- import { DataBindingMapper } from './data-binding-mapper.js'
20
-
21
- var clipboard = '{}'
22
-
23
- const PROPS = [
24
- '',
25
- 'text',
26
- ['fillStyle', 'fill style'],
27
- ['strokeStyle', 'stroke style'],
28
- ['fontColor', 'font color'],
29
- 'value',
30
- 'data',
31
- 'source',
32
- 'hidden',
33
- 'started',
34
- 'play',
35
- ['ref', 'reference'],
36
- 'action',
37
- 'options',
38
- 'rotate',
39
- 'dimension',
40
- 'location',
41
- 'accessor',
42
- 'appendum',
43
- 'tag',
44
- ['tap', '(tap)'],
45
- '(action)'
46
- ].map(prop => {
47
- return typeof prop == 'string' ? { name: prop, label: prop } : { name: prop[0], label: prop[1] }
48
- })
49
-
50
- export class PropertyDataBinding extends ScopedElementsMixin(AbstractProperty) {
51
- static styles = [
52
- PropertyGridStyles,
53
- css`
54
- #tab-header {
55
- display: flex;
56
- align-items: center;
57
- justify-content: space-between;
58
- }
59
-
60
- #tab-header > md-icon {
61
- padding: 0;
62
- margin: 0;
63
- width: 25px;
64
- height: 25px;
65
- font-size: x-large;
66
- border-bottom: 1px solid rgba(0, 0, 0, 0.2);
67
- }
68
-
69
- fieldset[collapsable][collapsed] > :not(legend) {
70
- display: none;
71
- }
72
-
73
- ox-buttons-radio {
74
- flex: 1;
75
- height: 25px;
76
- border: 1px solid rgba(0, 0, 0, 0.2);
77
- border-width: 1px 1px 0 1px;
78
- text-align: center;
79
-
80
- display: flex;
81
- padding: 0;
82
- box-sizing: border-box;
83
-
84
- width: 0; /* limit width */
85
- overflow-x: hidden;
86
- }
87
-
88
- ox-buttons-radio > div {
89
- background-color: rgba(0, 0, 0, 0.2);
90
- border: 1px solid rgba(0, 0, 0, 0.07);
91
- border-width: 0 0 2px 0;
92
- padding: 0;
93
- margin: 0;
94
- color: #fff;
95
- font-size: 13px;
96
- max-width: 25px;
97
- min-width: 25px;
98
- }
99
-
100
- ox-buttons-radio > div[disabled] {
101
- background-color: rgba(0, 0, 0, 0.1);
102
- }
103
-
104
- ox-buttons-radio > div[active] {
105
- border-color: rgb(242, 71, 28);
106
- }
107
-
108
- ox-buttons-radio > div.iron-selected {
109
- background-color: var(--md-sys-color-surface);
110
- color: var(--md-sys-color-on-surface);
111
- }
112
-
113
- ox-input-data {
114
- height: 300px;
115
- border-radius: var(--spacing-small);
116
- }
117
-
118
- div[binding] {
119
- display: flex;
120
- flex-direction: row-reverse;
121
- background-color: var(--md-sys-color-surface);
122
- color: var(--md-sys-color-on-surface);
123
- overflow: hidden;
124
- border-style: solid;
125
- border-color: rgba(0, 0, 0, 0.2);
126
- border-image: initial;
127
- border-width: 0px 1px;
128
- padding: 7px 5px 2px 5px;
129
- }
130
-
131
- md-icon {
132
- margin-left: 5px;
133
- color: var(--md-sys-color-on-secondary-container);
134
- opacity: 0.8;
135
- cursor: pointer;
136
- --md-icon-size: 18px;
137
- }
138
-
139
- md-icon:hover {
140
- color: var(--md-sys-color-on-primary-container);
141
- opacity: 1;
142
- }
143
-
144
- md-icon[disabled] {
145
- color: rgba(0, 0, 0, 0.1);
146
- }
147
-
148
- data-binding-mapper {
149
- --things-select: {
150
- min-width: 50%;
151
- margin-bottom: 10px;
152
- padding: 3px 20px 2px 5px;
153
- -webkit-border-radius: 4px;
154
- -moz-border-radius: 4px;
155
- border-radius: 4px;
156
- border: 1px solid rgba(0, 0, 0, 0.15);
157
- font-size: 15px;
158
- font-weight: 300;
159
- -webkit-appearance: none;
160
- };
161
- }
162
- `
163
- ]
164
-
165
- @property({ type: Object }) value?: Properties
166
- @property({ type: Object }) scene?: Scene
167
-
168
- @state() mappingIndex: number = 0
169
- @state() _afterRender?: Function | null
170
- @state() _dataExpanded: boolean = false
171
-
172
- @query('#tabs') tabs!: HTMLElement
173
- @query('#tab-nav-left-button') tabNavLeftButton!: HTMLElement
174
- @query('#tab-nav-right-button') tabNavRightButton!: HTMLElement
175
-
176
- private mapping: Properties = {}
177
-
178
- get mappings() {
179
- return this.value?.mappings || []
180
- }
181
-
182
- firstUpdated() {
183
- this.renderRoot.addEventListener('change', this.onValueChange.bind(this))
184
-
185
- this.tabContainer.addEventListener('scroll', () => {
186
- this._onTabScroll()
187
- })
188
- }
189
-
190
- updated(changes: PropertyValues<this>) {
191
- if (changes.has('value')) {
192
- this.onValueChanged()
193
- }
194
- }
195
-
196
- static get scopedElements() {
197
- return {
198
- 'data-binding-mapper': DataBindingMapper
199
- }
200
- }
201
-
202
- render() {
203
- const value = this.value || {
204
- mappings: []
205
- }
206
-
207
- return html`
208
- <fieldset>
209
- <legend>
210
- <ox-title-with-help topic="board-modeller/data-binding" msgid="label.identifier"
211
- >identifier</ox-title-with-help
212
- >
213
- </legend>
214
- <div class="property-grid">
215
- <label> <ox-i18n msgid="label.id">ID</ox-i18n> </label>
216
- <input value-key="id" .value=${value.id || ''} />
217
-
218
- <label> <ox-i18n msgid="label.class">Class</ox-i18n> </label>
219
- <input value-key="class" .value=${value.class || ''} />
220
-
221
- <label> <ox-i18n msgid="label.tag">Tag</ox-i18n> </label>
222
- <input value-key="tag" .value=${value.tag || ''} />
223
-
224
- <label> <ox-i18n msgid="label.template-prefix">Template Prefix</ox-i18n> </label>
225
- <input value-key="templatePrefix" .value=${value.templatePrefix || ''} />
226
-
227
- <input id="checkbox-ndns" type="checkbox" value-key="ndns" .checked=${value.ndns} />
228
- <label for="checkbox-ndns"> <ox-i18n msgid="label.ndns">No Data No Show</ox-i18n> </label>
229
-
230
- <input id="checkbox-sensitive" type="checkbox" value-key="sensitive" .checked=${value.sensitive} />
231
- <label for="checkbox-sensitive">
232
- <ox-i18n msgid="label.intent-sensitive">Intent Sensitive</ox-i18n>
233
- </label>
234
-
235
- <input id="checkbox-persistent" type="checkbox" value-key="persistent" .checked=${value.persistent} />
236
- <label for="checkbox-persistent">
237
- <ox-i18n msgid="label.persistent-data">Persistent Data</ox-i18n>
238
- </label>
239
- </div>
240
- </fieldset>
241
-
242
- <fieldset collapsable ?collapsed=${!this._dataExpanded}>
243
- <legend
244
- @click=${() => {
245
- this._dataExpanded = !this._dataExpanded
246
- }}
247
- >
248
- <ox-title-with-help topic="board-modeller/initial-data" msgid="label.initial-data"
249
- >initial value</ox-title-with-help
250
- >
251
- <md-icon>${this._dataExpanded ? 'expand_less' : 'expand_more'}</md-icon>
252
- </legend>
253
- <ox-input-data value-key="data" .value=${value.data}> </ox-input-data>
254
- </fieldset>
255
-
256
- <fieldset>
257
- <legend>
258
- <ox-title-with-help topic="board-modeller/data-spread" msgid="label.data-spread"
259
- >Data Spread</ox-title-with-help
260
- >
261
- </legend>
262
-
263
- <div id="tab-header">
264
- <md-icon
265
- id="tab-nav-left-button"
266
- @click=${() => {
267
- this._onTabScrollNavLeft()
268
- }}
269
- disabled
270
- >chevron_left</md-icon
271
- >
272
-
273
- <ox-buttons-radio
274
- id="tabs"
275
- .value=${String(this.mappingIndex)}
276
- @change=${(e: Event) => {
277
- e.stopPropagation()
278
- this._setMappingIndex((e.target as any).value)
279
- }}
280
- >
281
- ${this.mappings.map((m: string, i: number) => html` <div data-value=${i} data-mapping>${i + 1}</div> `)}
282
- <div data-value=${this.mappings.length} data-mapping disabled>${this.mappings.length + 1}</div>
283
- </ox-buttons-radio>
284
-
285
- <md-icon
286
- id="tab-nav-right-button"
287
- @click=${(e: Event) => {
288
- this._onTabScrollNavRight()
289
- }}
290
- disabled
291
- >chevron_right</md-icon
292
- >
293
- </div>
294
-
295
- <div binding>
296
- <md-icon style="font-size:19px" @click=${() => this._clearDataBindingMapper()} title="delete current tab"
297
- >delete_forever</md-icon
298
- >
299
- <md-icon @click=${() => this._pasteDataBindingMapper()} title="replace current tab">content_paste</md-icon>
300
- <md-icon style="font-size:17px" @click=${() => this._copyDataBindingMapper()} title="copy current tab"
301
- >content_copy</md-icon
302
- >
303
- </div>
304
-
305
- <data-binding-mapper
306
- @value-change=${(e: CustomEvent) => this._onMappingChanged(e)}
307
- .scene=${this.scene}
308
- .mapping=${(value.mappings && value.mappings[this.mappingIndex]) || {}}
309
- .properties=${PROPS}
310
- >
311
- </data-binding-mapper>
312
- </fieldset>
313
- `
314
- }
315
-
316
- _setMappingIndex(idx: number) {
317
- this.mappingIndex = isNaN(Number(idx)) ? 0 : Number(idx)
318
-
319
- this._onTabScroll()
320
- }
321
-
322
- _clearDataBindingMapper() {
323
- var mappings = [...(this.value?.mappings || [])]
324
- mappings.splice(this.mappingIndex, 1)
325
- this.onAfterValueChange(
326
- 'mappings',
327
- mappings.filter(m => !!m)
328
- )
329
- }
330
-
331
- _copyDataBindingMapper() {
332
- clipboard = JSON.stringify(this.mappings[this.mappingIndex])
333
- }
334
-
335
- async _pasteDataBindingMapper() {
336
- var index = this.mappingIndex
337
- var mappings = [...(this.value?.mappings || [])]
338
- mappings[this.mappingIndex] = JSON.parse(clipboard)
339
-
340
- this.onAfterValueChange('mappings', mappings)
341
-
342
- setTimeout(() => {
343
- this._setMappingIndex(index)
344
- }, 100)
345
- }
346
-
347
- async onValueChanged() {
348
- await this.updateComplete
349
-
350
- if (this._afterRender) {
351
- this._afterRender()
352
- } else {
353
- this._setMappingIndex(0)
354
- }
355
-
356
- this._afterRender = null
357
- }
358
-
359
- onValueChange(e: Event) {
360
- var element = e.target as HTMLElement
361
- var key = element.getAttribute('value-key')
362
-
363
- var value = this.getValueFromEventTarget(element)
364
-
365
- if (!key) {
366
- return
367
- }
368
-
369
- this.value = {
370
- ...this.value,
371
- [key]: value
372
- }
373
-
374
- this.onAfterValueChange(key, value)
375
- }
376
-
377
- get tabContainer() {
378
- return this.tabs
379
- }
380
-
381
- async _onMappingChanged(e: CustomEvent) {
382
- var mapping = (e.target as any).mapping
383
-
384
- /* data spread target의 변경이 있는 경우, target 컴포넌트들의 태그를 블링크 시킨다 */
385
- if (mapping && mapping.target) {
386
- this.scene &&
387
- this.scene.findAll(mapping.target, this.scene.selected && this.scene.selected[0]).forEach((c, i) => {
388
- if (i == 0) c.trigger('decotagreset')
389
- c.trigger('decotag', {})
390
- })
391
- }
392
-
393
- /* mapping의 모든 속성이 편집되면, 모델에 반영한다. */
394
- var mappings = [...(this.value?.mappings || [])]
395
-
396
- if (mapping.target && mapping.property && mapping.rule) {
397
- mappings[this.mappingIndex] = mapping
398
-
399
- var mappingIdx = this.mappingIndex
400
- this._afterRender = () => {
401
- this._setMappingIndex(mappingIdx)
402
- this.tabContainer.scrollLeft = this.tabContainer.scrollWidth
403
- }
404
-
405
- this.dispatchEvent(
406
- new CustomEvent('property-change', {
407
- bubbles: true,
408
- composed: true,
409
- detail: {
410
- mappings: mappings.filter(m => !!m)
411
- }
412
- })
413
- )
414
-
415
- await this.requestUpdate()
416
- } else if (!mapping.target && !mapping.property) {
417
- const { accessor, source } = e.detail?.changed || {}
418
-
419
- // accessor나 source를 입력중인 경우 tabIndex Change 방지
420
- if (!accessor && !source) {
421
- mappings[this.mappingIndex] = null
422
- var nextMappingIdx = Math.max(this.mappingIndex - 1, 0)
423
- this._afterRender = () => {
424
- this._setMappingIndex(nextMappingIdx)
425
- }
426
- this.dispatchEvent(
427
- new CustomEvent('property-change', {
428
- bubbles: true,
429
- composed: true,
430
- detail: {
431
- mappings: mappings.filter(m => !!m)
432
- }
433
- })
434
- )
435
- }
436
- }
437
- }
438
-
439
- _onTabScroll() {
440
- if (this.tabContainer.clientWidth == this.tabContainer.scrollWidth) {
441
- this.tabNavLeftButton.setAttribute('disabled', '')
442
- this.tabNavRightButton.setAttribute('disabled', '')
443
- }
444
- // left-end
445
- else if (this.tabContainer.scrollLeft == 0) {
446
- this.tabNavLeftButton.setAttribute('disabled', '')
447
- this.tabNavRightButton.removeAttribute('disabled')
448
- }
449
- // right-end
450
- else if (this.tabContainer.scrollLeft + this.tabContainer.clientWidth >= this.tabContainer.scrollWidth) {
451
- this.tabNavLeftButton.removeAttribute('disabled')
452
- this.tabNavRightButton.setAttribute('disabled', '')
453
- } else {
454
- this.tabNavLeftButton.removeAttribute('disabled')
455
- this.tabNavRightButton.removeAttribute('disabled')
456
- }
457
- }
458
-
459
- _onTabScrollNavLeft() {
460
- this.tabContainer.style.scrollBehavior = 'smooth'
461
- this.tabContainer.scrollLeft -= this.tabContainer.clientWidth
462
- this.tabContainer.style.scrollBehavior = 'auto'
463
- }
464
-
465
- _onTabScrollNavRight() {
466
- this.tabContainer.style.scrollBehavior = 'smooth'
467
- this.tabContainer.scrollLeft += this.tabContainer.clientWidth
468
- this.tabContainer.style.scrollBehavior = 'auto'
469
- }
470
- }
@@ -1,77 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import '@operato/i18n/ox-i18n.js'
6
- import '@operato/help/ox-title-with-help.js'
7
-
8
- import { css, html } from 'lit'
9
- import { property } from 'lit/decorators.js'
10
-
11
- import { Properties, Scene } from '@hatiolab/things-scene'
12
- import { ScopedElementsMixin } from '@open-wc/scoped-elements'
13
- import { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'
14
-
15
- import { AbstractProperty } from '../abstract-property.js'
16
- import { PropertyAnimations } from './property-animations.js'
17
- import { PropertyEvent } from './property-event.js'
18
- import { PropertyShadow } from './property-shadow.js'
19
-
20
- export class PropertyEffects extends ScopedElementsMixin(AbstractProperty) {
21
- static styles = [
22
- PropertyGridStyles,
23
- css`
24
- :host {
25
- display: flex;
26
- flex-direction: column;
27
- }
28
- `
29
- ]
30
-
31
- @property({ type: Object }) value?: Properties
32
- @property({ type: Object }) scene?: Scene
33
-
34
- firstUpdated() {
35
- this.renderRoot.addEventListener('change', this.onValueChange.bind(this))
36
- }
37
-
38
- static get scopedElements() {
39
- return {
40
- 'property-shadow': PropertyShadow,
41
- 'property-animations': PropertyAnimations,
42
- 'property-event': PropertyEvent
43
- }
44
- }
45
-
46
- render() {
47
- const value = this.value || {}
48
-
49
- return html`
50
- <fieldset>
51
- <legend>
52
- <ox-title-with-help topic="board-modeller/effects/shadow" msgid="label.shadow">shadow</ox-title-with-help>
53
- </legend>
54
-
55
- <property-shadow value-key="shadow" .value=${value.shadow || {}}> </property-shadow>
56
- </fieldset>
57
-
58
- <fieldset>
59
- <legend>
60
- <ox-title-with-help topic="board-modeller/effects/retention" msgid="label.retention"
61
- >retention</ox-title-with-help
62
- >
63
- </legend>
64
-
65
- <div class="property-grid">
66
- <label> <ox-i18n msgid="label.retention">retention</ox-i18n> </label>
67
- <input type="number" value-key="retention" .value=${value.retention} placeholder="ms" />
68
- </div>
69
- </fieldset>
70
-
71
- <property-animations value-key="animation" .scene=${this.scene} .value=${value.animation || {}}>
72
- </property-animations>
73
-
74
- <property-event value-key="event" .scene=${this.scene} .value=${value.event || {}}> </property-event>
75
- `
76
- }
77
- }
@@ -1,155 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import '@operato/input/ox-input-angle.js'
6
- import '@operato/i18n/ox-i18n.js'
7
-
8
- import { css, html, LitElement } from 'lit'
9
- import { property } from 'lit/decorators.js'
10
-
11
- import { Properties, Scene } from '@hatiolab/things-scene'
12
- import { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'
13
-
14
- import { convert } from './value-converter.js'
15
-
16
- /**
17
- * 컴포넌트의 animation 속성을 편집하는 element
18
-
19
- Example:
20
-
21
- <property-animation .value=${animation}>
22
- </property-animation>
23
- */
24
-
25
- export class PropertyAnimation extends LitElement {
26
- static styles = [
27
- PropertyGridStyles,
28
- css`
29
- :host {
30
- display: flex;
31
- }
32
- `
33
- ]
34
-
35
- @property({ type: Object }) value?: Properties
36
- @property({ type: Object }) scene?: Scene
37
-
38
- firstUpdated() {
39
- this.renderRoot.addEventListener('change', this.onValueChange.bind(this))
40
- }
41
-
42
- render() {
43
- const value = this.value || {}
44
-
45
- return html`
46
- <div class="property-grid">
47
- <label>Animation</label>
48
- <select value-key="type" .value=${value.type}>
49
- <option value="">None</option>
50
- <option value="rotation">Rotation</option>
51
- <option value="vibration">Vibration</option>
52
- <option value="heartbeat">Heartbeat</option>
53
- <option value="moving">Moving</option>
54
- <option value="fade">Fade</option>
55
- <option value="outline">Outline</option>
56
- </select>
57
-
58
- <label> <ox-i18n msgid="label.waiting-time">waiting time</ox-i18n> </label>
59
- <input type="number" value-key="delay" .value=${value.delay} placeholder="ms" />
60
-
61
- <label> <ox-i18n msgid="label.duration">duration</ox-i18n> </label>
62
- <input type="number" value-key="duration" .value=${value.duration} placeholder="ms" />
63
-
64
- <label> <ox-i18n msgid="label.animation-interval">interval</ox-i18n> </label>
65
- <input type="number" value-key="interval" .value=${value.interval} placeholder="ms" />
66
-
67
- ${value.type == 'rotation' || value.type == 'vibration'
68
- ? html`
69
- <label> <ox-i18n msgid="label.theta">theta</ox-i18n> </label>
70
- <ox-input-angle value-key="theta" .value=${value.theta}> </ox-input-angle>
71
- `
72
- : html``}
73
- ${value.type == 'heartbeat'
74
- ? html`
75
- <label> <ox-i18n msgid="label.scale">scale</ox-i18n> </label>
76
- <input type="number" value-key="scale" .value=${value.scale} />
77
- `
78
- : html``}
79
- ${value.type == 'moving'
80
- ? html`
81
- <label> <ox-i18n msgid="label.x-axes">X-axes</ox-i18n> </label>
82
- <input type="number" value-key="x" .value=${value.x} />
83
-
84
- <label> <ox-i18n msgid="label.y-axes">Y-axes</ox-i18n> </label>
85
- <input type="number" value-key="y" .value=${value.y} />
86
- `
87
- : html``}
88
- ${value.type == 'fade'
89
- ? html`
90
- <label> <ox-i18n msgid="label.start-alpha">start alpha</ox-i18n> </label>
91
- <input type="number" value-key="startAlpha" .value=${value.startAlpha} />
92
-
93
- <label> <ox-i18n msgid="label.end-alpha">end alpha</ox-i18n> </label>
94
- <input type="number" value-key="endAlpha" .value=${value.endAlpha} />
95
- `
96
- : html``}
97
- ${value.type == 'outline'
98
- ? html`
99
- <label> <ox-i18n msgid="label.target">target</ox-i18n> </label>
100
- <input value-key="rideOn" .value=${value.rideOn || ''} list="target-list" />
101
- <datalist id="target-list">
102
- ${this.scene!.ids.map(info => info.key).map(id => html` <option value=${id}></option> `)}
103
- </datalist>
104
- `
105
- : html``}
106
-
107
- <input id="checkbox-repeat" value-key="repeat" type="checkbox" .checked=${value.repeat} />
108
- <label for="checkbox-repeat" class="checkbox-label"> <ox-i18n msgid="label.repeat">repeat</ox-i18n> </label>
109
-
110
- <input
111
- id="checkbox-autoplay"
112
- value-key="autoplay"
113
- type="checkbox"
114
- .checked=${value.autoplay || (value.autoplay ?? true)}
115
- />
116
- <label for="checkbox-autoplay" class="checkbox-label">
117
- <ox-i18n msgid="label.autoplay">autoplay</ox-i18n>
118
- </label>
119
-
120
- <label>delta</label>
121
- <select value-key="delta" .value=${value.delta}>
122
- <option value="linear">linear</option>
123
- <option value="quad">quad</option>
124
- <option value="circ">circ</option>
125
- <option value="back">back</option>
126
- <option value="bounce">bounce</option>
127
- <option value="elastic">elastic</option>
128
- </select>
129
-
130
- <label>ease</label>
131
- <select value-key="ease" .value=${value.ease}>
132
- <option value="in">in</option>
133
- <option value="out">out</option>
134
- <option value="inout">inout</option>
135
- </select>
136
- </div>
137
- `
138
- }
139
-
140
- onValueChange(e: Event) {
141
- var element = e.target as HTMLElement
142
- var key = element.getAttribute('value-key')
143
-
144
- if (!key) {
145
- return
146
- }
147
-
148
- this.value = {
149
- ...this.value,
150
- [key]: convert(element)
151
- }
152
-
153
- this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
154
- }
155
- }