天天看點

Ant Design Pro (六) 簡易Marquee

1. 添加元件代碼

新增src/pages/Demo/components/Marquee.tsx

代碼如下

import React, { PureComponent } from 'react';


/**
 * 參考
 * https://blog.csdn.net/adsfa23124/article/details/101769001
 * https://wenku.baidu.com/view/b70bbb0390c69ec3d5bb75b9.html
 * https://www.jb51.net/css/94991.html
*/
interface IMarqueeProps {
    fontSize?:number,
    bold?: boolean,
    color?:string,
    text?:string,
    state?:string,
};


class Marquee extends PureComponent<IMarqueeProps> {
    state = {
        pos: 0,
        float: 'right',
        dir: 'right',
    }

    interval : any;
    action = () => {
        this.interval = setInterval(() => {
        let marqueeElement = document.getElementById("marquee")
        if (marqueeElement === null) { return }

        let marquee = marqueeElement.getBoundingClientRect();
        let marqueePar = document.getElementById("marqueeParent")?.getBoundingClientRect()
        if (marquee === undefined || marqueePar === undefined) return;

        // let textWidth = parseFloat(window.getComputedStyle(marqueeElement).width);
        let dir = this.state.dir
        let pos = 0
        /* 判斷邊界 */
        if (marquee.x < marqueePar.x) { // 左邊界
            dir = 'right'
        }else if (marqueePar.x + marqueePar.width  <= marquee.x){ // 右邊界
            dir = 'left'
        }

        if  (this.state.dir == 'right'){
            pos = this.state.pos - 1
        }else{
            pos = this.state.pos + 1
        }
        this.setState({
            pos: pos,
            dir: dir
        })
        }, 10)  //定時器
    }

    componentWillUnmount = () => {
        if (this.interval) {
            clearInterval(this.interval);  
        }
    }

    start = () => {
        if (this.interval) {
            return 
        }
        this.action()
    }

    stop = () => {
        if (this.interval) {
            clearInterval(this.interval);
            this.interval = null
        }
    }

    render() {
        if (this.props.state == 'start') {
            this.start()
        } else if (this.props.state == 'stop') {
            this.stop()
        }

        return (
            <div id = 'marqueeParent'>
                <div id = 'marquee' style = 
                    {{ 
                        float: 'right',
                        position: 'relative', 
                        right: this.state.pos +'px',
                        fontSize: this.props.fontSize +'px',
                        fontWeight: this.props.bold? 'bold' : 'normal',
                        color: this.props.color
                    }}
                > { this.props.text } </div>
            </div>
        )
    }
}

export default Marquee;
           

2. 添加代碼使用

添加到Demo頁面

import { Card, Tabs, Input, Typography, Space, message, Button } from 'antd';
import styleObj from '../components/style'

import React from 'react';
import { useState } from 'react';
import { postData, getData } from '@/services/demo';
import Marquee from './components/Marquee'

const { Text } = Typography;
const { Search } = Input;


const DemoPage: React.FC = () => {
    const [currentKey, setCurrentKey] = useState("1");
    const [tabText1, setTabText1] = useState("Tab1");
    const [tabText2, setTabText2] = useState("Tab2");
    const [tabText3, setTabText3] = useState("Tab3");
    const [marqueeState, setMarqueeState] = useState('start');

    const handleOnChange = (key:string) => {
        console.log("handleOnChange: " + key);
        setCurrentKey(key);
    }

    const onStop = ()=>{
        setMarqueeState('stop');
    }

    const onStart = ()=>{
        setMarqueeState('start');
    }

    async function onSearch (text:string) {
        // console.log("Current Key: ", currentKey, ", On Search Text: ", text);
        
        let dat = { text: text };
        try {
            switch (currentKey){
                case '1': {
                    let result = await postData(dat);
                    setTabText1(result.data.text);
                    break;
                } 
                case '2': {
                    let result = await getData(dat);
                    setTabText2(result.data.text);
                    break;
                }
                case '3': {
                    let result = await postData(dat);
                    setTabText3(result.data.text);
                    break;
                }
                default: {break;}
            }
            message.success("successful");
          } catch (error) {
            // message.error("unknown error");
          }
          return;
    }


    return (
        <div className="site-card-border-less-wrapper">
        <Card title='demo_page' style={styleObj.CardStyle} headStyle =  {styleObj.HeadStyle}>
        <Tabs defaultActiveKey="1" activeKey={ currentKey } onChange={ handleOnChange }>
        <Tabs tab="Demo_Tab_1" key="1"/> 
        <Tabs tab="Demo_Tab_2" key="2"/>
        <Tabs tab="Demo_Tab_3" key="3"/>
        </Tabs>
        {
            currentKey === '1' && (
                <Space direction="vertical">
                    <Search placeholder="input search text1" onSearch={onSearch} enterButton />
                    <Text> { tabText1 } </Text>
                </Space>
            )
        }
        {
            currentKey === '2' && (
                <Space direction="vertical">
                    <Search placeholder="input search text2" onSearch={onSearch} enterButton />
                    <Text> { tabText2 } </Text>
                </Space>
            )
        }
        {
            currentKey === '3' && (
                <Space direction="vertical">
                    <Marquee text = "你好世界,1111" state = {marqueeState} bold = {true} fontSize = {80} />
                    <Button icon="start" onClick={onStart} > 開始 </Button>
                    <Button icon="pause" onClick={onStop} > 暫停 </Button>
                </Space>
                // <Space direction="vertical">
                //     <Search placeholder="input search text3" onSearch={onSearch} enterButton />
                //     <Text> { tabText3 } </Text>
                // </Space>
            )
        }
        </Card>
        </div>
    );
};

export default DemoPage;
           

3. 界面效果

Ant Design Pro (六) 簡易Marquee

Ant Design Pro 使用筆記

繼續閱讀