@operato/scene-news-ticker 0.1.5

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 (46) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +45 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +5 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/news-ticker-element.d.ts +16 -0
  8. package/dist/news-ticker-element.js +80 -0
  9. package/dist/news-ticker-element.js.map +1 -0
  10. package/dist/news-ticker-horizontal.d.ts +17 -0
  11. package/dist/news-ticker-horizontal.js +129 -0
  12. package/dist/news-ticker-horizontal.js.map +1 -0
  13. package/dist/news-ticker-vertical.d.ts +22 -0
  14. package/dist/news-ticker-vertical.js +126 -0
  15. package/dist/news-ticker-vertical.js.map +1 -0
  16. package/dist/news-ticker.d.ts +39 -0
  17. package/dist/news-ticker.js +97 -0
  18. package/dist/news-ticker.js.map +1 -0
  19. package/helps/scene/component/news-ticker.ko.md +27 -0
  20. package/helps/scene/component/news-ticker.md +27 -0
  21. package/helps/scene/component/news-ticker.zh.md +27 -0
  22. package/helps/scene/images/news_ticker_1.png +0 -0
  23. package/helps/scene/images/news_ticker_2.png +0 -0
  24. package/helps/scene/images/news_ticker_3.png +0 -0
  25. package/helps/scene/images/news_ticker_video_1.gif +0 -0
  26. package/helps/scene/images/news_ticker_video_2.gif +0 -0
  27. package/icons/icon-news-ticker.png +0 -0
  28. package/logs/.08636eb59927f12972f6774f5947c8507b3564c2-audit.json +20 -0
  29. package/logs/.5e5d741d8b7784a2fbad65eedc0fd46946aaf6f2-audit.json +20 -0
  30. package/logs/application-2022-02-10-10.log +37 -0
  31. package/logs/application-2022-02-10-11.log +8 -0
  32. package/logs/connections-2022-02-10-10.log +288 -0
  33. package/logs/connections-2022-02-10-11.log +64 -0
  34. package/package.json +63 -0
  35. package/src/index.ts +5 -0
  36. package/src/news-ticker-element.ts +51 -0
  37. package/src/news-ticker-horizontal.ts +128 -0
  38. package/src/news-ticker-vertical.ts +125 -0
  39. package/src/news-ticker.ts +128 -0
  40. package/test/basic-test.html +81 -0
  41. package/test/index.html +22 -0
  42. package/test/unit/test-news-ticker.js +33 -0
  43. package/test/unit/util.js +22 -0
  44. package/things-scene.config.js +24 -0
  45. package/tsconfig.json +22 -0
  46. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,51 @@
1
+ /*
2
+ * Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import './news-ticker-horizontal'
6
+ import './news-ticker-vertical'
7
+
8
+ import { html, LitElement } from 'lit'
9
+ import { customElement, property } from 'lit/decorators.js'
10
+
11
+ @customElement('ox-news-ticker')
12
+ export default class ThingsNewsTicker extends LitElement {
13
+ @property({ type: String }) textData: string = ''
14
+ @property({ type: String }) fontFamily: string = ''
15
+ @property({ type: String }) fontColor: string = ''
16
+ @property({ type: String }) fontSize: string = ''
17
+ @property({ type: String }) textAlign: string = ''
18
+ @property({ type: Boolean }) isReverse: boolean = false
19
+ @property({ type: Boolean }) isTextOverflowed: boolean = false
20
+ @property({ type: String }) direction?: 'vertical' | 'horizontal'
21
+ @property({ type: Number }) duration: number = 30000
22
+
23
+ render() {
24
+ return html`
25
+ ${this.direction == 'vertical'
26
+ ? html`
27
+ <ox-news-ticker-vertical
28
+ .duration=${this.duration}
29
+ .isReverse=${this.isReverse}
30
+ .isTextOverflowed=${this.isTextOverflowed}
31
+ .textData=${this.textData}
32
+ ></ox-news-ticker-vertical>
33
+ `
34
+ : html`
35
+ <ox-news-ticker-horizontal
36
+ .duration=${this.duration}
37
+ .isReverse=${this.isReverse}
38
+ .isTextOverflowed=${this.isTextOverflowed}
39
+ .textData=${this.textData}
40
+ ></ox-news-ticker-horizontal>
41
+ `}
42
+ `
43
+ }
44
+
45
+ updated() {
46
+ this.style.setProperty('--ox-news-ticker-font-family', this.fontFamily)
47
+ this.style.setProperty('--ox-news-ticker-font-size', this.fontSize)
48
+ this.style.setProperty('--ox-news-ticker-font-color', this.fontColor)
49
+ this.style.setProperty('--ox-news-ticker-text-align', this.textAlign)
50
+ }
51
+ }
@@ -0,0 +1,128 @@
1
+ /*
2
+ * Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import { css, html, LitElement, PropertyValues } from 'lit'
6
+ import { customElement, property, query } from 'lit/decorators.js'
7
+
8
+ @customElement('ox-news-ticker-horizontal')
9
+ export default class ThingsNewsTickerHorizontal extends LitElement {
10
+ static styles = [
11
+ css`
12
+ :host * {
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ :host .ticker-wrap {
17
+ position: absolute;
18
+ bottom: 0;
19
+ width: 100%;
20
+ overflow: hidden;
21
+ height: 100%;
22
+ background-color: rgba(#000, 0.9);
23
+ padding-left: var(--ox-news-ticker-wrapper-padding-left);
24
+ box-sizing: content-box;
25
+ font-family: var(--ox-news-ticker-font-family);
26
+ }
27
+
28
+ :host .ticker-wrap .ticker {
29
+ display: inline-block;
30
+ min-width: 100%;
31
+ text-align: var(--ox-news-ticker-text-align);
32
+ height: 4rem;
33
+ line-height: 4rem;
34
+ white-space: nowrap;
35
+ padding-right: var(--ox-news-ticker-container-padding-right);
36
+ box-sizing: content-box;
37
+ }
38
+
39
+ :host .ticker-wrap .ticker__item {
40
+ display: inline-block;
41
+ font-size: var(--ox-news-ticker-font-size);
42
+ color: var(--ox-news-ticker-font-color);
43
+ }
44
+
45
+ :host body {
46
+ padding-bottom: 5rem;
47
+ }
48
+ :host h1,
49
+ :host h2,
50
+ :host p {
51
+ padding: 0 5%;
52
+ }
53
+ `
54
+ ]
55
+
56
+ @property({ type: Boolean }) isReverse: boolean = false
57
+ @property({ type: Boolean }) isTextOverflowed?: boolean
58
+ @property({ type: Number }) duration: number = 30000
59
+ @property({ type: String }) textData: string = ''
60
+
61
+ private _anim?: Animation
62
+
63
+ @query('.ticker-wrap .ticker') animationTargetEl!: Element
64
+
65
+ get currentAnimation() {
66
+ return this._anim
67
+ }
68
+
69
+ set currentAnimation(anim) {
70
+ this._anim = anim
71
+ }
72
+
73
+ get textLines() {
74
+ return this.textData.split('\n')
75
+ }
76
+
77
+ render() {
78
+ return html`
79
+ <div class="ticker-wrap">
80
+ <div class="ticker">${this.textLines.map(t => html` <div class="ticker__item">${t}</div> `)}</div>
81
+ </div>
82
+ `
83
+ }
84
+
85
+ updated(changes: PropertyValues<this>) {
86
+ if (
87
+ changes.has('textData') ||
88
+ changes.has('duration') ||
89
+ changes.has('isReverse') ||
90
+ changes.has('isTextOverflowed')
91
+ ) {
92
+ this.style.setProperty('--ox-news-ticker-wrapper-padding-left', this.isTextOverflowed ? '100%' : '0')
93
+ this.style.setProperty('--ox-news-ticker-container-padding-right', this.isTextOverflowed ? '100%' : '0')
94
+
95
+ this.startAnimation()
96
+ }
97
+ }
98
+
99
+ startAnimation() {
100
+ this.stopAnimation()
101
+
102
+ if (!this.isTextOverflowed) return
103
+
104
+ this.currentAnimation = this.animationTargetEl.animate(
105
+ [
106
+ {
107
+ transform: 'translate3d(0, 0, 0)',
108
+ visibility: 'hidden'
109
+ },
110
+ {
111
+ transform: 'translate3d(-100%, 0, 0)',
112
+ visibility: 'visible'
113
+ }
114
+ ],
115
+ {
116
+ duration: this.duration,
117
+ iterations: Infinity,
118
+ direction: this.isReverse ? 'reverse' : 'normal'
119
+ }
120
+ )
121
+ }
122
+
123
+ stopAnimation() {
124
+ if (this.currentAnimation) {
125
+ this.currentAnimation.cancel()
126
+ }
127
+ }
128
+ }
@@ -0,0 +1,125 @@
1
+ /*
2
+ * Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import 'web-animations-js'
6
+
7
+ import { css, html, LitElement, PropertyValues } from 'lit'
8
+ import { customElement, property, query } from 'lit/decorators.js'
9
+
10
+ const CUBIC_BEZIER_EASING = 'cubic-bezier(1, 0, 0.5, 0)'
11
+
12
+ @customElement('ox-news-ticker-vertical')
13
+ export default class ThingsNewsTickerVertical extends LitElement {
14
+ static styles = [
15
+ css`
16
+ :host {
17
+ display: block;
18
+ overflow: hidden;
19
+ height: 100%;
20
+ width: 100%;
21
+ box-sizing: border-box;
22
+ }
23
+
24
+ ul {
25
+ margin: 0;
26
+ padding: 0;
27
+ list-style: none;
28
+ white-space: nowrap;
29
+ }
30
+
31
+ #news_ticker {
32
+ width: 100%;
33
+ height: 100%;
34
+ overflow: hidden;
35
+ position: relative;
36
+ }
37
+
38
+ li {
39
+ display: flex;
40
+ height: 100%;
41
+ align-items: center;
42
+ overflow: hidden;
43
+ text-align: var(--ox-news-ticker-text-align, left);
44
+ }
45
+
46
+ #news_ticker a {
47
+ width: 100%;
48
+ line-height: normal;
49
+ color: var(--ox-news-ticker-font-color, black);
50
+ text-decoration: none;
51
+ font-size: var(--ox-news-ticker-font-size, 13px);
52
+ }
53
+ `
54
+ ]
55
+
56
+ @property({ type: Boolean }) isReverse: boolean = false
57
+ @property({ type: Number }) duration: number = 30000
58
+ @property({ type: String }) textData: string = ''
59
+
60
+ private _anim?: Animation
61
+
62
+ @query('#news_ticker > ul') animationTargetEl!: Element
63
+
64
+ get currentAnimation() {
65
+ return this._anim
66
+ }
67
+
68
+ set currentAnimation(anim) {
69
+ this._anim = anim
70
+ }
71
+
72
+ get textLines() {
73
+ return this.textData.split('\n')
74
+ }
75
+
76
+ render() {
77
+ return html`
78
+ <div id="news_ticker">
79
+ <ul>
80
+ ${this.textLines.map(t => html` <li><a href="#">${t}</a></li> `)}
81
+ </ul>
82
+ </div>
83
+ `
84
+ }
85
+
86
+ updated(changes: PropertyValues<this>) {
87
+ if (changes.has('textData') || changes.has('duration') || changes.has('isReverse')) {
88
+ this.startAnimation()
89
+ }
90
+ }
91
+
92
+ startAnimation() {
93
+ this.stopAnimation()
94
+
95
+ var frames = this.createAnimationFrames()
96
+ this.currentAnimation = this.animationTargetEl.animate(frames, {
97
+ duration: this.textLines.length * this.duration,
98
+ iterations: Infinity,
99
+ direction: this.isReverse ? 'reverse' : 'normal'
100
+ })
101
+ }
102
+
103
+ stopAnimation() {
104
+ if (this.currentAnimation) this.currentAnimation.cancel()
105
+ }
106
+
107
+ createAnimationFrames() {
108
+ var textLinesLength = this.textLines.length
109
+ var frames = this.textLines.map((t, i) => {
110
+ return {
111
+ transform: `translateY(${-(i / textLinesLength) * 100}%)`,
112
+ offset: (1 / textLinesLength) * i,
113
+ easing: CUBIC_BEZIER_EASING
114
+ }
115
+ })
116
+
117
+ frames.push({
118
+ transform: `translateY(0)`,
119
+ offset: 1,
120
+ easing: CUBIC_BEZIER_EASING
121
+ })
122
+
123
+ return frames
124
+ }
125
+ }
@@ -0,0 +1,128 @@
1
+ /*
2
+ * Copyright © 2017 HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import './news-ticker-element'
6
+
7
+ import { Component, error, HTMLOverlayElement } from '@hatiolab/things-scene'
8
+
9
+ import ThingsNewsTicker from './news-ticker-element'
10
+
11
+ const NATURE = {
12
+ mutable: false,
13
+ resizable: true,
14
+ rotatable: true,
15
+ properties: [
16
+ {
17
+ type: 'select',
18
+ label: 'direction',
19
+ name: 'direction',
20
+ property: {
21
+ options: [
22
+ {
23
+ display: 'horizontal',
24
+ value: 'horizontal'
25
+ },
26
+ {
27
+ display: 'vertical',
28
+ value: 'vertical'
29
+ }
30
+ ]
31
+ }
32
+ },
33
+ {
34
+ type: 'checkbox',
35
+ label: 'reverse',
36
+ name: 'reverse'
37
+ },
38
+ {
39
+ type: 'number',
40
+ label: 'duration',
41
+ name: 'duration',
42
+ placeholder: 'seconds'
43
+ }
44
+ ],
45
+ help: 'scene/component/news-ticker'
46
+ }
47
+
48
+ export default class NewsTicker extends HTMLOverlayElement {
49
+ get nature() {
50
+ return NATURE
51
+ }
52
+
53
+ get hasTextProperty() {
54
+ return true
55
+ }
56
+
57
+ get tagName() {
58
+ return 'ox-news-ticker'
59
+ }
60
+
61
+ createElement() {
62
+ super.createElement()
63
+
64
+ this.setState('text', '#{data}')
65
+
66
+ var element = this.element
67
+
68
+ element.style.overflow = 'hidden'
69
+ }
70
+
71
+ /* component.property => element.property */
72
+ setElementProperties(element: HTMLElement) {
73
+ try {
74
+ var {
75
+ direction = 'horizontal',
76
+ reverse,
77
+ textAlign,
78
+ fontColor = 'black',
79
+ fontSize = 13,
80
+ font,
81
+ duration = 30
82
+ } = this.state
83
+
84
+ var text = this.text
85
+
86
+ var isReverse = reverse
87
+ var isTextOverflowed = this.isTextOverflowed
88
+
89
+ var newsTicker = element as ThingsNewsTicker
90
+
91
+ newsTicker.direction = direction
92
+ newsTicker.duration = duration * 1000
93
+ newsTicker.fontColor = fontColor
94
+ newsTicker.fontFamily = font
95
+ newsTicker.fontSize = `${fontSize}px`
96
+ newsTicker.textAlign = textAlign
97
+ newsTicker.isReverse = isReverse
98
+ newsTicker.isTextOverflowed = isTextOverflowed
99
+ newsTicker.textData = text
100
+ } catch (e) {
101
+ error(e)
102
+ }
103
+ }
104
+
105
+ get isTextOverflowed() {
106
+ var { width } = this.bounds
107
+ var span = document.createElement('span')
108
+
109
+ // @ts-ignore
110
+ span.style.font = this.font
111
+ span.style.position = 'fixed'
112
+ span.style.left = '-100%'
113
+ span.style.visibility = 'none'
114
+
115
+ span.textContent = this.text
116
+
117
+ document.body.appendChild(span)
118
+
119
+ var textBounds = span.getBoundingClientRect()
120
+ var isOverflowed = width < textBounds.width
121
+
122
+ document.body.removeChild(span)
123
+
124
+ return isOverflowed
125
+ }
126
+ }
127
+
128
+ Component.register('news-ticker', NewsTicker)
@@ -0,0 +1,81 @@
1
+ <!DOCTYPE html>
2
+ <!--
3
+ @license
4
+ Copyright © 2017 HatioLab Inc. All rights reserved.
5
+ -->
6
+ <html>
7
+ <head>
8
+ <meta charset="utf-8" />
9
+ <meta
10
+ name="viewport"
11
+ content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"
12
+ />
13
+
14
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
15
+ <script src="../../web-component-tester/browser.js"></script>
16
+
17
+ <!-- Step 1: import the element to test -->
18
+ <link rel="import" href="../things-scene-news-ticker.html" />
19
+ </head>
20
+ <body>
21
+ <!-- You can use the document as a place to set up your fixtures. -->
22
+ <test-fixture id="things-scene-news-ticker-fixture">
23
+ <template>
24
+ <things-scene-news-ticker>
25
+ <h2>things-scene-news-ticker</h2>
26
+ </things-scene-news-ticker>
27
+ </template>
28
+ </test-fixture>
29
+
30
+ <script>
31
+ suite('<things-scene-news-ticker>', function() {
32
+ var myEl
33
+
34
+ setup(function() {
35
+ myEl = fixture('things-scene-news-ticker-fixture')
36
+ })
37
+
38
+ test('defines the "author" property', function() {
39
+ assert.equal(myEl.author.name, 'Dimitri Glazkov')
40
+ assert.equal(
41
+ myEl.author.image,
42
+ 'http://addyosmani.com/blog/wp-content/uploads/2013/04/unicorn.jpg'
43
+ )
44
+ })
45
+
46
+ test('says hello', function() {
47
+ assert.equal(
48
+ myEl.sayHello(),
49
+ 'things-scene-news-ticker says, Hello World!'
50
+ )
51
+
52
+ var greetings = myEl.sayHello('greetings Earthlings')
53
+ assert.equal(
54
+ greetings,
55
+ 'things-scene-news-ticker says, greetings Earthlings'
56
+ )
57
+ })
58
+
59
+ test('fires lasers', function(done) {
60
+ myEl.addEventListener('things-scene-news-ticker-lasers', function(
61
+ event
62
+ ) {
63
+ assert.equal(event.detail.sound, 'Pew pew!')
64
+ done()
65
+ })
66
+ myEl.fireLasers()
67
+ })
68
+
69
+ test('distributed children', function() {
70
+ var els = myEl.getContentChildren()
71
+ assert.equal(els.length, 1, 'one distributed node')
72
+ assert.equal(
73
+ els[0],
74
+ myEl.querySelector('h2'),
75
+ 'content distributed correctly'
76
+ )
77
+ })
78
+ })
79
+ </script>
80
+ </body>
81
+ </html>
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+ <!--
3
+ @license
4
+ Copyright © 2017 HatioLab Inc. All rights reserved.
5
+ -->
6
+ <html><head>
7
+ <meta charset="utf-8">
8
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
9
+
10
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
11
+ <script src="../../web-component-tester/browser.js"></script>
12
+ </head>
13
+ <body>
14
+ <script>
15
+ // Load and run all tests (.html, .js):
16
+ WCT.loadSuites([
17
+ 'basic-test.html',
18
+ 'basic-test.html?dom=shadow'
19
+ ]);
20
+ </script>
21
+
22
+ </body></html>
@@ -0,0 +1,33 @@
1
+ /*
2
+ * Copyright © 2017 HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import './util'
6
+
7
+ import { expect } from 'chai'
8
+
9
+ import '../../bower_components/things-scene-core/things-scene-min'
10
+ import { NewsTicker } from '../../src/index'
11
+
12
+ describe('news-ticker', function() {
13
+ var board
14
+
15
+ beforeEach(function() {
16
+ board = scene.create({
17
+ model: {
18
+ components: [
19
+ {
20
+ id: 'news-ticker',
21
+ type: 'news-ticker'
22
+ }
23
+ ]
24
+ }
25
+ })
26
+ })
27
+
28
+ it('component should be found by its id.', function() {
29
+ var component = board.findById('news-ticker')
30
+
31
+ expect(!!component).not.to.equal(false)
32
+ })
33
+ })
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright © 2017 HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ var noop = () => {}
6
+
7
+ global.Canvas = require('canvas');
8
+
9
+ Canvas.prototype.setAttribute = noop;
10
+ Canvas.prototype.style = {};
11
+
12
+ global.Image = Canvas.Image;
13
+ global.screen = {
14
+ width: 1280,
15
+ height: 800
16
+ };
17
+
18
+ global.window = global;
19
+
20
+ global.addEventListener = noop;
21
+ global.location = {};
22
+ global.getComputedStyle = noop;
@@ -0,0 +1,24 @@
1
+ const icon = new URL('./icons/icon-news-ticker.png', import.meta.url).href
2
+
3
+ var templates = [
4
+ {
5
+ type: 'news-ticker',
6
+ description: 'news-ticker',
7
+ group: 'etc',
8
+ /* line|shape|textAndMedia|chartAndGauge|table|container|dataSource|IoT|3D|warehouse|form|etc */
9
+ icon,
10
+ model: {
11
+ type: 'news-ticker',
12
+ left: 10,
13
+ top: 10,
14
+ width: 300,
15
+ height: 50,
16
+ duration: 5,
17
+ text: '#{data}'
18
+ }
19
+ }
20
+ ]
21
+
22
+ export default {
23
+ templates
24
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2018",
4
+ "module": "esnext",
5
+ "moduleResolution": "node",
6
+ "noEmitOnError": true,
7
+ "lib": ["es2017", "dom"],
8
+ "strict": true,
9
+ "esModuleInterop": false,
10
+ "allowSyntheticDefaultImports": true,
11
+ "experimentalDecorators": true,
12
+ "importHelpers": true,
13
+ "outDir": "dist",
14
+ "sourceMap": true,
15
+ "inlineSources": true,
16
+ "rootDir": "src",
17
+ "declaration": true,
18
+ "incremental": true,
19
+ "types": ["node"]
20
+ },
21
+ "include": ["**/*.ts", "*.d.ts"]
22
+ }