rails_design 0.0.1

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 (123) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +18 -0
  4. data/Rakefile +18 -0
  5. data/app/assets/images/image-square.png +0 -0
  6. data/app/assets/images/logo.png +0 -0
  7. data/app/assets/javascripts/default_form/datetime.js +31 -0
  8. data/app/assets/javascripts/default_form/default_valid.js +101 -0
  9. data/app/assets/javascripts/default_form/field.js +33 -0
  10. data/app/assets/javascripts/default_form/index.js +9 -0
  11. data/app/assets/javascripts/default_form/valid_weui.js +17 -0
  12. data/app/assets/javascripts/rails_design/attachment.js +295 -0
  13. data/app/assets/javascripts/rails_design/cable.js +3 -0
  14. data/app/assets/javascripts/rails_design/dataset.js +39 -0
  15. data/app/assets/javascripts/rails_design/index.js +4 -0
  16. data/app/assets/javascripts/rails_design/stimulus.js +19 -0
  17. data/app/assets/javascripts/rails_design/turbo.js +35 -0
  18. data/app/assets/javascripts/stimulus_com/checkbox.js +77 -0
  19. data/app/assets/javascripts/stimulus_com/choice.js +18 -0
  20. data/app/assets/javascripts/stimulus_com/common.js +52 -0
  21. data/app/assets/javascripts/stimulus_com/count_down.js +27 -0
  22. data/app/assets/javascripts/stimulus_com/former.js +26 -0
  23. data/app/assets/javascripts/stimulus_com/hover.js +40 -0
  24. data/app/assets/javascripts/stimulus_com/index.js +58 -0
  25. data/app/assets/javascripts/stimulus_com/input.js +36 -0
  26. data/app/assets/javascripts/stimulus_com/menu.js +34 -0
  27. data/app/assets/javascripts/stimulus_com/modal.js +85 -0
  28. data/app/assets/javascripts/stimulus_com/modal_show.js +16 -0
  29. data/app/assets/javascripts/stimulus_com/navbar.js +11 -0
  30. data/app/assets/javascripts/stimulus_com/notice.js +10 -0
  31. data/app/assets/javascripts/stimulus_com/picture.js +85 -0
  32. data/app/assets/javascripts/stimulus_com/show.js +26 -0
  33. data/app/assets/javascripts/stimulus_com/showcase.js +34 -0
  34. data/app/assets/javascripts/stimulus_com/slide.js +188 -0
  35. data/app/assets/javascripts/stimulus_com/slide_y.js +189 -0
  36. data/app/assets/javascripts/stimulus_com/sortable.js +41 -0
  37. data/app/assets/javascripts/stimulus_com/sticky.js +11 -0
  38. data/app/assets/javascripts/stimulus_com/swipe.js +78 -0
  39. data/app/assets/javascripts/stimulus_com/taxon.js +45 -0
  40. data/app/assets/javascripts/stimulus_com/time.js +19 -0
  41. data/app/assets/javascripts/stimulus_com/touch.js +83 -0
  42. data/app/assets/javascripts/stimulus_com/tree.js +34 -0
  43. data/app/assets/javascripts/stimulus_com/tree_remote.js +64 -0
  44. data/app/assets/javascripts/stimulus_com/typer.js +41 -0
  45. data/app/assets/javascripts/stimulus_com/visit.js +61 -0
  46. data/app/assets/javascripts/stimulus_phone/index.js +19 -0
  47. data/app/assets/javascripts/stimulus_phone/qq_map.js +29 -0
  48. data/app/assets/javascripts/stimulus_phone/search.js +37 -0
  49. data/app/assets/javascripts/stimulus_phone/wechat.js +80 -0
  50. data/app/assets/javascripts/stimulus_phone/weui-actionsheet.js +43 -0
  51. data/app/assets/javascripts/stimulus_phone/weui-datepicker.js +38 -0
  52. data/app/assets/javascripts/stimulus_phone/weui-dialog.js +24 -0
  53. data/app/assets/javascripts/stimulus_phone/weui-picker.js +54 -0
  54. data/app/assets/javascripts/stimulus_phone/wxpay.js +29 -0
  55. data/app/assets/stylesheets/app.scss +3 -0
  56. data/app/assets/stylesheets/ext_bulma/base/_all.scss +5 -0
  57. data/app/assets/stylesheets/ext_bulma/base/_choices.scss +3 -0
  58. data/app/assets/stylesheets/ext_bulma/base/_global.scss +19 -0
  59. data/app/assets/stylesheets/ext_bulma/base/_main.scss +15 -0
  60. data/app/assets/stylesheets/ext_bulma/components/_all.scss +10 -0
  61. data/app/assets/stylesheets/ext_bulma/components/_box.scss +15 -0
  62. data/app/assets/stylesheets/ext_bulma/components/_breadcrumb.scss +17 -0
  63. data/app/assets/stylesheets/ext_bulma/components/_card.scss +12 -0
  64. data/app/assets/stylesheets/ext_bulma/components/_level.scss +8 -0
  65. data/app/assets/stylesheets/ext_bulma/components/_media.scss +14 -0
  66. data/app/assets/stylesheets/ext_bulma/components/_menu.scss +76 -0
  67. data/app/assets/stylesheets/ext_bulma/components/_pagination.scss +9 -0
  68. data/app/assets/stylesheets/ext_bulma/components/_panel.scss +5 -0
  69. data/app/assets/stylesheets/ext_bulma/elements/_all.scss +7 -0
  70. data/app/assets/stylesheets/ext_bulma/elements/_button.scss +14 -0
  71. data/app/assets/stylesheets/ext_bulma/elements/_fa.scss +4 -0
  72. data/app/assets/stylesheets/ext_bulma/elements/_image.scss +38 -0
  73. data/app/assets/stylesheets/ext_bulma/elements/_table.scss +52 -0
  74. data/app/assets/stylesheets/ext_bulma/elements/_title.scss +9 -0
  75. data/app/assets/stylesheets/ext_bulma/expand/_all.scss +2 -0
  76. data/app/assets/stylesheets/ext_bulma/expand/_slide.scss +26 -0
  77. data/app/assets/stylesheets/ext_bulma/expand/_sortable.scss +4 -0
  78. data/app/assets/stylesheets/ext_bulma/form/_all.scss +34 -0
  79. data/app/assets/stylesheets/ext_bulma/form/_checkbox.scss +267 -0
  80. data/app/assets/stylesheets/ext_bulma/form/_file.scss +23 -0
  81. data/app/assets/stylesheets/ext_bulma/form/_select.scss +5 -0
  82. data/app/assets/stylesheets/ext_bulma/form/_tools.scss +30 -0
  83. data/app/assets/stylesheets/ext_bulma/grid/_all.scss +3 -0
  84. data/app/assets/stylesheets/ext_bulma/grid/_columns.scss +13 -0
  85. data/app/assets/stylesheets/ext_bulma/helpers/_all.scss +5 -0
  86. data/app/assets/stylesheets/ext_bulma/helpers/_dot.scss +11 -0
  87. data/app/assets/stylesheets/ext_bulma/helpers/_drawable.scss +3 -0
  88. data/app/assets/stylesheets/ext_bulma/helpers/_grid.scss +10 -0
  89. data/app/assets/stylesheets/ext_bulma/index.scss +22 -0
  90. data/app/assets/stylesheets/ext_bulma/layout/_all.scss +4 -0
  91. data/app/assets/stylesheets/ext_bulma/layout/_footer.scss +4 -0
  92. data/app/assets/stylesheets/ext_bulma/layout/_level.scss +1 -0
  93. data/app/assets/stylesheets/ext_choices/index.scss +16 -0
  94. data/app/assets/stylesheets/ext_font/index.scss +4 -0
  95. data/app/assets/stylesheets/ext_weui/index.scss +24 -0
  96. data/app/assets/stylesheets/ext_weui/widget/_actionsheet.scss +3 -0
  97. data/app/assets/stylesheets/ext_weui/widget/_article.scss +7 -0
  98. data/app/assets/stylesheets/ext_weui/widget/_button.scss +7 -0
  99. data/app/assets/stylesheets/ext_weui/widget/_cell.scss +17 -0
  100. data/app/assets/stylesheets/ext_weui/widget/_form.scss +3 -0
  101. data/app/assets/stylesheets/ext_weui/widget/_half_screen_dialog.scss +10 -0
  102. data/app/assets/stylesheets/ext_weui/widget/_icon.scss +9 -0
  103. data/app/assets/stylesheets/ext_weui/widget/_media.scss +43 -0
  104. data/app/assets/stylesheets/ext_weui/widget/_panel.scss +4 -0
  105. data/app/assets/stylesheets/ext_weui/widget/_preview.scss +5 -0
  106. data/app/assets/stylesheets/ext_weui/widget/_search.scss +5 -0
  107. data/app/assets/stylesheets/ext_weui/widget/_tab.scss +10 -0
  108. data/app/assets/stylesheets/ext_weui/widget/_tabbar.scss +12 -0
  109. data/app/assets/stylesheets/ext_weui/widget/_uploader.scss +14 -0
  110. data/app/assets/stylesheets/phone.scss +6 -0
  111. data/app/assets/stylesheets/slide/index.scss +208 -0
  112. data/app/assets/stylesheets/ui_tooltip/_mixins.scss +46 -0
  113. data/app/assets/stylesheets/ui_tooltip/_variables.scss +5 -0
  114. data/app/assets/stylesheets/ui_tooltip/index.scss +278 -0
  115. data/app/controllers/design/base_controller.rb +4 -0
  116. data/app/controllers/design/home_controller.rb +13 -0
  117. data/app/views/design/home/swipe.html.erb +7 -0
  118. data/app/views/layouts/ui/base.html.erb +5 -0
  119. data/config/routes.rb +11 -0
  120. data/lib/rails_design/config.rb +8 -0
  121. data/lib/rails_design/engine.rb +5 -0
  122. data/lib/rails_design.rb +2 -0
  123. metadata +181 -0
@@ -0,0 +1,189 @@
1
+ import TouchController from './touch'
2
+
3
+ // z-index: 0, 当前显示的图片;
4
+ // z-index: -1, 即将显示的图片,touch move 时动态设定;
5
+ // z-index: -2, 未显示的图片;
6
+ export default class extends TouchController {
7
+
8
+ connect() {
9
+ this.element.addEventListener('touchstart', (event) => {
10
+ this.start(event)
11
+ }, { passive: true })
12
+ }
13
+
14
+ // data-action="touchmove->slide-y#move:passive"
15
+ move(event) {
16
+ const ele = event.currentTarget
17
+ console.debug('touch moved by:', ele.dataset.index)
18
+ if (this.zoomed(event)) {
19
+ console.error('scale')
20
+ return
21
+ }
22
+ let offset = this.offset(event)
23
+ let pad_y = Math.abs(offset.y)
24
+ let isScrolling = pad_y > Math.abs(offset.x) ? 1 : 0 // 1 上下滚动,0 左右滑动
25
+ if (isScrolling === 0) {
26
+ return
27
+ }
28
+
29
+ if (offset.y < 0) { // offset.y < 0 表示向上滑动
30
+ let next = ele.nextElementSibling
31
+ if (next) {
32
+ this.slidingToTop(ele, next, pad_y)
33
+ }
34
+ } else if (offset.y > 0) { // offset.y > 0 表示向下滑动
35
+ let prev = ele.previousElementSibling
36
+ if (prev) {
37
+ this.slidingToBottom(ele, prev, pad_y)
38
+ }
39
+ }
40
+ }
41
+
42
+ // data-action="touchend->slide-y#end:passive"
43
+ end(event) {
44
+ if (this.zoomed(event)) {
45
+ return
46
+ }
47
+ let ele = event.currentTarget
48
+
49
+ let offset = this.offset(event)
50
+ let pad_y = Math.abs(offset.y)
51
+ let isScrolling = pad_y > Math.abs(offset.x) ? 1 : 0 // 1 上下滑动,0 左右滑动
52
+ if (isScrolling === 0) {
53
+ console.debug('not scrolling')
54
+ this.rollback(offset, ele)
55
+ }
56
+
57
+ if (this.effective(pad_y, false)) {
58
+ this.going(offset, ele)
59
+ } else {
60
+ this.rollback(offset, ele)
61
+ }
62
+ }
63
+
64
+ // 执行翻页
65
+ going(offset, ele) {
66
+ const next = ele.nextElementSibling
67
+ const prev = ele.previousElementSibling
68
+
69
+ if (offset.y < 0 && next) {
70
+ this.closeToTop(next)
71
+ next.style.zIndex = 0
72
+ this.toCurrent(next)
73
+
74
+ this.awayFromBottom(ele)
75
+ ele.style.zIndex = -1
76
+ this.beenCurrent(ele)
77
+ }
78
+
79
+ if (offset.y > 0 && prev) {
80
+ this.closeToBottom(prev)
81
+ prev.style.zIndex = 0
82
+ this.toCurrent(prev)
83
+
84
+ this.awayFromTop(ele)
85
+ ele.style.zIndex = -1
86
+ this.beenCurrent(ele)
87
+ }
88
+ }
89
+
90
+ // 回退到之前的状态
91
+ rollback(offset, ele) {
92
+ const next = ele.nextElementSibling
93
+ const prev = ele.previousElementSibling
94
+
95
+ if (offset.y < 0 && next) {
96
+ this.closeToBottom(ele)
97
+ this.toCurrent(ele)
98
+
99
+ this.awayFromTop(next)
100
+ this.beenCurrent(next)
101
+ }
102
+
103
+ if (offset.y > 0 && prev) {
104
+ this.closeToTop(ele)
105
+ this.toCurrent(ele)
106
+
107
+ this.awayFromBottom(prev)
108
+ this.beenCurrent(prev)
109
+ }
110
+ }
111
+
112
+ // 上滑
113
+ slidingToTop(ele, next, pad) {
114
+ ele.style.bottom = pad + 'px'
115
+ next.style.zIndex = -1
116
+ next.style.top = (this.element.clientHeight - pad) + 'px'
117
+ }
118
+
119
+ // 下滑
120
+ slidingToBottom(ele, prev, pad) {
121
+ ele.style.top = pad + 'px'
122
+ prev.style.zIndex = -1
123
+ prev.style.bottom = (this.element.clientHeight - pad) + 'px'
124
+ }
125
+
126
+ // xx
127
+ resetIndex(event) {
128
+ ['top', 'bottom', 'transition-property', 'transition-duration'].forEach(rule => {
129
+ event.currentTarget.style.removeProperty(rule)
130
+ })
131
+ event.currentTarget.style.zIndex = -2
132
+ }
133
+
134
+ // 不再展示
135
+ beenCurrent(ele) {
136
+ console.debug('add transition event listener for been', ele.dataset.index)
137
+ ele.addEventListener('transitionend', this.resetIndex, { once: true })
138
+ ele.addEventListener('transitioncancel', (event) => {
139
+ this.resetIndex(event)
140
+ ele.removeEventListener('transitionend', this.resetIndex)
141
+ }, { once: true })
142
+ }
143
+
144
+ // 即将展示
145
+ toCurrent(ele) {
146
+ console.debug('add transition event listener for to', ele.dataset.index)
147
+ ele.addEventListener('transitionend', (event) => {
148
+ this.clearStyle(event.currentTarget)
149
+ }, { once: true })
150
+ ele.addEventListener('transitioncancel', (event) => {
151
+ this.clearStyle(event.currentTarget)
152
+ }, { once: true })
153
+ }
154
+
155
+ // 接近上侧
156
+ closeToTop(ele) {
157
+ ele.style.top = 0
158
+ ele.style.transitionProperty = 'top'
159
+ ele.style.transitionDuration = this.duration
160
+ }
161
+
162
+ // 接近下侧
163
+ closeToBottom(ele) {
164
+ ele.style.bottom = 0
165
+ ele.style.transitionProperty = 'bottom'
166
+ ele.style.transitionDuration = this.duration
167
+ }
168
+
169
+ // 远离下侧
170
+ awayFromBottom(ele) {
171
+ ele.style.bottom = this.element.clientHeight + 'px'
172
+ ele.style.transitionProperty = 'bottom'
173
+ ele.style.transitionDuration = this.duration
174
+ }
175
+
176
+ // 远离上侧
177
+ awayFromTop(ele) {
178
+ ele.style.top = this.element.clientHeight + 'px'
179
+ ele.style.transitionProperty = 'top'
180
+ ele.style.transitionDuration = this.duration
181
+ }
182
+
183
+ clearStyle(ele) {
184
+ ['top', 'bottom', 'transition-property', 'transition-duration'].forEach(rule => {
185
+ ele.style.removeProperty(rule)
186
+ })
187
+ }
188
+
189
+ }
@@ -0,0 +1,41 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import Sortable from 'sortablejs'
3
+
4
+ export default class extends Controller {
5
+
6
+ reload(element, controller) {
7
+ Sortable.create(element, {
8
+ handle: '.is-drawable',
9
+ onEnd: function(evt) {
10
+ if (evt.oldIndex === evt.newIndex) {
11
+ return
12
+ }
13
+ let url = [element.dataset['src'], evt.item.dataset['id'], 'reorder'].join('/')
14
+ let body = {
15
+ sort_array: this.toArray(),
16
+ old_index: evt.oldIndex,
17
+ new_index: evt.newIndex
18
+ }
19
+
20
+ fetch(url, {
21
+ method: 'PATCH',
22
+ headers: {
23
+ Accept: 'text/vnd.turbo-stream.html',
24
+ 'Content-Type': 'application/json',
25
+ 'X-CSRF-Token': controller.csrfToken()
26
+ },
27
+ body: JSON.stringify(body)
28
+ }).then(response => {
29
+ return response.text()
30
+ }).then(body => {
31
+ Turbo.renderStreamMessage(body)
32
+ })
33
+ }
34
+ })
35
+ }
36
+
37
+ connect() {
38
+ this.reload(this.element, this)
39
+ }
40
+
41
+ }
@@ -0,0 +1,11 @@
1
+ import stickybits from 'stickybits'
2
+ import { Controller } from '@hotwired/stimulus'
3
+
4
+ // data-controller="menu"
5
+ export default class extends Controller {
6
+
7
+ connect() {
8
+ stickybits(this.element)
9
+ }
10
+
11
+ }
@@ -0,0 +1,78 @@
1
+ import TouchController from './touch'
2
+
3
+ export default class extends TouchController {
4
+ static targets = ['open']
5
+
6
+ // data-action="touchstart->swipe#start:passive"
7
+ start(event) {
8
+ let touch = event.targetTouches[0]
9
+ this.startPos = {
10
+ x: touch.pageX,
11
+ y: touch.pageY
12
+ }
13
+ this.startTime = new Date().getTime() // 毫秒,千分之一秒
14
+ this.barWidth = this.element.clientWidth
15
+ this.swiperWidth = this.openTarget.clientWidth
16
+ }
17
+
18
+ // data-action="touchmove->swipe#move touchstart->swipe#move"
19
+ move(event) {
20
+ if (this.zoomed(event)) {
21
+ return
22
+ }
23
+ let offset = this.offset(event.targetTouches[0])
24
+ let pad = Math.abs(offset.x)
25
+ let isScrolling = pad < Math.abs(offset.y) ? 1 : 0 // 1 上下滚动,0 左右滑动
26
+ if (isScrolling !== 0) {
27
+ return
28
+ }
29
+
30
+ if (isScrolling === 0 && offset.x < 0) {
31
+ this.openTarget.style.width = `${this.swiperWidth + pad}px`
32
+ let styles = {
33
+ width: `${this.barWidth - this.swiperWidth + this.openTarget.clientWidth}px`,
34
+ left: `-${this.openTarget.clientWidth}px`
35
+ }
36
+ Object.assign(this.element.style, styles)
37
+ } else if (isScrolling === 0 && offset.x > 0) {
38
+ let x = pad < this.swiperWidth ? this.swiperWidth - pad : 0
39
+ this.openTarget.style.width = `${x}px`
40
+ let styles = {
41
+ width: `${this.barWidth - (pad < this.swiperWidth ? pad : this.swiperWidth)}px`,
42
+ left: `-${x}px`
43
+ }
44
+ Object.assign(this.element.style, styles)
45
+ }
46
+ }
47
+
48
+ end(event) {
49
+ // let styles = {
50
+ // width: '150px',
51
+ // 'transition-property': 'width'
52
+ // }
53
+ this.openTarget.style.width = `${this.openTarget.clientWidth}px`
54
+ // Object.assign(this.element.style, styles)
55
+ }
56
+
57
+ get leftPos() {
58
+ let left = this.element.style.left.replace(/px$/, '')
59
+ return parseFloat(left)
60
+ }
61
+
62
+ get barWidth() {
63
+ return parseFloat(this.data.get('barWidth'))
64
+ }
65
+
66
+ set barWidth(value) {
67
+ this.data.set('barWidth', value)
68
+ }
69
+
70
+ get swiperWidth() {
71
+ return parseFloat(this.data.get('swiperWidth'))
72
+ }
73
+
74
+ set swiperWidth(value) {
75
+ this.data.set('swiperWidth', value)
76
+ }
77
+
78
+ }
@@ -0,0 +1,45 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class extends Controller {
4
+ static values = {
5
+ url: String,
6
+ title: String,
7
+ params: Object
8
+ }
9
+
10
+ // change
11
+ choose(event) {
12
+ let ele = event.currentTarget
13
+ if (ele.value === '' || ele.value === null) {
14
+ this.clear(this.element)
15
+ } else {
16
+ let search_url = new URL(this.urlValue, location.origin)
17
+ search_url.searchParams.set('node_id', ele.value)
18
+ search_url.searchParams.set('html_id', this.element.id)
19
+ Object.keys(this.paramsValue).forEach(k => {
20
+ search_url.searchParams.set(k, this.paramsValue[k])
21
+ })
22
+
23
+ fetch(search_url, {
24
+ method: 'GET',
25
+ headers: {
26
+ Accept: 'text/vnd.turbo-stream.html'
27
+ }
28
+ }).then(response => {
29
+ return response.text()
30
+ }).then(body => {
31
+ this.clear(this.element)
32
+ Turbo.renderStreamMessage(body)
33
+ })
34
+ }
35
+ }
36
+
37
+ clear(node) {
38
+ let el = node.nextElementSibling
39
+ while (el && el.dataset['taxonTitleValue'] === this.titleValue) {
40
+ el.remove()
41
+ el = node.nextElementSibling
42
+ }
43
+ }
44
+
45
+ }
@@ -0,0 +1,19 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import moment from 'moment'
3
+
4
+ // data-controller="time"
5
+ export default class extends Controller {
6
+
7
+ connect() {
8
+ this.parse()
9
+ }
10
+
11
+ parse() {
12
+ if (this.element.textContent.length > 0) {
13
+ let format = this.element.dataset['format'] || 'YYYY-MM-DD HH:mm'
14
+ this.element.textContent = moment.utc(this.element.textContent).local().format(format)
15
+ this.element.dataset['localized'] = 'true'
16
+ }
17
+ }
18
+
19
+ }
@@ -0,0 +1,83 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class TouchController extends Controller {
4
+ static values = {
5
+ debug: Boolean
6
+ }
7
+
8
+ // data-action="touchstart->slide#start:passive"
9
+ start(event) {
10
+ const touch = event.targetTouches[0]
11
+ this.startPos = {
12
+ x: touch.pageX,
13
+ y: touch.pageY
14
+ }
15
+ this.startTime = new Date().getTime() // 毫秒,千分之一秒
16
+ }
17
+
18
+ // scale && scale !== 表示缩放了
19
+ zoomed(event) {
20
+ return event.changedTouches.length > 1 || (event.scale && event.scale !== 1)
21
+ }
22
+
23
+ // 是否达到触发条件
24
+ effective(pad, x = true) {
25
+ const endTime = new Date().getTime()
26
+ let isMore
27
+ // 滑动距离是否超过元素宽度一半
28
+ if (x) {
29
+ isMore = pad > this.element.clientWidth / 2
30
+ } else {
31
+ isMore = pad > this.element.clientHeight / 2
32
+ }
33
+ console.debug('是否超过一半:', isMore)
34
+
35
+ const speed = pad / (endTime - this.startTime) // 手势速度
36
+ const isFast = speed > 0.1
37
+ console.debug('手势速度:', isFast) // 大于 0.1
38
+
39
+ return isMore || isFast
40
+ }
41
+
42
+ offset(event) {
43
+ const touch = event.changedTouches[0]
44
+ const offset = {
45
+ x: touch.pageX - this.startPos.x,
46
+ y: touch.pageY - this.startPos.y
47
+ }
48
+ if (this.hasDebugValue && this.debugValue) {
49
+ console.debug(event.type, 'offset:', offset)
50
+ }
51
+
52
+ return offset
53
+ }
54
+
55
+ get startPos() {
56
+ let r = this.data.get('startPos').split(',')
57
+ return {
58
+ x: parseFloat(r[0]),
59
+ y: parseFloat(r[1])
60
+ }
61
+ }
62
+
63
+ set startPos(pos) {
64
+ this.data.set('startPos', [pos.x, pos.y].join(','))
65
+ }
66
+
67
+ get startTime() {
68
+ return this.data.get('startTime')
69
+ }
70
+
71
+ set startTime(time) {
72
+ this.data.set('startTime', time)
73
+ }
74
+
75
+ get duration() {
76
+ let duration = this.data.get('duration')
77
+ if (!duration) {
78
+ duration = '1s'
79
+ }
80
+ return duration
81
+ }
82
+
83
+ }