@operato/scene-manufacturing 8.0.0-beta.1 → 9.0.0-beta.0

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/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export { default as TactTimer } from './tact-timer'
@@ -1,47 +0,0 @@
1
- /**
2
- * 문자열 길이를 늘려주는 함수
3
- *
4
- * @param {String} i
5
- * @param {Number} len
6
- */
7
- function ii(i: string, len?: number) {
8
- var s = i
9
- len = len || 2
10
- while (s.length < len) s = '0' + s
11
- return s
12
- }
13
-
14
- /**
15
- * 시간 표시 포맷을 맞추는 함수
16
- *
17
- * @param {Number} seconds seconds
18
- * @param {string} timeFormat hh:mm:ss
19
- */
20
- export default function formatTime(seconds = 0, timeFormat = '') {
21
- var h = 0,
22
- m = 0,
23
- s = 0
24
- var formatted = ''
25
-
26
- h = Math.floor(seconds / 3600)
27
- formatted = timeFormat.replace(/(^|[^\\])hh+/g, '$1' + ii(h.toString()))
28
- formatted = formatted.replace(/(^|[^\\])h/g, '$1' + h)
29
- if (timeFormat !== formatted) {
30
- timeFormat = formatted
31
- seconds %= 3600
32
- }
33
-
34
- m = Math.floor(seconds / 60)
35
- formatted = timeFormat.replace(/(^|[^\\])mm+/g, '$1' + ii(m.toString()))
36
- formatted = formatted.replace(/(^|[^\\])m/g, '$1' + m)
37
- if (timeFormat !== formatted) {
38
- timeFormat = formatted
39
- seconds %= 60
40
- }
41
-
42
- s = seconds
43
- formatted = timeFormat.replace(/(^|[^\\])ss+/g, '$1' + ii(s.toString()))
44
- formatted = formatted.replace(/(^|[^\\])s/g, '$1' + s)
45
-
46
- return formatted
47
- }
@@ -1,34 +0,0 @@
1
- export const MASK: string = `
2
- <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 95 23">
3
- <defs>
4
- <style>
5
- .cls-1 {
6
- fill: url(#linear-gradient);
7
- }
8
-
9
- .cls-1, .cls-2 {
10
- stroke-width: 0px;
11
- }
12
-
13
- .cls-2 {
14
- fill: {{fillColor}};
15
- }
16
- </style>
17
- <linearGradient id="linear-gradient" x1="47.4" y1="85.6" x2="47.4" y2="95" gradientTransform="translate(0 -74)" gradientUnits="userSpaceOnUse">
18
- <stop offset="0" stop-color="#000" stop-opacity="0"/>
19
- <stop offset=".9" stop-color="#000" stop-opacity=".2"/>
20
- </linearGradient>
21
- </defs>
22
- <rect class="cls-1" x="1.4" y="11.6" width="92.1" height="9.5" rx="2.6" ry="2.6"/>
23
- <path class="cls-2" d="M95,0H0v23h95V0ZM92.5,17.9c0,1.4-1.2,2.6-2.6,2.6H5.1c-1.4,0-2.6-1.2-2.6-2.6V5.1c0-1.4,1.2-2.6,2.6-2.6h84.8c1.4,0,2.6,1.2,2.6,2.6v12.8Z"/>
24
- <path class="cls-2" d="M47.9,3.1c0-.6.7-.6.7-.6v-.7h-2.5v.7s.7,0,.7.6v16.7s0,.7-.7.8v.6h2.5v-.6c-.7-.1-.7-.8-.7-.8V3.1Z"/>
25
- <path class="cls-2" d="M38.6,3.1c0-.6.7-.6.7-.6v-.7h-2.5v.7s.7,0,.7.6v16.7s0,.7-.7.8v.6h2.5v-.6c-.7-.1-.7-.8-.7-.8V3.1Z"/>
26
- <path class="cls-2" d="M29.3,3.1c0-.6.7-.6.7-.6v-.7h-2.5v.7s.7,0,.7.6v16.7s0,.7-.7.8v.6h2.5v-.6c-.7-.1-.7-.8-.7-.8V3.1Z"/>
27
- <path class="cls-2" d="M19.9,3.1c0-.6.7-.6.7-.6v-.7h-2.5v.7s.7,0,.7.6v16.7s0,.7-.7.8v.6h2.5v-.6c-.7-.1-.7-.8-.7-.8V3.1Z"/>
28
- <path class="cls-2" d="M11,3.1c0-.6.7-.6.7-.6v-.7h-2.5v.7s.7,0,.7.6v16.7s0,.7-.7.8v.6h2.5v-.6c-.7-.1-.7-.8-.7-.8V3.1Z"/>
29
- <path class="cls-2" d="M84.9,3.1c0-.6.7-.6.7-.6v-.7h-2.5v.7s.7,0,.7.6v16.7s0,.7-.7.8v.6h2.5v-.6c-.7-.1-.7-.8-.7-.8V3.1Z"/>
30
- <path class="cls-2" d="M75.6,3.1c0-.6.7-.6.7-.6v-.7h-2.5v.7s.7,0,.7.6v16.7s0,.7-.7.8v.6h2.5v-.6c-.7-.1-.7-.8-.7-.8V3.1Z"/>
31
- <path class="cls-2" d="M66.4,3.1c0-.6.7-.6.7-.6v-.7h-2.5v.7s.7,0,.7.6v16.7s0,.7-.7.8v.6h2.5v-.6c-.7-.1-.7-.8-.7-.8V3.1Z"/>
32
- <path class="cls-2" d="M57.2,3.1c0-.6.7-.6.7-.6v-.7h-2.5v.7s.7,0,.7.6v16.7s0,.7-.7.8v.6h2.5v-.6c-.7-.1-.7-.8-.7-.8V3.1Z"/>
33
- </svg>
34
- `
package/src/tact-timer.ts DELETED
@@ -1,322 +0,0 @@
1
- import { Component, ComponentNature, Properties, RectPath, Shape } from '@hatiolab/things-scene'
2
- import format from './libs/format'
3
- import { MASK } from './tact-timer-mask'
4
-
5
- const NATURE: ComponentNature = {
6
- mutable: false,
7
- resizable: true,
8
- rotatable: true,
9
- properties: [
10
- {
11
- type: 'string',
12
- label: 'start-time',
13
- name: 'startTime',
14
- placeholder: 'YYYYMMDDhhmmss'
15
- },
16
- {
17
- type: 'string',
18
- label: 'end-time',
19
- name: 'endTime',
20
- placeholder: 'YYYYMMDDhhmmss'
21
- },
22
- {
23
- type: 'string',
24
- label: 'format',
25
- name: 'format',
26
- placeholder: 'hh:mm:ss'
27
- },
28
- {
29
- type: 'select',
30
- label: 'progress-direction',
31
- name: 'progressDirection',
32
- property: {
33
- options: ['', 'increase', 'decrease']
34
- }
35
- },
36
- {
37
- type: 'color',
38
- label: 'tact-timer-mask-color',
39
- name: 'maskColor'
40
- },
41
- {
42
- type: 'color',
43
- label: 'before-due-progress-color',
44
- name: 'beforeDueProgressColor'
45
- },
46
- {
47
- type: 'color',
48
- label: 'over-due-progress-color',
49
- name: 'overDueProgressColor'
50
- },
51
- {
52
- type: 'color',
53
- label: 'before-due-font-color',
54
- name: 'beforeDueFontColor'
55
- },
56
- {
57
- type: 'color',
58
- label: 'over-due-font-color',
59
- name: 'overDueFontColor'
60
- },
61
- {
62
- type: 'color',
63
- label: 'under-threshold-color',
64
- name: 'underThresholdColor'
65
- },
66
- {
67
- type: 'number',
68
- label: 'progress-threshold',
69
- name: 'progressThreshold',
70
- placeholder: '%'
71
- },
72
- {
73
- type: 'number',
74
- label: 'round',
75
- name: 'round'
76
- },
77
- {
78
- type: 'boolean',
79
- label: 'auto-start',
80
- name: 'autoStart'
81
- },
82
- {
83
- type: 'boolean',
84
- label: 'show-progress',
85
- name: 'showProgress'
86
- },
87
- {
88
- type: 'boolean',
89
- label: 'show-timer',
90
- name: 'showTimer'
91
- }
92
- ],
93
- help: 'scene/component/manufacturing/tact-timer'
94
- }
95
-
96
- export default class TactTimer extends RectPath(Shape) {
97
- private _start: number = 0
98
- private _due: number = 0
99
- private imageElement?: HTMLImageElement
100
-
101
- get nature() {
102
- return NATURE
103
- }
104
-
105
- ready() {
106
- if (!this.app.isViewMode) {
107
- return
108
- }
109
-
110
- const { autoStart, started } = this.state
111
-
112
- if (autoStart || started) {
113
- this.setState('started', true)
114
-
115
- this.start()
116
- }
117
- }
118
-
119
- start() {
120
- const { startTime, endTime, hidden } = this.state
121
- const start = this.parseTime(startTime)
122
- const end = this.parseTime(endTime)
123
-
124
- if (start && end && !hidden) {
125
- this._due = end.getTime()
126
- this._start = start.getTime()
127
- this.counting()
128
- }
129
- }
130
-
131
- stop() {
132
- this.started = false
133
- }
134
-
135
- onchange(after: Properties) {
136
- if ('startTime' in after || 'endTime' in after || 'hidden' in after) {
137
- this.start()
138
- }
139
-
140
- if ('maskColor' in after) {
141
- delete this.imageElement
142
- }
143
- }
144
-
145
- getImageElement(): HTMLImageElement | undefined {
146
- if (!this.imageElement) {
147
- const { maskColor = 'black' } = this.state
148
-
149
- this.imageElement = new Image()
150
- this.imageElement.src =
151
- 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(MASK.replace(/{{fillColor}}/g, maskColor))
152
- }
153
-
154
- return this.imageElement
155
- }
156
-
157
- counting() {
158
- const { hidden, started } = this.state
159
- if (this.disposed || hidden || !started) {
160
- return
161
- }
162
-
163
- requestAnimationFrame(() => {
164
- const { showTimer, beforeDueFontColor, overDueFontColor, fontColor } = this.state
165
- const countdown = this.countdown
166
-
167
- this.setState('fontColor', (this.countdown > 0 ? beforeDueFontColor : overDueFontColor) || fontColor)
168
-
169
- if (showTimer) {
170
- const text = format(Math.abs(countdown), this.getState('format'))
171
- this.text = text
172
- } else {
173
- this.text = ''
174
- }
175
-
176
- this.setState('data', this.countdown)
177
-
178
- setTimeout(() => {
179
- this.counting()
180
- }, 1000)
181
- })
182
- }
183
-
184
- render(context: CanvasRenderingContext2D) {
185
- var {
186
- top,
187
- left,
188
- height,
189
- width,
190
- round = 0,
191
- fontColor,
192
- maskColor,
193
- beforeDueFontColor,
194
- overDueFontColor,
195
- beforeDueProgressColor = 'transparent',
196
- overDueProgressColor = 'transparent',
197
- underThresholdColor = 'transparent',
198
- progressDirection = 'increase',
199
- progressThreshold = 0,
200
- showProgress
201
- } = this.state
202
-
203
- const increase = this.countdown > 0
204
- const totalDuration = (this._due - this._start) / 1000
205
- const underThreshold = this.countdown / totalDuration < progressThreshold / 100
206
-
207
- // progress의 색상
208
- context.beginPath()
209
- context.roundRect(left, top, width, height, round)
210
- context.clip()
211
- this.drawFill(context)
212
-
213
- // value의 색상
214
- context.beginPath()
215
-
216
- if (!showProgress) {
217
- return
218
- }
219
-
220
- var progress = Math.abs((this.countdown / totalDuration) * 100)
221
-
222
- if (!isNaN(progress)) {
223
- progress = width - (width * progress) / 100
224
- progress = Math.max(Math.min(progress, width), 0)
225
-
226
- if (progressDirection == 'increase') {
227
- context.rect(left, top, progress, height)
228
- } else {
229
- context.rect(left + progress, top, width - progress, height)
230
- }
231
-
232
- context.fillStyle = increase
233
- ? underThreshold
234
- ? underThresholdColor
235
- : beforeDueProgressColor
236
- : overDueProgressColor
237
- context.fill()
238
-
239
- context.beginPath()
240
- }
241
-
242
- const image = this.getImageElement()
243
- this.drawImage(context, image!, left - 2, top - 2, width + 4, height + 4)
244
-
245
- context.roundRect(left, top, width, height, round)
246
-
247
- this.setState('fontColor', (increase ? beforeDueFontColor : overDueFontColor) || fontColor)
248
- }
249
-
250
- postrender(context: CanvasRenderingContext2D) {
251
- this.drawStroke(context)
252
- this.drawText(context)
253
- }
254
-
255
- parseTime(timeString: string): Date | undefined {
256
- if (!timeString || timeString.length !== 14) {
257
- return undefined
258
- }
259
- const year = parseInt(timeString.slice(0, 4), 10)
260
- const month = parseInt(timeString.slice(4, 6), 10) - 1
261
- const day = parseInt(timeString.slice(6, 8), 10)
262
- const hour = parseInt(timeString.slice(8, 10), 10)
263
- const minute = parseInt(timeString.slice(10, 12), 10)
264
- const second = parseInt(timeString.slice(12, 14), 10)
265
-
266
- return new Date(year, month, day, hour, minute, second)
267
- }
268
-
269
- get countdown(): number {
270
- const due = this._due || 0
271
- const now = Date.now()
272
-
273
- return Math.round((due - now) / 1000)
274
- }
275
-
276
- get value() {
277
- const { startTime, endTime } = this.state
278
- return [startTime, endTime]
279
- }
280
-
281
- set value(v) {
282
- if (v instanceof Array) {
283
- const [startTime, endTime] = v
284
- this.setState({
285
- startTime,
286
- endTime
287
- })
288
- } else if (typeof v == 'object') {
289
- const { startTime, endTime } = v
290
- this.setState({
291
- startTime,
292
- endTime
293
- })
294
- } else if (typeof v == 'string') {
295
- const [startTime, endTime] = (v as string).split(/[-+/%$#_,]+/)
296
- this.setState({
297
- startTime,
298
- endTime
299
- })
300
- } else {
301
- this.setState({
302
- startTime: undefined,
303
- endTime: undefined
304
- })
305
- }
306
- }
307
-
308
- get started() {
309
- return this.getState('started')
310
- }
311
-
312
- set started(started) {
313
- if (this.started !== started) {
314
- this.setState('started', started)
315
- if (started) {
316
- this.start()
317
- }
318
- }
319
- }
320
- }
321
-
322
- Component.register('tact-timer', TactTimer)
@@ -1,3 +0,0 @@
1
- import tactTimer from './tact-timer'
2
-
3
- export default [tactTimer]
@@ -1,27 +0,0 @@
1
- const icon = new URL('../../icons/tact-timer.png', import.meta.url).href
2
-
3
- export default {
4
- type: 'tact-timer',
5
- description: 'tact timer',
6
- group: 'etc' /* line|shape|textAndMedia|chartAndGauge|table|container|dataSource|IoT|3D|warehouse|form|etc */,
7
- icon,
8
- model: {
9
- type: 'tact-timer',
10
- left: 100,
11
- top: 100,
12
- width: 200,
13
- height: 40,
14
- fontSize: 80,
15
- lineWidth: 1,
16
- round: 10,
17
- showProgress: true,
18
- showTimer: true,
19
- progressDirection: 'decrease',
20
- increaseProgressColor: 'green',
21
- decreaseProgressColor: 'red',
22
- increaseFontColor: 'navy',
23
- decreaseFontColor: 'orange',
24
- underThresholdColor: 'yellow',
25
- progressThreshold: 30
26
- }
27
- }
package/tsconfig.json DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es2018",
4
- "module": "esnext",
5
- "moduleResolution": "node",
6
- "noEmitOnError": true,
7
- "lib": ["es2019", "dom"],
8
- "strict": true,
9
- "esModuleInterop": false,
10
- "allowJs": true,
11
- "allowSyntheticDefaultImports": true,
12
- "experimentalDecorators": true,
13
- "importHelpers": true,
14
- "outDir": "dist",
15
- "sourceMap": true,
16
- "inlineSources": true,
17
- "rootDir": "src",
18
- "declaration": true,
19
- "incremental": true
20
- },
21
- "include": ["**/*.ts", "*.d.ts"]
22
- }