zoukankan      html  css  js  c++  java
  • taro3.x: h5-MovableView兼容解决

    MovableView不支持h5,使用onTouchMove实现拖拽

    main.tsx

    import React, { useEffect, useState } from 'react'
    import Taro from '@tarojs/taro'
    import {
        View,
        Image,
        Text,
        Label,
        CheckboxGroup,
        Checkbox,
        MovableArea,
        MovableView
    } from '@tarojs/components'
    import classnames from 'classnames'
    import find from 'lodash/find'
    import includes from 'lodash/includes'
    
    import api from '@services/api'
    import app from '@services/request'
    import './index.scss'
    
    interface ISandState {
        value: string
        text: string
        checked: boolean
    }
    
    const INIT_SAND_STATE: ISandState[] = [
        {
            value: '1',
            text: '在售',
            checked: true
        },
        {
            value: '2',
            text: '待售',
            checked: true
        },
        {
            value: '3',
            text: '售完',
            checked: true
        }
    ]
    
    interface IShowState {
        show: boolean
        text: string
    }
    
    const INIT_SAND_DATA = {
        sandBuilding: []
    }
    
    const INIT_SHOW_STATE = { show: true, text: '收起' }
    
    interface IProps {
        houseId: string,
        outerWidth?: number,
        outerHeight: number,
        currentBuilding?: any,
        setCurrentBuilding: (any) => void,
        updateSandBuilding: (any) => void
    }
    
    let lastPointX: number = 0
    let lastPointY: number = 0
    let imgTop: number = 0
    let imgLeft: number = 0
    let maxLeft: number = 0
    let maxTop: number = 0
    
    const SandCommon = (props: IProps) => {
        const { houseId, outerHeight, currentBuilding = {} } = props
        const [movableView, setMovableView] = useState<any>({})
        const [showState, setShowState] = useState<IShowState>(INIT_SHOW_STATE)
        const [sandState, setSandState] = useState<ISandState[]>(INIT_SAND_STATE)
        const [sandData, setSandData] = useState<any>(INIT_SAND_DATA)
        const [sandBuilding, setSandBuilding] = useState<any>(INIT_SAND_DATA.sandBuilding)
        const [current, setCurrent] = useState<any>({})
        const screenWidth = Taro.getSystemInfoSync().screenWidth
        const outerWidth = props.outerWidth ? props.outerWidth : screenWidth
    
        useEffect(() => {
            fetchSand()
        }, [houseId])
    
        useEffect(() => {
            setCurrent(currentBuilding)
        }, [currentBuilding])
    
        const setImageRealSize = (fang_sand_pic: string) => {
            Taro.getImageInfo({
                src: fang_sand_pic,
                success: (result: any) => {
                    setMovableView({
                         result.width,
                        height: result.height,
                        centerX: (outerWidth - result.width) / 2,
                        centerY: (outerHeight - result.height) / 2
                    })
                }
            })
        }
    
        const fetchSand = () => {
            app.request({
                url: app.areaApiUrl(api.getHouseSand),
                data: {
                    id: houseId
                }
            }, { loading: false }).then((result: any) => {
                setSandData(result)
                setImageRealSize(result.fang_sand_pic)
                showSandBuilding(INIT_SAND_STATE, result.sandBuilding)
                props.updateSandBuilding(result.sandBuilding)
            })
        }
    
        const toggleShowState = () => {
            setShowState({
                show: !showState.show,
                text: showState.show ? '展开' : '收起'
            })
        }
    
        const handleCheckboxChange = (e: any) => {
            const values = e.detail.value
            for (const item of sandState) {
                if (includes(values, item.value)) {
                    item.checked = true
                } else {
                    item.checked = false
                }
            }
            setSandState(sandState)
            showSandBuilding(sandState, sandData.sandBuilding)
        }
    
        const showSandBuilding = (sandState, allSandBUilding) => {
            let sandBuilding: any[] = []
            for (const item of allSandBUilding) {
                const target = find(sandState, { value: item.sale_status })
                if (target.checked) {
                    sandBuilding.push(item)
                }
            }
            setSandBuilding(sandBuilding)
        }
    
        const switchCurrent = (item: any) => {
            props.setCurrentBuilding(item)
        }
    
        const handleTouchStart = (e: any) => {
            const sandView: any = document.getElementsByClassName('sand-view')[0]
            maxLeft = outerWidth - movableView.width
            maxTop = outerHeight - movableView.height
            lastPointX = e.touches[0].clientX;
            lastPointY = e.touches[0].clientY;
            imgLeft = parseFloat(sandView.style.left)
            imgTop = parseFloat(sandView.style.top)
        }
    
        const handleTouchMove = (e: any) => {
            e.preventDefault();
            let changeX = e.touches[0].clientX - lastPointX;
            let changeY = e.touches[0].clientY - lastPointY;
            let disX = imgLeft + changeX;
            let disY = imgTop + changeY;
            setMovableView({
                ...movableView,
                centerX: Math.max(Math.min(disX, 0), maxLeft),
                centerY: Math.max(Math.min(disY, 0), maxTop)
            })
        }
    
        const renderSandBuilding = () => {
            return sandBuilding.map((item: any, index: number) => (
                <View
                    key={index}
                    style={item.style}
                    className={classnames('sand-item', `sale-status-${item.sale_status}`, current.id === item.id && 'actived')}
                    onClick={() => switchCurrent(item)}
                >
                    <Text>{item.name}</Text>
                    <Text className="triangle-down"></Text>
                </View>
            ))
        }
    
        const renderMovableView = () => {
            const { width, height, centerX, centerY } = movableView
            return IS_H5 ?
                (
                    <View className="sand-area">
                        <View
                            className="sand-view"
                            style={{
                                 `${width}px`,
                                height: `${height}px`,
                                left: `${centerX}px`,
                                top: `${centerY}px`
                            }}
                            onTouchStart={handleTouchStart}
                            onTouchMove={handleTouchMove}
                        >
                            <Image className="taro-image" src={sandData.fang_sand_pic} />
                            {renderSandBuilding()}
                        </View>
                    </View>
                ) :
                (
                    <MovableArea className="sand-area">
                        <MovableView
                            x={centerX}
                            y={centerY}
                            style={{ width, height }}
                            className="sand-view"
                            direction="all"
                            animation={false}
                        >
                            <Image className="taro-image" src={sandData.fang_sand_pic} />
                            {renderSandBuilding()}
                        </MovableView>
                    </MovableArea>
                )
        }
    
        return (
            <View className="sand-card" style={{  '100%', height: `${outerHeight}px` }}>
                {renderMovableView()}
                <View className="sand-state">
                    <CheckboxGroup
                        onChange={handleCheckboxChange}
                        className={classnames('sand-state-box', !showState.show && 'hide')}
                    >
                        {
                            sandState.map((item: any, index: any) => (
                                <Label
                                    key={index}
                                    for={index}
                                    className={classnames('check-label', `sale-status-${item.value}`)}
                                >
                                    <Checkbox
                                        id={index}
                                        className="check-box"
                                        value={item.value}
                                        checked={item.checked}
                                    >
                                    </Checkbox>
                                    <Text className="check-text">{item.text}</Text>
                                </Label>
                            ))
                        }
                    </CheckboxGroup>
                    <View className="sand-state-btn" onClick={toggleShowState}>{showState.text}</View>
                </View>
            </View>
        )
    }
    export default SandCommon
  • 相关阅读:
    PyCharm小技巧
    How to install torcs package in Debian
    QT4.8.6静态编译
    Debian初识(选择最佳镜像发布站点加入source.list文件)
    Dev-C++ 小问题锦集
    ubuntu 12.04lts 安装mysql ,并通过QT连接
    win7下安装ubuntu14.04lts 双系统
    cmake打印变量值
    驾车常识:小轿车灯光
    汽车点火开关的功能介绍
  • 原文地址:https://www.cnblogs.com/Nyan-Workflow-FC/p/14430960.html
Copyright © 2011-2022 走看看