SlidngScale.tsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import { ScrollView, View, Text, Image } from "@tarojs/components";
  2. import VirtualList from '@tarojs/components/virtual-list';
  3. import './SlidngScale.scss'
  4. import { useEffect, useRef, useState } from "react";
  5. import Taro from "@tarojs/taro";
  6. import { rpxToPx } from "@/utils/tools";
  7. import { throttle } from 'lodash';
  8. var timerA = null
  9. export default function Component(props: {
  10. step: number, min: number,
  11. max: number, default_value: number, changed: Function, unit: string
  12. themeColor: string
  13. }) {
  14. const scrollViewRef = useRef<any>();
  15. const minNum: number = props.min;//props.step < 1 ?props.default_value-2:props.default_value-20//
  16. const maxNum: number = props.max;//props.step < 1 ?props.default_value+2:props.default_value+20//
  17. const [timer, setTimer] = useState(null)
  18. const [leftData, setLeftData] = useState(0)
  19. const stepNum: number = props.step * 10;
  20. const jingdu: number = props.step < 1 ? 10 : 1;
  21. const list: any[] = [];
  22. const slidngWidth = 10
  23. const [current, setCurrent] = useState(props.default_value)
  24. const [left, setLeft] = useState((props.default_value - minNum) * slidngWidth / props.step + 1);
  25. const [isDraging, setIsDraging] = useState(false)
  26. const [timeoutId, setTimeoutId] = useState(null);
  27. // const [showScrollView, setShowScrollView] = useState(false)
  28. for (var i: number = minNum; i <= maxNum; i += props.step) {
  29. var value: number = parseFloat(i.toFixed(1));
  30. var isBig: boolean = Math.round((value - minNum) * jingdu) % Math.round(stepNum * jingdu) == 0;
  31. var isMiddle: boolean = (Math.round((value - minNum) * jingdu) * 2) % Math.round(stepNum * jingdu) == 0;
  32. list.push({
  33. value: props.step < 1 ? value : Math.round(value),
  34. showBig: isBig && i >= minNum && i <= maxNum,
  35. showMiddle: isMiddle && !isBig && i >= minNum && i <= maxNum
  36. })
  37. }
  38. // useEffect(() => {
  39. // setTimeout(() => {
  40. // setShowScrollView(true)
  41. // }, 200)
  42. // }, [])
  43. // const dpr = Taro.pxTransform//Taro.getSystemInfoSync().pixelRatio;
  44. useEffect(() => {
  45. let timeoutId;
  46. }, [])
  47. function scrollContent(e) {
  48. if (timerA)
  49. clearTimeout(timerA);
  50. timerA = setTimeout(() => {
  51. update(e)
  52. }, 90) as any
  53. }
  54. const handleScroll = throttle((e) => {
  55. console.log(e)
  56. if (timer) {
  57. clearTimeout(timer)
  58. setTimer(null)
  59. }
  60. if (leftData != e.detail && !isDraging) {
  61. setLeftData(e.detail)
  62. var timer2 = setTimeout(() => {
  63. console.log('aaa')
  64. update(e)
  65. }, 90)
  66. setTimer(timer2 as any)
  67. }
  68. },200);
  69. function dragStart(e) {
  70. setIsDraging(true)
  71. }
  72. function dragEnd(e) {
  73. setIsDraging(false)
  74. }
  75. function update(e) {
  76. const { scrollLeft } = e.detail;
  77. var count = scrollLeft / slidngWidth;
  78. var strValue = (minNum + Math.round(count) * props.step).toFixed(1);
  79. if ((strValue as any) < minNum) {
  80. strValue = minNum as any;
  81. }
  82. if ((strValue as any) > maxNum) {
  83. strValue = maxNum as any;
  84. }
  85. if (parseFloat(strValue) != current) {
  86. var data = strValue as any;
  87. if (props.step < 1) {
  88. data = parseFloat(strValue).toFixed(1);
  89. if (data.indexOf('.') > 0) {
  90. const regexp = /(?:\.0*|(\.\d+?)0+)$/
  91. data = data.replace(regexp, '$1')
  92. }
  93. }
  94. else {
  95. data = Math.round(data);
  96. }
  97. setCurrent(data);
  98. props.changed(data);
  99. }
  100. }
  101. const scrollEnd = (e) => {
  102. console.log(e, 'end')
  103. // const { scrollLeft } = e.detail;
  104. // setLeft(scrollLeft)
  105. }
  106. function itemContent(data) {
  107. var item = list[data.index]
  108. var index = data.index
  109. return <View className={item.showBig ? 'slidng_item_big' : item.showMiddle ? 'slidng_item_middle' : 'slidng_item'} style={{ width: 2, marginRight: 8, backgroundColor: props.themeColor, zIndex: 0 }} key={index}>
  110. {
  111. item.showBig ? <Text className="slidng_text">{item.value}</Text> : null
  112. }
  113. </View>
  114. }
  115. return <View className="slidng">
  116. <View className="number_bg">
  117. <Text className="number">{current}</Text>
  118. <Text className="unit">{props.unit}</Text>
  119. </View>
  120. <View className="scroll_bg">
  121. <View className="shadow_top" />
  122. <View className="shadow_left" />
  123. <View className="shadow_right" />
  124. <View className="top_line" style={{ backgroundColor: props.themeColor }} />
  125. <ScrollView
  126. style={{ zIndex: 0, position: 'relative' }} ref={scrollViewRef}
  127. scrollX scrollLeft={left} className="scroll"
  128. enablePassive={true}
  129. fastDeceleration={true}
  130. onScrollEnd={scrollEnd}
  131. onDragEnd={dragEnd}
  132. onDragStart={dragStart}
  133. onScroll={handleScroll}
  134. enhanced
  135. >
  136. <View className="scrollContent">
  137. <View className="scrollPadding" />
  138. <View className="content">
  139. {
  140. list.map((item, index) => {
  141. return <View className={item.showBig ? 'slidng_item_big' : item.showMiddle ? 'slidng_item_middle' : 'slidng_item'}
  142. style={{ width: 2, marginRight: 8, backgroundColor: props.themeColor, zIndex: 0 }} key={index}>
  143. {
  144. item.showBig ? <Text className="slidng_text">{item.value}</Text> : null
  145. }
  146. </View>
  147. })
  148. }
  149. {/* <View style={{position:'fixed',right:0,top:0,width:100,bottom:0,backgroundColor:'red',zIndex:10}}/> */}
  150. </View>
  151. <View className="scrollPadding" />
  152. </View>
  153. </ScrollView>
  154. {/* <VirtualList height={rpxToPx(300)} width={rpxToPx(750)} onScroll={handleScroll} layout="horizontal"
  155. initialScrollOffset={left}
  156. itemCount={list.length}
  157. item={itemContent}
  158. itemSize={10}
  159. itemData={list}
  160. /> */}
  161. <Image className="center_line" src={require('@assets/images/scale_center.png')} />
  162. {/* <View className="center_line" /> */}
  163. </View>
  164. </View>
  165. }