辽宁工程建设工程信息网站,wordpress4.8版权修改,关键词搜索引擎优化推广,建筑招聘网站有哪些效果#xff1a; 功能点#xff1a;
1、四个档位
2、可点击加减切换档位
3、可以点击区域切换档位
4、可以滑动切换档位
目的#xff1a;
给大家提供一些实现思路#xff0c;找了一圈#xff0c;一些文章基本不能直接用#xff0c;错漏百出#xff0c;代码还藏着掖…效果 功能点
1、四个档位
2、可点击加减切换档位
3、可以点击区域切换档位
4、可以滑动切换档位
目的
给大家提供一些实现思路找了一圈一些文章基本不能直接用错漏百出代码还藏着掖着希望可以帮到大家
代码
ts的写法风格
index.tsx
import { View, ITouchEvent, BaseTouchEvent } from tarojs/components
import Taro from tarojs/taro
import { useState } from react
import styles from ./index.module.less
import classNames from classnames
import { debounce } from ~/utils/utilenum ANGLES {ANGLES_135 -135,ANGLES_90 -90,ANGLES_45 -45,ANGLES_0 0
}enum MODE_VALUE {MODE_1 1,MODE_2 2,MODE_3 3,MODE_4 4
}const HalfCircle () {const [state, setState] useState({originAngle: ANGLES.ANGLES_135,isTouch: false,val: MODE_VALUE.MODE_1,originX: 0,originY: 0})/** 半圆的半径 */const RADIUS 150/** 半径的一半 */const RADIUS_HALF RADIUS / 2/** 4/3 圆的直径 */const RADIUS_THIRD RADIUS_HALF * 3/** 直径 */const RADIUS_DOUBLE RADIUS * 2/** 误差 */const DEVIATION 25/** 是否开启点击振动 */const isVibrateShort trueconst getAngle () {return {transform: rotate(${state.originAngle}deg),transition: all ${state.isTouch ? 0.2s : 0.55s}}}/*** 根据坐标判断是否在半圆轨道上半圆为RADIUS误差为DEVIATION* param pageX* param pageY*/const isInHalfCircleLine (pageX: number, pageY: number, deviation?: number) {const DEVIATION_VALUE deviation || DEVIATIONconst squareSum (pageX - RADIUS) * (pageX - RADIUS) (pageY - RADIUS) * (pageY - RADIUS)const min (RADIUS - DEVIATION_VALUE) * (RADIUS - DEVIATION_VALUE)const max (RADIUS DEVIATION_VALUE) * (RADIUS DEVIATION_VALUE)return squareSum min squareSum max}/** 根据做标点获取档位 0 - 4, -45 - 3, -90 - 2, -135 - 1从而获取旋转的角度 */const setGear (pageX: number, pageY: number) {let val state.vallet originAngle state.originAngleif (isInHalfCircleLine(pageX, pageY)) {if (pageX 0 pageX RADIUS_HALF) {val MODE_VALUE.MODE_1originAngle ANGLES.ANGLES_135} else if (pageX RADIUS_HALF pageX RADIUS) {val MODE_VALUE.MODE_2originAngle ANGLES.ANGLES_90} else if (pageX RADIUS pageX RADIUS_THIRD) {val MODE_VALUE.MODE_3originAngle ANGLES.ANGLES_45} else {val MODE_VALUE.MODE_4originAngle ANGLES.ANGLES_0}}if (state.val val) returnsetState((old) {return {...old,originAngle,val}})if (isVibrateShort) {setTimeout(() {Taro.vibrateShort()}, 200)}}/*** 滑动比较细腻,根据x轴坐标calcX判断是否前进还是后退* param pageX* param pageY*/const setGearSibler (pageX: number, pageY: number) {let val state.vallet originAngle state.originAngleconst calcX pageX - state.originX/** 把误差值增加方便滑动 */if (isInHalfCircleLine(pageX, pageY, 50)) {if (pageX 0 pageX RADIUS_HALF) {if (calcX 0) {/** 向前滑动就前进一个档位 */val MODE_VALUE.MODE_2originAngle ANGLES.ANGLES_90} else {/** 向后滑动就后退一个档位 */val MODE_VALUE.MODE_1originAngle ANGLES.ANGLES_135}} else if (pageX RADIUS_HALF pageX RADIUS) {if (calcX 0) {val MODE_VALUE.MODE_2originAngle ANGLES.ANGLES_90} else {val MODE_VALUE.MODE_1originAngle ANGLES.ANGLES_135}} else if (pageX RADIUS pageX RADIUS_THIRD) {if (calcX 0) {val MODE_VALUE.MODE_3originAngle ANGLES.ANGLES_45} else {val MODE_VALUE.MODE_2originAngle ANGLES.ANGLES_90}} else {if (calcX 0) {val MODE_VALUE.MODE_4originAngle ANGLES.ANGLES_0} else {val MODE_VALUE.MODE_3originAngle ANGLES.ANGLES_45}}}setState((old) {return {...old,originAngle,val}})}/*** 获取正确的坐标点* param pageX* param pageY* returns*/const getRealXY (pageX: number,pageY: number): Promise{realX: numberrealY: number} {return new Promise((resolve) {Taro.createSelectorQuery().select(#sliderBgcId).boundingClientRect((rect) {const { left, top } rect/** 获取真实的做标点 */const realX pageX - leftconst realY pageY - topresolve({realX,realY})}).exec()})}const onTouchEnd (event: BaseTouchEventany) {setState((old) {return {...old,isTouch: false}})}const onTouchMove debounce(async (event: BaseTouchEventany) {const { pageX, pageY } event.changedTouches[0]const { realX, realY } await getRealXY(pageX, pageY)if (isInHalfCircleLine(realX, realY)) {setGearSibler(realX, realY)}}, 100)const onTouchStart async (event: BaseTouchEventany) {const { pageX, pageY } event.changedTouches[0]const { realX, realY } await getRealXY(pageX, pageY)setState((old) {return {...old,originX: realX,originY: realY,isTouch: true}})}/** 点击设置档位 */const onHandleFirstTouch async (event: BaseTouchEventany) {const { pageX, pageY } event.changedTouches[0]const { realX, realY } await getRealXY(pageX, pageY)if (isInHalfCircleLine(realX, realY)) {setGear(realX, realY)}}const lose () {if (state.isTouch) returnif (state.val 1) return Taro.showToast({title: 最低只能1挡,icon: error,duration: 2000})setState((old) {return {...old,originAngle: state.originAngle - 45,val: state.val - 1}})if (isVibrateShort) {Taro.vibrateShort()}}const add () {if (state.isTouch) returnif (state.val 4) return Taro.showToast({title: 最高只能4挡,icon: error,duration: 2000})setState((old) {return {...old,originAngle: state.originAngle 45,val: state.val 1}})if (isVibrateShort) {Taro.vibrateShort()}}return (ViewclassName{styles.slider}// onTouchEnd{(event) onTouchEnd(event)}// onTouchMove{(event) onTouchMove(event)}// onTouchStart{(event) onTouchStart(event)}onClick{onHandleFirstTouch}View className{styles.activeSliderSet}View className{styles.activeSlider} style{getAngle()} //ViewView className{styles.origin} idoriginView className{styles.long} style{getAngle()}ViewclassName{styles.circle}onTouchMove{(event) onTouchMove(event as BaseTouchEventany)}onTouchStart{(event) onTouchStart(event as BaseTouchEventany)}onTouchEnd{(event) onTouchEnd(event as BaseTouchEventany)}//View/View{/* 背景 */}View className{styles.sliderBgc} idsliderBgcId /{/* 刻度 */}{/* View className{styles.scaleBgc} / */}View className{styles.centerContent}View className{styles.centerText}能量档位/ViewView className{styles.btn_air_bar}View className{classNames(styles.btn_air, styles.btn_air_left)} onClick{lose}-/ViewView className{styles.val}View classNameval_text{state.val}/View/ViewView className{classNames(styles.btn_air, styles.btn_air_right)} onClick{add}/View/View/View/View)
}export default HalfCircleindex.module.less
color-brand: #EBC795 ;
borderColor:#706D6D;
sliderWidth:10px;
radius:150px;
long: 150px;
border-radius: long;.slider {position: relative;padding-bottom: sliderWidth / 2;background-color: #000;width: 100vw;display: flex;justify-content: center;align-items: center;// 背景色.sliderBgc {width: long*2;height: long;border: sliderWidth solid;border-radius: border-radius border-radius 0 0;border-color: borderColor;border-bottom: none;}.scaleBgc {width: long*2 sliderWidth *2;height: long sliderWidth;position: absolute;// bottom: 0;// left: 0;border: sliderWidth solid;border-radius: border-radius sliderWidth border-radius sliderWidth 0 0;border-color: transparent;border-bottom: none;top: -10px;background-clip: padding-box, border-box;background-origin: padding-box, border-box;background-image: linear-gradient(to right, #000, #000), linear-gradient(90deg, #FFD1B2, #E49E6B);}// 激活色.activeSliderSet {position: absolute;width: (long) *2;height: long;// left: 0;// bottom: 0;z-index: 2;overflow: hidden;.activeSlider {bottom: 0;left: 0;width: long*2;height: long;border: sliderWidth solid;border-color: color-brand;// border-color: transparent !important;border-radius: border-radius border-radius 0 0;border-bottom: none;transform: rotate(-100deg);transform-origin: long long;// background-clip: padding-box, border-box;// background-origin: padding-box, border-box;// background-image: linear-gradient(to right, #000, #000), linear-gradient(90deg, #FFD1B2, #E49E6B);}}.origin {width: 0;height: 0;position: absolute;background-color: rgba(0, 0, 0, 0.1);bottom: 0;left: 50%;z-index: 11;transform: translateX(50%);.long {width: long - (sliderWidth / 2);height: 0;z-index: 9999;position: absolute;top: 0;left: 0;transform-origin: 0 0;.circle {width: 16px;height: 16px;border-radius: 50%;position: absolute;top: 50%;right: 0;transform: translate(50%, -50%);background-color: #000;border: #fff 4px solid;z-index: 999;padding: 5px;}}}}.centerContent {position: absolute;bottom: 0;left: 50%;transform: translateX(-50%);z-index: 99;margin-bottom: 20px;.centerText {text-align: center;color: var(--q-light-color-text-secondary, var(--text-secondary, #8C8C8C));font-size: 10px;margin-bottom: 25px;}.btn_air_bar {display: flex;align-items: center;.btn_air {width: 30px;height: 30px;border-radius: 50%;background-color: wheat;font-size: 16px;font-weight: 500;display: flex;align-items: center;justify-content: center;}.btn_air_left {background-color: #706D6D;color: white;}.btn_air_right {background-color: white;color: #706D6D;}.val {height: 26px;display: flex;align-items: center;margin: 0 30px;font-size: 26px;font-weight: 700;}}
}
防抖的工具函数debounce 的详细代码
import { debounce } from ~/utils/util
function debounceT extends Function(func: T, delay: number): T {let timeoutreturn function (this: any, ...args: any[]): void {const context this;clearTimeout(timeout);timeout setTimeout(() {func.apply(context, args);}, delay);} as any;
}