bing-progress.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. <template>
  2. <view class="bing-progress" :style="{width:bpWidth,height:bpHeight,borderRadius:borderRadius,
  3. backgroundColor:backgroundColor,flexDirection:direction!='vertical'?'row':'column'}">
  4. <!-- 进度 -->
  5. <!-- #ifdef APP-NVUE -->
  6. <div class="bp-bar_max"
  7. :style="{width:barMaxWidth,height:barMaxHeight,backgroundColor:noActiveColor,
  8. flexDirection:direction!='vertical'?'row':'column',left:barMaxLeft,borderRadius:barBorderRadius}">
  9. <div class="bp-bar_sub_active"
  10. :style="{width:barSubActiveWidth,height:barSubActiveHeight,backgroundColor:subActiveColor,
  11. top:subActiveTop,bottom:subActiveBottom,left:subActiveLeft,right:subActiveRight,borderRadius:isActiveCircular?barBorderRadius:0}"></div>
  12. <div class="bp-bar_active"
  13. :style="{width:barActiveWidth,height:barActiveHeight,backgroundColor:activeColor,
  14. top:activeTop,bottom:activeBottom,left:activeLeft,right:activeRight,borderRadius:isActiveCircular?barBorderRadius:0}"></div>
  15. </div>
  16. <!-- #endif -->
  17. <!-- #ifndef APP-NVUE -->
  18. <view class="bp-bar_max"
  19. :style="{width:barMaxWidth,height:barMaxHeight,backgroundColor:noActiveColor,borderRadius:barBorderRadius,
  20. flexDirection:direction!='vertical'?'row':'column',left:barMaxLeft}">
  21. <view class="bp-bar_sub_active"
  22. :style="{width:barSubActiveWidth,height:barSubActiveHeight,backgroundColor:subActiveColor,
  23. top:subActiveTop,bottom:subActiveBottom,left:subActiveLeft,right:subActiveRight,borderRadius:isActiveCircular?barBorderRadius:0}"></view>
  24. <view class="bp-bar_active"
  25. :style="{width:barActiveWidth,height:barActiveHeight,backgroundColor:activeColor,
  26. top:activeTop,bottom:activeBottom,left:activeLeft,right:activeRight,borderRadius:isActiveCircular?barBorderRadius:0}"></view>
  27. </view>
  28. <!-- #endif -->
  29. <movable-area class="bp-marea" @touchmove.stop.prevent="touchmove" @touchstart="touchstart" @touchcancel="touchend" @touchend="touchend"
  30. :style="{width:mareaWidth,height:mareaHeight,left:mareaLeft}">
  31. <!-- 拖柄 -->
  32. <movable-view class="bp-mview" :direction="direction=='vertical'?'vertical':'horizontal'" :animation="false"
  33. :disabled="true" :x="handleX" :y="handleY" friction="10" damping="100"
  34. :style="{width:mhandleWidth,height:mhandleHeight,backgroundColor:handleColor,
  35. borderRadius:handleBorderRadius,fontSize:infoFontSize,top:mhandleTop}">
  36. <view class="bp-handle" :style="{fontSize:infoFontSize,width:mhandleWidth,height:mhandleHeight,borderRadius:handleBorderRadius}">
  37. <image class="bp-handle-img" :src="handleImgUrl" v-if="handleImgUrl"
  38. :style="{fontSize:infoFontSize,width:mhandleWidth,height:mhandleHeight,borderRadius:handleBorderRadius}"></image>
  39. <text class="bp-handle-text" v-if="handleImgUrl=='' && infoAlign=='handle' && showInfo"
  40. :style="{fontSize:infoFontSize,color:infoColor,width:mhandleWidth,height:textHeight,borderRadius:'20px'}">{{ infoContent=='subValue'?msubValue:showValue }}{{ infoEndText }}</text>
  41. </view>
  42. </movable-view>
  43. </movable-area>
  44. <text class="bp-value" v-if="showValueState() || (infoAlign=='center'&&direction!='vertical' && showInfo)"
  45. :style="{color:infoColor,fontSize:infoFontSize,left:valueLeft,width:valueWidth()+'px'}">{{ infoContent=='subValue'?msubValue:showValue }}{{ infoEndText }}</text>
  46. </view>
  47. </template>
  48. <script>
  49. /**
  50. * 进度条,副进度条
  51. */
  52. export default {
  53. created() {
  54. /**
  55. * 获取系统屏幕信息,用于后续单位换算
  56. */
  57. const systemInfo = uni.getSystemInfoSync()
  58. this.px2rpx = 750 / systemInfo.screenWidth
  59. this.screenWidth = systemInfo.screenWidth
  60. this.screenHeight = systemInfo.screenHeight
  61. },
  62. mounted() {
  63. // #ifndef APP-NVUE
  64. /**
  65. * 非NVUE滑动事件获取到的位置是相对于屏幕的,获取组件位置,用于计算滑块位置
  66. */
  67. let query = uni.createSelectorQuery().in(this)
  68. query.select('.bing-progress').boundingClientRect(data => {
  69. this.mainInfo.top = data.top
  70. this.mainInfo.left = data.left
  71. this.mainInfo.bottom = data.bottom
  72. this.mainInfo.right = data.right
  73. }).exec()
  74. // #endif
  75. this.percent = Math.abs((this.valueFormat(this.value) - this.min) / (this.max - this.min))
  76. this.subPercent = Math.abs((this.valueFormat(this.subValue,true) - this.min) / (this.max - this.min))
  77. if(this.reverse) {
  78. if(this.direction!='vertical') {
  79. this.handleX = (1 - this.percent) * this.barMaxLength
  80. }
  81. else {
  82. this.handleY = this.percent * this.barMaxLength
  83. }
  84. }
  85. else {
  86. if(this.direction!='vertical') {
  87. this.handleX = this.percent * this.barMaxLength
  88. }
  89. else {
  90. this.handleY = (1 - this.percent) * this.barMaxLength
  91. }
  92. }
  93. },
  94. /**
  95. * sub表示副进度条属性
  96. */
  97. props: {
  98. width: {
  99. type: String,
  100. default: '300px'
  101. },
  102. strokeWidth: {
  103. type: String,
  104. default: '30px'
  105. },
  106. backgroundColor: {
  107. type: String,
  108. default: 'rgba(0,0,0,0)'
  109. },
  110. noActiveColor: {
  111. type: String,
  112. default: "#00ffff"
  113. },
  114. activeColor: {
  115. type: String,
  116. default: "#0000ff"
  117. },
  118. subActiveColor: {
  119. type: String,
  120. default: "#ffaaaa"
  121. },
  122. handleColor: {
  123. type: String,
  124. default: "#ffff00"
  125. },
  126. infoColor: {
  127. type: String,
  128. default: "#000000"
  129. },
  130. // 整个进度条的外边界圆角半径
  131. borderRadius: {
  132. type: String,
  133. default: '5px'
  134. },
  135. // 进度条内部滑轨圆角半径
  136. barBorderRadius: {
  137. type: String,
  138. default: '5px'
  139. },
  140. // active and sunActive 是否显示圆角 NVUE默认true,其他默认false
  141. // #ifdef APP-NVUE
  142. isActiveCircular: {
  143. type: Boolean,
  144. default: true
  145. },
  146. // #endif
  147. // #ifndef APP-NVUE
  148. isActiveCircular: {
  149. type: Boolean,
  150. default: false
  151. },
  152. // #endif
  153. handleWidth: {
  154. type: String,
  155. default: '50px'
  156. },
  157. handleHeight: {
  158. type: String,
  159. default: '40px'
  160. },
  161. handleBorderRadius: {
  162. type: String,
  163. default: '5px'
  164. },
  165. handleImgUrl: {
  166. type: String,
  167. default: ''
  168. },
  169. disabled: {
  170. type: Boolean,
  171. default: false
  172. },
  173. direction: {
  174. type: String,
  175. default: 'horizontal'
  176. },
  177. infoEndText: {
  178. type: String,
  179. default: ""
  180. },
  181. infoFontSize: {
  182. type: String,
  183. default: '18px'
  184. },
  185. showInfo: {
  186. type: Boolean,
  187. default: true
  188. },
  189. // 进度值显示value还是subValue
  190. infoContent: {
  191. type: String,
  192. default: 'value'
  193. },
  194. infoAlign: {
  195. type: String,
  196. default: 'right'
  197. },
  198. max: {
  199. type: Number,
  200. default: 100
  201. },
  202. min: {
  203. type: Number,
  204. default: 0
  205. },
  206. value: {
  207. type: Number,
  208. default: 0
  209. },
  210. subValue: {
  211. type: Number,
  212. default: 0
  213. },
  214. step: {
  215. type: Number,
  216. default: 1
  217. },
  218. // 副进度条步长
  219. subStep: {
  220. type: Number,
  221. default: 1
  222. },
  223. // true连续滑动,false步进,即以step的间隔变化
  224. continuous: {
  225. type: Boolean,
  226. default: true
  227. },
  228. // 副进度条continuous
  229. subContinuous: {
  230. type: Boolean,
  231. default: true
  232. },
  233. reverse: {
  234. type: Boolean,
  235. default: false
  236. },
  237. },
  238. data() {
  239. return {
  240. handleX: 50,
  241. handleY: 0,
  242. px2rpx: 1,
  243. percent: 0, // 0-1
  244. subPercent: 0, // 0-1
  245. mainInfo: {
  246. left: 0,
  247. top: 0,
  248. bottom: 0,
  249. right: 0
  250. },
  251. touchState: false,
  252. screenHeight: 0,
  253. screenWidth: 0,
  254. msubValue: 0
  255. }
  256. },
  257. watch: {
  258. /**
  259. * @param {Object} newValue
  260. * @param {Object} oldValue
  261. */
  262. value(newValue, oldValue) {
  263. if(!this.touchState) {
  264. newValue = this.valueSetBoundary(newValue)
  265. this.percent = Math.abs((newValue - this.min) / (this.max - this.min))
  266. }
  267. },
  268. showValue(newValue, oldValue) {
  269. // 步进
  270. if(!this.continuous) {
  271. if(this.reverse) {
  272. if(this.direction!='vertical') {
  273. this.handleX = Math.abs(1 - (newValue - this.min) / (this.max - this.min)) * this.barMaxLength
  274. }
  275. else {
  276. this.handleY = Math.abs((newValue - this.min) / (this.max - this.min)) * this.barMaxLength
  277. }
  278. }
  279. else {
  280. if(this.direction!='vertical') {
  281. this.handleX = Math.abs((newValue - this.min) / (this.max - this.min)) * this.barMaxLength
  282. }
  283. else {
  284. this.handleY = (1 - Math.abs((newValue - this.min) / (this.max - this.min))) * this.barMaxLength
  285. }
  286. }
  287. }
  288. this.$emit("change", {type: 'change',value:this.showValue,subValue:this.msubValue})
  289. this.$emit("valuechange", {type: 'valuechange',value:this.showValue,subValue:this.msubValue})
  290. },
  291. percent(newValue, oldValue) {
  292. // 连续
  293. if(this.continuous) {
  294. if(this.reverse) {
  295. if(this.direction!='vertical') {
  296. this.handleX = (1 - newValue) * this.barMaxLength
  297. }
  298. else {
  299. this.handleY = newValue * this.barMaxLength
  300. }
  301. }
  302. else {
  303. if(this.direction!='vertical') {
  304. this.handleX = newValue * this.barMaxLength
  305. }
  306. else {
  307. this.handleY = (1 - newValue) * this.barMaxLength
  308. }
  309. }
  310. }
  311. },
  312. subValue(newValue, oldValue) {
  313. newValue = this.valueSetBoundary(newValue)
  314. if(this.subContinuous) {
  315. this.msubValue = newValue
  316. }
  317. else {
  318. this.msubValue = this.valueFormat(newValue, true)
  319. }
  320. this.subPercent = Math.abs((newValue - this.min) / (this.max - this.min))
  321. this.$emit("change", {type: 'change',value:this.showValue,subValue:this.msubValue})
  322. this.$emit("subvaluechange", {type: 'subvaluechange',value:this.showValue,subValue:this.msubValue})
  323. },
  324. },
  325. computed: {
  326. bpWidth() {
  327. if(this.direction=="vertical") {
  328. return this.maxHeight()[2]
  329. }
  330. return this.sizeDeal(this.width)[2]
  331. },
  332. bpHeight() {
  333. if(this.direction=="vertical") {
  334. return this.sizeDeal(this.width)[2]
  335. }
  336. return this.maxHeight()[2]
  337. },
  338. mareaWidth() {
  339. if(this.direction=="vertical") {
  340. return this.maxHeight()[2]
  341. }
  342. let width = this.sizeDeal(this.width)[0]
  343. return (width - this.textWidth()) + 'px'
  344. },
  345. mareaHeight() {
  346. if(this.direction=="vertical") {
  347. let width = this.sizeDeal(this.width)[0]
  348. return (width - this.textWidth()) + 'px'
  349. }
  350. return this.maxHeight()[2]
  351. },
  352. mareaLeft() {
  353. if(this.showValueState()) {
  354. if(this.infoAlign == 'left') {
  355. return this.textWidth() + 'px'
  356. }
  357. }
  358. return 0
  359. },
  360. barMaxHeight() {
  361. if(this.direction=="vertical") {
  362. let width = this.sizeDeal(this.width)[0]
  363. let handleWidth = this.sizeDeal(this.handleWidth)
  364. return (width - this.textWidth() - handleWidth[0]) + 'px'
  365. }
  366. return this.sizeDeal(this.strokeWidth)[2]
  367. },
  368. barMaxWidth() {
  369. if(this.direction=="vertical") {
  370. return this.sizeDeal(this.strokeWidth)[2]
  371. }
  372. let width = this.sizeDeal(this.width)[0]
  373. let handleWidth = this.sizeDeal(this.handleWidth)
  374. return (width - this.textWidth() - handleWidth[0]) + 'px'
  375. },
  376. barMaxLeft() {
  377. if(this.showValueState()) {
  378. if(this.infoAlign == 'left') {
  379. return this.textWidth() + this.sizeDeal(this.handleWidth)[0] / 2 + 'px'
  380. }
  381. }
  382. if(this.direction != 'vertical') {
  383. return this.sizeDeal(this.handleWidth)[0] / 2 + 'px'
  384. }
  385. // vertical
  386. return (this.maxHeight()[0] - this.sizeDeal(this.strokeWidth)[0]) / 2 + 'px'
  387. },
  388. activeRight() {
  389. if(this.reverse) {
  390. return 0
  391. }
  392. return 'unset'
  393. },
  394. activeLeft() {
  395. if(this.reverse) {
  396. return 'unset'
  397. }
  398. return 0
  399. },
  400. activeTop() {
  401. if(this.reverse) {
  402. return 0
  403. }
  404. return 'unset'
  405. },
  406. activeBottom() {
  407. if(this.reverse) {
  408. return 'unset'
  409. }
  410. return 0
  411. },
  412. barActiveWidth() {
  413. if(this.direction=="vertical") {
  414. return this.sizeDeal(this.strokeWidth)[2]
  415. }
  416. let percent
  417. if(this.continuous) {
  418. percent = this.percent
  419. }
  420. else {
  421. percent = Math.abs((this.showValue - this.min) / (this.max - this.min))
  422. }
  423. return this.barMaxLength * percent + 'px'
  424. },
  425. barActiveHeight() {
  426. if(this.direction=="vertical") {
  427. let percent
  428. if(this.continuous) {
  429. percent = this.percent
  430. }
  431. else {
  432. percent = Math.abs((this.showValue - this.min) / (this.max - this.min))
  433. }
  434. return this.barMaxLength * percent + 'px'
  435. }
  436. return this.sizeDeal(this.strokeWidth)[2]
  437. },
  438. subActiveTop() {
  439. if(this.reverse) {
  440. return 0
  441. }
  442. return 'unset'
  443. },
  444. subActiveBottom() {
  445. if(this.reverse) {
  446. return 'unset'
  447. }
  448. return 0
  449. },
  450. subActiveRight() {
  451. if(this.reverse) {
  452. return 0
  453. }
  454. return 'unset'
  455. },
  456. subActiveLeft() {
  457. if(this.reverse) {
  458. return 'unset'
  459. }
  460. return 0
  461. },
  462. barSubActiveWidth() {
  463. if(this.direction == "vertical") {
  464. return this.sizeDeal(this.strokeWidth)[2]
  465. }
  466. if(this.subContinuous) {
  467. return this.barMaxLength * this.subPercent + 'px'
  468. }
  469. else {
  470. return this.barMaxLength * Math.abs((this.msubValue - this.min) / (this.max - this.min)) + 'px'
  471. }
  472. },
  473. barSubActiveHeight() {
  474. if(this.direction == "vertical") {
  475. if(this.subContinuous) {
  476. return this.barMaxLength * this.subPercent + 'px'
  477. }
  478. else {
  479. this.barMaxLength * Math.abs((this.msubValue - this.min) / (this.max - this.min)) + 'px'
  480. }
  481. }
  482. return this.sizeDeal(this.strokeWidth)[2]
  483. },
  484. mhandleWidth() {
  485. if(this.direction == "vertical") {
  486. return this.sizeDeal(this.handleHeight)[2]
  487. }
  488. return this.sizeDeal(this.handleWidth)[2]
  489. },
  490. mhandleHeight() {
  491. if(this.direction == "vertical") {
  492. return this.sizeDeal(this.handleWidth)[2]
  493. }
  494. return this.sizeDeal(this.handleHeight)[2]
  495. },
  496. mhandleTop() {
  497. if(this.direction == 'vertical') {
  498. return 0
  499. }
  500. else {
  501. // 拖柄垂直居中
  502. let handle = this.sizeDeal(this.handleHeight)[0]
  503. let top = this.maxHeight()[0] / 2 - handle / 2 + 'px'
  504. return top
  505. }
  506. },
  507. showValue() {
  508. return this.valueFormat(this.percent * (this.max - this.min) + this.min)
  509. },
  510. textHeight() {
  511. let infoSize = this.sizeDeal(this.infoFontSize)
  512. return infoSize[0]*1.2 + infoSize[1]
  513. },
  514. valueLeft() {
  515. if(this.infoAlign=='left') {
  516. return 0
  517. }
  518. else if(this.infoAlign == 'center') {
  519. let width = this.sizeDeal(this.width)
  520. return width[0]/2 - this.valueWidth()/2 + 'px'
  521. }
  522. else if(this.infoAlign=='right'){
  523. let width = this.sizeDeal(this.width)
  524. return width[0] - this.textWidth() + 'px'
  525. }
  526. return 0
  527. },
  528. barMaxLength() {
  529. let width = this.sizeDeal(this.width)[0]
  530. let handleWidth = this.sizeDeal(this.handleWidth)
  531. return width - this.textWidth() - handleWidth[0]
  532. },
  533. },
  534. methods: {
  535. touchstart(e) {
  536. if(!this.disabled) {
  537. this.touchState = true
  538. let detail = e.changedTouches[0]
  539. this.handleMove(detail)
  540. this.$emit("dragstart", {type: 'dragstart',value:this.showValue,subValue:this.msubValue})
  541. }
  542. },
  543. touchmove(e) {
  544. if(!this.disabled) {
  545. e.stopPropagation()
  546. let detail = e.changedTouches[0]
  547. this.handleMove(detail)
  548. this.$emit("dragging", {type: 'dragging',value:this.showValue,subValue:this.msubValue})
  549. }
  550. },
  551. touchend(e) {
  552. if(!this.disabled) {
  553. let detail = e.changedTouches[0]
  554. this.handleMove(detail)
  555. this.touchState = false
  556. this.$emit("dragend", {type: 'dragend',value:this.showValue,subValue:this.msubValue})
  557. }
  558. },
  559. handleMove(detail) {
  560. let width = this.sizeDeal(this.width)[0]
  561. let handleWidth = this.sizeDeal(this.handleWidth)
  562. let percent
  563. if(this.direction!='vertical') {
  564. if(this.infoAlign=='left') {
  565. // #ifndef APP-NVUE
  566. percent = (detail.pageX - this.mainInfo.left - this.textWidth() - handleWidth[0]/2)/ this.barMaxLength
  567. // #endif
  568. // #ifdef APP-NVUE
  569. percent = (detail.pageX - handleWidth[0]/2)/ this.barMaxLength
  570. // #endif
  571. }
  572. else {
  573. // #ifndef APP-NVUE
  574. percent = (detail.pageX - this.mainInfo.left - handleWidth[0]/2)/ this.barMaxLength
  575. // #endif
  576. // #ifdef APP-NVUE
  577. percent = (detail.pageX - handleWidth[0]/2)/ this.barMaxLength
  578. // #endif
  579. }
  580. }
  581. else {
  582. // #ifdef APP-NVUE
  583. percent = 1 - (detail.pageY - handleWidth[0]/2- 1) / this.barMaxLength
  584. // #endif
  585. // #ifndef APP-NVUE
  586. percent = 1 - (detail.pageY - this.mainInfo.top - handleWidth[0]/2)/ this.barMaxLength
  587. // #endif
  588. }
  589. percent = percent > 0 ? percent : 0
  590. percent = percent < 1 ? percent : 1
  591. if(this.reverse) {
  592. this.percent = 1 - percent
  593. }
  594. else {
  595. this.percent = percent
  596. }
  597. },
  598. showValueState() {
  599. if(this.direction != 'vertical' && this.showInfo && (this.infoAlign=='left' || this.infoAlign=='right')) {
  600. return true
  601. }
  602. return false
  603. },
  604. valueSetBoundary(value) {
  605. // 控制value在合法范围内
  606. if(this.max > this.min) {
  607. value = value < this.max ? value : this.max
  608. value = value > this.min ? value : this.min
  609. }
  610. else {
  611. value = value > this.max ? value : this.max
  612. value = value < this.min ? value : this.min
  613. }
  614. return value
  615. },
  616. /**
  617. * @param {Object} v
  618. * @param {Object} isSub 是否是副副进度条
  619. */
  620. valueFormat (v,isSub){
  621. // set step
  622. v = this.valueSetBoundary(v)
  623. let stepInfo = this.stepInfo(isSub)
  624. v = Number(v - this.min).toFixed(stepInfo[1])
  625. let step = stepInfo[0] * 10 ** stepInfo[1]
  626. let valueE = v * 10 ** stepInfo[1]
  627. let remainder = valueE % step
  628. let remainderInt = Math.floor(remainder)
  629. // 对余数四舍五入0-1
  630. let sub = Math.round(remainder / step)
  631. let value = (Math.floor(valueE) - remainderInt + sub*step) / (10 ** stepInfo[1])
  632. value = Number((value + this.min).toFixed(stepInfo[1]))
  633. return value
  634. },
  635. /**
  636. * @param {Object} v
  637. * @param {Object} isSub 是否是副副进度条
  638. */
  639. stepInfo(isSub) {
  640. // return step, decimal位数
  641. let step
  642. if(isSub) {
  643. step = Number(this.subStep)
  644. }
  645. else {
  646. step = Number(this.step)
  647. }
  648. if (step <= 0 || !step){
  649. return [1, 0]
  650. }
  651. else{
  652. let steps = step.toString().split('.')
  653. if (steps.length == 1){
  654. return [step,0]
  655. }
  656. else {
  657. return [step,steps[1].length]
  658. }
  659. }
  660. },
  661. textWidth() {
  662. if(this.showValueState()) {
  663. let numWidth = this.max.toString().length> this.min.toString().length? this.max.toString().length: this.min.toString().length
  664. let textWidth = ((numWidth + this.stepInfo()[1]) * 0.7 + this.infoEndText.length) * this.sizeDeal(this.infoFontSize)[0]
  665. return Number(textWidth.toFixed(2))
  666. }
  667. return 0
  668. },
  669. valueWidth() {
  670. let numWidth = this.max.toString().length> this.min.toString().length? this.max.toString().length: this.min.toString().length
  671. let textWidth = ((numWidth + this.stepInfo()[1]) * 0.7 + this.infoEndText.length) * this.sizeDeal(this.infoFontSize)[0]
  672. return Number(textWidth.toFixed(2))
  673. },
  674. maxHeight() {
  675. let h = []
  676. if (this.direction!='vertical'){ // direction 为 vertical 时不显示info
  677. let subt = this.infoEndText.match(/[^\x00-\xff]/g)
  678. if (subt){
  679. h.push(this.sizeDeal(this.infoFontSize)[0] * 1.1)
  680. }
  681. else{
  682. h.push(this.sizeDeal(this.infoFontSize)[0])
  683. }
  684. }
  685. h.push(this.sizeDeal(this.strokeWidth)[0])
  686. h.push(this.sizeDeal(this.handleHeight)[0])
  687. h.sort(function(a, b) {
  688. return b - a
  689. }) // 降序
  690. return [h[0], 'px', h[0] + 'px']
  691. },
  692. sizeDeal(size) {
  693. // 分离字体大小和单位,rpx 转 px
  694. let s = Number.isNaN(parseFloat(size)) ? 0 : parseFloat(size)
  695. let u = size.toString().replace(/[0-9\.]/g, '')
  696. if (u == 'rpx') {
  697. s /= this.px2rpx
  698. u = 'px'
  699. }else if (u == 'vw') {
  700. u = 'px'
  701. s = s / 100 * this.screenWidth
  702. } else if(u == 'vh') {
  703. u = 'px'
  704. s = s / 100 * this.screenHeight
  705. } else{
  706. u = 'px'
  707. }
  708. return [s, u, s + u]
  709. },
  710. }
  711. }
  712. </script>
  713. <style scoped>
  714. @import "bing-progress.css"
  715. </style>