| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- import { View, Text, Image } from '@tarojs/components'
- import './Slider.scss'
- import { ColorType } from '@/context/themes/color'
- import { useEffect, useRef, useState } from 'react';
- import { rpxToPx } from '@/utils/tools';
- import Taro from '@tarojs/taro';
- import { useSelector } from 'react-redux';
- import { useTranslation } from 'react-i18next';
- import { jumpPage } from '@/features/trackTimeDuration/hooks/Common';
- var currentValue = 0;
- var lastValue = 0;
- export default function (props: { onChanged?: Function, value?: number, edit?: boolean, isPreMeal?: boolean, isPostMeal?: boolean, id?: string }) {
- const sliderWidth = 578;
- const [brightness, setBrightness] = useState(props.value ? props.value * 10 : 0);
- const [isSliding, setIsSliding] = useState(false);
- const [value, setValue] = useState(props.value ? props.value : 0)
- const [startX, setStartX] = useState(0);
- const common = useSelector((state: any) => state.common);
- const user = useSelector((state: any) => state.user);
- const [showArrow, setShowArrow] = useState(true)
- const { t } = useTranslation()
- useEffect(() => {
- // if (props.value) {
- // setBrightness(props.value * 10)
- // }
- }, [props.value])
- const handleTouchStart = (event) => {
- if (!user.isLogin) {
- jumpPage('/pages/account/ChooseAuth', 'ChooseAuth')
- return
- }
- setIsSliding(true);
- setShowArrow(false);
- setStartX(event.touches[0].clientX);
- };
- const handleTouchMove = (event) => {
- if (!user.isLogin) {
- return
- }
- if (isSliding) {
- const { touches } = event;
- const touchX = touches[0].clientX;
- const deltaX = touchX - startX;
- // console.log(deltaY,startY,touchY)
- // const containerHeight = rpxToPx(182); // 容器高度,根据实际情况调整
- let brightnessValue = brightness + deltaX / rpxToPx(sliderWidth - 120) * 100;// / containerHeight * 100;
- // 边界限制
- brightnessValue = Math.max(0, Math.min(brightnessValue, 100));
- brightnessValue = Math.round(brightnessValue)
- setStartX(touchX)
- setBrightness(brightnessValue);
- currentValue = brightnessValue;
- var data = calculateNumber(brightnessValue)
- if (lastValue != data && data == 5) {
- Taro.vibrateShort({
- type: 'light'
- })
- }
- lastValue = data
- setValue(data)
- }
- };
- const handleTouchEnd = () => {
- if (!user.isLogin) {
- return
- }
- setIsSliding(false);
- Taro.vibrateShort({
- type: 'light'
- })
- if (props.onChanged) {
- var obj = common.food_scales.filter((item: any) => {
- return item.point == value
- })
- Taro.showModal({
- title: props.isPreMeal ? t('feature.food.pre_meal_confirm_title', { score: value, desc: value < 5 ? '饿' : '饱' }) : t('feature.food.post_meal_confirm_title', { score: value, desc: value < 5 ? '饿' : '饱' }),
- content: obj[0].description ? obj[0].description : '暂无描述',
- success: function (res) {
- if (res.confirm) {
- props.onChanged && props.onChanged(value);
- }
- else {
- setShowArrow(true)
- if (props.isPreMeal) {
- setStartX(0);
- setBrightness(0)
- setValue(0)
- }
- else {
- setBrightness(props.value! * 10)
- setValue(props.value!)
- }
- }
- }
- })
- }
- if (props.edit) {
- // 松手后,滑块动画移动到最左边
- // Taro.showToast({
- // icon: 'none',
- // title: '请先上传!'
- // })
- Taro.showModal({
- title: t('feature.common.prompt'),
- content: t('feature.food.pre_meal_enforce_order_alert'),
- showCancel: false,
- confirmText: '好的',
- success: function (res) {
- if (res.confirm) {
- setShowArrow(true)
- setStartX(0);
- setBrightness(0)
- setValue(0)
- }
- }
- })
- // const animationId = requestAnimationFrame(moveToStart);
- // return () => cancelAnimationFrame(animationId);
- }
- };
- const moveToStart = () => {
- const newPosition = Math.max(currentValue - 8, 0);
- currentValue = newPosition
- setBrightness(newPosition)
- setValue(calculateNumber(newPosition))
- if (newPosition > 0) {
- requestAnimationFrame(moveToStart);
- } else {
- setStartX(0);
- setBrightness(0)
- }
- };
- function calculateOpacity(number) {
- if (number === 0 || number === 100) {
- return 1;
- } else if (number === 50) {
- return 0;
- } else if (number < 50) {
- return 1 - (number / 50);
- } else {
- return (number - 50) / 50;
- }
- }
- function calculateNumber(number) {
- if (number <= 2) {
- return 0;
- } else if (number <= 7) {
- return 0.5;
- } else {
- var result = Math.floor(number / 10);
- var decimal = number % 10;
- if (decimal >= 3 && decimal <= 7) {
- return result + 0.5;
- } else if (decimal >= 8 && decimal <= 9) {
- if (result == 9) {
- return 9.5
- }
- return result + 1;
- } else {
- return result;
- }
- }
- }
- function getTitle() {
- var obj = common.food_scales.filter((item: any) => {
- return item.point == value
- })
- return obj[0].name
- }
- function getDesc() {
- var obj = common.food_scales.filter((item: any) => {
- return item.point == value
- })
- return obj[0].description ?? '暂无描述'
- }
- function getSliderTitleClass() {
- if (props.isPostMeal) {
- if (showArrow) {
- return 'slider-tip-title-post'
- }
- }
- return value < 5 ? 'slider-tip-title' : 'slider-tip-title-post'
- }
- function getSliderDescClass() {
- if (props.isPostMeal) {
- if (showArrow) {
- return 'slider-tip-desc-post'
- }
- }
- return value < 5 ? 'slider-tip-desc' : 'slider-tip-desc-post'
- }
- function getSliderTitle() {
- if (props.isPostMeal) {
- if (showArrow) {
- return t('feature.food.slider_tip_post_meal_title')
- }
- }
- return value < 5 ?
- t('feature.food.slider_tip_pre_meal_title') :
- t('feature.food.slider_tip_post_meal_title')
- }
- function getSliderDesc() {
- if (props.isPostMeal) {
- if (showArrow) {
- return t('feature.food.slider_tip_post_meal_desc')
- }
- }
- return value < 5 ?
- t('feature.food.slider_tip_pre_meal_desc') :
- t('feature.food.slider_tip_post_meal_desc')
- }
- function getSliderBgColor() {
- if (props.isPostMeal) {
- if (showArrow) {
- return ColorType.food
- }
- }
- return value == 5 ? '#fff' : value < 5 ? ColorType.fast : ColorType.food
- }
- return <View style={{ display: 'flex', flexDirection: 'column', position: 'relative', width: rpxToPx(578) }}>
- <View className='slider-container'
- catchMove
- onTouchStart={handleTouchStart}
- onTouchMove={handleTouchMove}
- onTouchEnd={handleTouchEnd}>
- <View className='slider-tip-bg' style={{ width: (100 - brightness) * 0.01 * rpxToPx(sliderWidth) - brightness * 0.01 * rpxToPx(120) + brightness * 0.01 * rpxToPx(28) }}>
- <Text className={getSliderTitleClass()}>{getSliderTitle()}</Text>
- <Text className={getSliderDescClass()}>{getSliderDesc()}</Text>
- </View>
- <View className='slider-item-content'>
- <View className='slider-item-bg' style={{
- width: brightness * 0.01 * rpxToPx(sliderWidth - 126) + rpxToPx(112 + 2),
- backgroundColor: getSliderBgColor()//value == 5 ? '#fff' : value < 5 ? ColorType.fast : ColorType.food
- }}>
- {/* <View className='slider-item' style={{
- width: brightness * 0.01 * rpxToPx(sliderWidth - 126) + rpxToPx(112) + 1,
- backgroundColor: brightness <= 50 ? ColorType.fast : ColorType.food,
- opacity: calculateOpacity(brightness),
- }}>
- </View> */}
- </View>
- </View>
- {
- !showArrow ? <View className='slider-text-bg'>
- <Text className='slider-text'>{value}</Text>
- </View> :
- <View className='slider-arrow-bg' style={{ left: props.isPostMeal ? brightness * 0.01 * rpxToPx(sliderWidth - 120) : 0 }}>
- <Image src={require('@assets/images/arrow4.png')} className='slider-arrow' />
- </View>
- }
- </View>
- {
- isSliding && <View className='tooltip_bg'>
- <View style={{ flex: 1 }} />
- <View className='tooltip_content'>
- <Text className='tooltip_title' style={{ color: value == 5 ? '#fff' : value < 5 ? ColorType.fast : ColorType.food }}>{props.isPostMeal ? '餐后' : '餐前'}{getTitle()}</Text>
- <Text className='tooltip_desc'>{getDesc()}</Text>
- </View>
- <View className='tooltip_arrow' style={{ marginLeft: brightness * 0.01 * rpxToPx(sliderWidth - 120) + rpxToPx((120 - 50) / 2) }} />
- </View>
- }
- </View>
- }
|