| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- 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';
- var currentValue = 0;
- export default function (props: { onChanged?: Function, value?: number, edit?: boolean, isPreMeal?: 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 { t } = useTranslation()
- useEffect(() => {
- // if (props.value) {
- // setBrightness(props.value * 10)
- // }
- }, [props.value])
- const handleTouchStart = (event) => {
- setIsSliding(true);
- setStartX(event.touches[0].clientX);
- };
- const handleTouchMove = (event) => {
- 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;
- setValue(calculateNumber(brightnessValue))
- }
- };
- const handleTouchEnd = () => {
- setIsSliding(false);
- 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') : t('feature.food.post_meal_confirm_title'),
- content: value + '分 - ' + obj[0].description ?? '暂无描述',
- success: function (res) {
- if (res.confirm) {
- props.onChanged && props.onChanged(value);
- }
- else {
- if (props.isPreMeal) {
- setStartX(0);
- setBrightness(0)
- setValue(0)
- }
- else {
- setBrightness(props.value! * 10)
- setValue(props.value!)
- }
- }
- }
- })
- }
- if (props.edit) {
- if (startX != 0 && value != 0) {
- // 松手后,滑块动画移动到最左边
- Taro.vibrateShort({
- type: 'heavy'
- })
- // Taro.showToast({
- // icon: 'none',
- // title: '请先上传!'
- // })
- Taro.showModal({
- title: '提示',
- content: t('feature.food.pre_meal_enforce_order_alert'),
- showCancel: false,
- confirmText: '好的',
- success: function (res) {
- if (res.confirm) {
- 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 ?? '暂无描述'
- }
- 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 - 120) + rpxToPx(28) }}>
- <Text className='slider-tip-title'>{props.isPreMeal || !props.onChanged ?
- t('feature.food.slider_tip_pre_meal_title') :
- t('feature.food.slider_tip_post_meal_title')}</Text>
- <Text className='slider-tip-desc'>{props.isPreMeal || !props.onChanged ?
- t('feature.food.slider_tip_pre_meal_desc') :
- t('feature.food.slider_tip_post_meal_desc')}</Text>
- </View>
- <View className='slider-item-bg' style={{ width: brightness * 0.01 * rpxToPx(sliderWidth - 120) + rpxToPx(112) }}>
- </View>
- <View className='slider-item' style={{
- width: brightness * 0.01 * rpxToPx(sliderWidth - 120) + rpxToPx(112),
- backgroundColor: brightness <= 50 ? ColorType.fast : ColorType.food,
- opacity: calculateOpacity(brightness),
- }}>
- </View>
- {
- isSliding || value != 0 ? <View className='slider-text-bg'>
- <Text className='slider-text'>{value}</Text>
- </View> :
- <View className='slider-arrow-bg'>
- <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'>{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>
- }
|