slider.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  2. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  3. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  4. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  5. return c > 3 && r && Object.defineProperty(target, key, r), r;
  6. };
  7. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  8. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  9. return new (P || (P = Promise))(function (resolve, reject) {
  10. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  11. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  12. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  13. step((generator = generator.apply(thisArg, _arguments || [])).next());
  14. });
  15. };
  16. import { SuperComponent, wxComponent } from '../common/src/index';
  17. import config from '../common/config';
  18. import { trimSingleValue, trimValue } from './tool';
  19. import props from './props';
  20. const { prefix } = config;
  21. const name = `${prefix}-slider`;
  22. let Slider = class Slider extends SuperComponent {
  23. constructor() {
  24. super(...arguments);
  25. this.externalClasses = [
  26. `${prefix}-class`,
  27. `${prefix}-class-bar`,
  28. `${prefix}-class-bar-active`,
  29. `${prefix}-class-bar-disabled`,
  30. `${prefix}-class-cursor`,
  31. ];
  32. this.properties = props;
  33. this.controlledProps = [
  34. {
  35. key: 'value',
  36. event: 'change',
  37. },
  38. ];
  39. this.data = {
  40. sliderStyles: '',
  41. classPrefix: name,
  42. initialLeft: null,
  43. initialRight: null,
  44. activeLeft: 0,
  45. activeRight: 0,
  46. maxRange: 0,
  47. lineLeft: 0,
  48. lineRight: 0,
  49. dotTopValue: [0, 0],
  50. _value: 0,
  51. blockSize: 20,
  52. isScale: false,
  53. scaleArray: [],
  54. scaleTextArray: [],
  55. prefix,
  56. };
  57. this.observers = {
  58. value(newValue) {
  59. this.handlePropsChange(newValue);
  60. },
  61. _value(newValue) {
  62. const { min, max, range } = this.properties;
  63. const { maxRange, blockSize } = this.data;
  64. const fullLineWidth = maxRange + Number(blockSize);
  65. if (range) {
  66. const left = (fullLineWidth * (newValue[0] - Number(min))) / (Number(max) - Number(min));
  67. const right = (fullLineWidth * (Number(max) - newValue[1])) / (Number(max) - Number(min));
  68. this.setDotStyle(left, right);
  69. }
  70. else {
  71. const left = (fullLineWidth * (Number(newValue) - Number(min))) / (Number(max) - Number(min));
  72. this.setDotStyle(left, null);
  73. this.getSingleBarWidth(newValue);
  74. }
  75. },
  76. marks(val) {
  77. this.handleMask(val);
  78. },
  79. };
  80. }
  81. attached() {
  82. const { value } = this.properties;
  83. if (!value)
  84. this.handlePropsChange(0);
  85. this.getInitialStyle();
  86. }
  87. triggerValue(value) {
  88. this._trigger('change', {
  89. value: trimValue(value, this.properties),
  90. });
  91. }
  92. handlePropsChange(newValue) {
  93. const value = trimValue(newValue, this.properties);
  94. const setValueAndTrigger = () => {
  95. this.setData({
  96. _value: value,
  97. });
  98. };
  99. if (this.data.maxRange === 0) {
  100. this.getInitialStyle().then(setValueAndTrigger);
  101. return;
  102. }
  103. setValueAndTrigger();
  104. }
  105. handleMask(marks) {
  106. if ((marks === null || marks === void 0 ? void 0 : marks.length) && Array.isArray(marks)) {
  107. this.setData({
  108. isScale: true,
  109. scaleArray: marks,
  110. scaleTextArray: [],
  111. });
  112. }
  113. if (Object.prototype.toString.call(marks) === '[object Object]') {
  114. const scaleArray = Object.keys(marks).map((item) => Number(item));
  115. const scaleTextArray = scaleArray.map((item) => marks[item]);
  116. this.setData({
  117. isScale: scaleArray.length > 0,
  118. scaleArray,
  119. scaleTextArray,
  120. });
  121. }
  122. }
  123. getSingleBarWidth(value) {
  124. const { max, min } = this.properties;
  125. const width = `${((Number(value) - Number(min)) * 100) / (Number(max) - Number(min))}%`;
  126. this.setData({
  127. lineBarWidth: width,
  128. });
  129. }
  130. getSelectorQuery(id) {
  131. return new Promise((resolve, reject) => {
  132. wx.createSelectorQuery()
  133. .in(this)
  134. .select(`#${id}`)
  135. .boundingClientRect((rect) => {
  136. if (rect) {
  137. resolve(rect);
  138. }
  139. else {
  140. reject(rect);
  141. }
  142. })
  143. .exec();
  144. });
  145. }
  146. getInitialStyle() {
  147. return __awaiter(this, void 0, void 0, function* () {
  148. const line = yield this.getSelectorQuery('sliderLine');
  149. const { blockSize } = this.data;
  150. const halfBlock = Number(blockSize) / 2;
  151. this.setData({
  152. maxRange: line.right - line.left - Number(blockSize),
  153. initialLeft: line.left - halfBlock,
  154. initialRight: line.right + halfBlock,
  155. });
  156. });
  157. }
  158. setDotStyle(left, right) {
  159. const { range } = this.properties;
  160. const { blockSize } = this.data;
  161. const halfBlock = Number(blockSize) / 2;
  162. if (left !== null) {
  163. this.setData({
  164. activeLeft: left - halfBlock,
  165. });
  166. }
  167. if (right !== null) {
  168. this.setData({
  169. activeRight: right - halfBlock,
  170. });
  171. }
  172. if (range) {
  173. this.setLineStyle();
  174. const [a, b] = this.data._value;
  175. this.setData({
  176. dotTopValue: [a, b],
  177. });
  178. }
  179. }
  180. stepValue(value) {
  181. const { step, min, max } = this.properties;
  182. if (Number(step) < 1 || Number(step) > Number(max) - Number(min))
  183. return value;
  184. const closestStep = trimSingleValue(Math.round(value / Number(step)) * Number(step), Number(min), Number(max));
  185. return closestStep;
  186. }
  187. onSingleLineTap(e) {
  188. const { disabled } = this.properties;
  189. if (disabled)
  190. return;
  191. const value = this.getSingleChangeValue(e);
  192. this.triggerValue(value);
  193. }
  194. getSingleChangeValue(e) {
  195. const { min, max } = this.properties;
  196. const { initialLeft, maxRange, blockSize } = this.data;
  197. const [touch] = e.changedTouches;
  198. const { pageX } = touch;
  199. const halfBlock = Number(blockSize) / 2;
  200. const currentLeft = pageX - initialLeft - halfBlock;
  201. let value = 0;
  202. if (currentLeft <= 0) {
  203. value = Number(min);
  204. }
  205. else if (currentLeft >= maxRange + Number(blockSize)) {
  206. value = Number(max);
  207. }
  208. else {
  209. value = Math.round((currentLeft / (maxRange + Number(blockSize))) * (Number(max) - Number(min)) + Number(min));
  210. }
  211. return this.stepValue(value);
  212. }
  213. convertPosToValue(posValue, dir) {
  214. const { maxRange, blockSize } = this.data;
  215. const { max, min } = this.properties;
  216. const fullLineWidth = maxRange + blockSize;
  217. return dir === 0
  218. ? (posValue / fullLineWidth) * (Number(max) - Number(min)) + Number(min)
  219. : Number(max) - (posValue / fullLineWidth) * (Number(max) - Number(min));
  220. }
  221. onLineTap(e) {
  222. const { disabled } = this.properties;
  223. const { initialLeft, initialRight, maxRange, blockSize } = this.data;
  224. if (disabled)
  225. return;
  226. const [touch] = e.changedTouches;
  227. const { pageX } = touch;
  228. const halfBlock = Number(blockSize) / 2;
  229. const currentLeft = pageX - initialLeft - halfBlock;
  230. if (currentLeft < 0 || currentLeft > maxRange + Number(blockSize))
  231. return;
  232. this.getSelectorQuery('leftDot').then((leftDot) => {
  233. this.getSelectorQuery('rightDot').then((rightDot) => {
  234. const distanceLeft = Math.abs(pageX - leftDot.left - halfBlock);
  235. const distanceRight = Math.abs(rightDot.left - pageX + halfBlock);
  236. const isMoveLeft = distanceLeft < distanceRight;
  237. if (isMoveLeft) {
  238. const left = pageX - initialLeft - halfBlock;
  239. const leftValue = this.convertPosToValue(left, 0);
  240. this.triggerValue([this.stepValue(leftValue), this.data._value[1]]);
  241. }
  242. else {
  243. const right = -(pageX - initialRight) - halfBlock;
  244. const rightValue = this.convertPosToValue(right, 1);
  245. this.triggerValue([this.data._value[0], this.stepValue(rightValue)]);
  246. }
  247. });
  248. });
  249. }
  250. onTouchMoveLeft(e) {
  251. const { disabled } = this.properties;
  252. const { initialLeft, blockSize, _value } = this.data;
  253. if (disabled)
  254. return;
  255. const [touch] = e.changedTouches;
  256. const { pageX } = touch;
  257. const halfBlock = Number(blockSize) / 2;
  258. const currentLeft = pageX - initialLeft - halfBlock;
  259. const newData = [..._value];
  260. const leftValue = this.convertPosToValue(currentLeft, 0);
  261. newData[0] = this.stepValue(leftValue);
  262. this.triggerValue(newData);
  263. }
  264. onTouchMoveRight(e) {
  265. const { disabled } = this.properties;
  266. const { initialRight, blockSize, _value } = this.data;
  267. if (disabled)
  268. return;
  269. const [touch] = e.changedTouches;
  270. const { pageX } = touch;
  271. const halfBlock = Number(blockSize) / 2;
  272. const currentRight = -(pageX - initialRight) - halfBlock;
  273. const newData = [..._value];
  274. const rightValue = this.convertPosToValue(currentRight, 1);
  275. newData[1] = this.stepValue(rightValue);
  276. this.triggerValue(newData);
  277. }
  278. setLineStyle() {
  279. const { activeLeft, activeRight, maxRange, blockSize } = this.data;
  280. const halfBlock = Number(blockSize) / 2;
  281. if (activeLeft + activeRight <= maxRange) {
  282. this.setData({
  283. lineLeft: activeLeft + halfBlock,
  284. lineRight: activeRight + halfBlock,
  285. });
  286. }
  287. else {
  288. this.setData({
  289. lineLeft: maxRange + halfBlock - activeRight,
  290. lineRight: maxRange - activeLeft + halfBlock * 1.5,
  291. });
  292. }
  293. }
  294. };
  295. Slider = __decorate([
  296. wxComponent()
  297. ], Slider);
  298. export default Slider;