【问题标题】:Progress circle bar in React JSReact JS 中的进度条
【发布时间】:2020-08-27 19:29:38
【问题描述】:

我正在创建一个进度圆条,用作计时器和滑块,其中每张幻灯片都有自己的进度条

我可以实现它,但是我无法将条形与其自身同步。

这是正在发生的事情:

如您所见,它无法正常工作。我需要条形图填充 100% 的圆圈,然后继续到下一个点并重复该过程,但是我无法同步它们。

如果我只有一个点,它似乎可以正常工作,但是:

我用的是两个setTimeout,一个是通过percentage的控制来减少circle的属性stroke-dashoffset,这个使bar被填充;第二个setTimeout正是为了让圆圈出现在下面的点周围。我有变量timer,它控制更改的间隔,它位于第二个setTimeout。我相信问题可能出在这两个setTimeout之间的时间上,但这只是一个猜测。

我正在使用钩子,但是我无法让它在 Codepen 上以这种方式工作,因为我创建了一个带有类组件的 codepen,但更糟糕的是,我不知道为什么,因为它遵循相同的逻辑。

https://codepen.io/WegisSilveira/pen/poyPVWq

无论如何,这是我的带有钩子的代码。 css和codepen上的一样:

import React, { Fragment } from 'react'

import './ProgressBar.css'


const ProgressBar = props => {

let [sqSize, setSqSize] = React.useState(30)
let [percentage, setPercentage] = React.useState(0)
let [strokeWidth, setStrokeWidth] = React.useState(3)

let [trigger, setTrigger] = React.useState(false)
let [barIndex, setBarIndex] = React.useState(0)

let bars = Array(props.bar).fill(1)
let timer = 3000


const barTriggerHandler = () => {
    setTrigger(!trigger)
}


if (trigger) {
    setTimeout(() => {
        percentage < 99 ? setPercentage(percentage + 1) : setPercentage(0)
    }, timer / 100);

    setTimeout(() => {
        console.log(percentage)
        barIndex < bars.length - 1 ? setBarIndex(barIndex + 1) : setBarIndex(0)
    }, timer);
    
}

// SVG centers the stroke width on the radius, subtract out so circle fits in square
const radius = (sqSize - strokeWidth) / 2;
// Enclose cicle in a circumscribing square
const viewBox = `0 0 ${sqSize} ${sqSize}`;
// Arc length at 100% coverage is the circle circumference
const dashArray = radius * Math.PI * 2;
// Scale 100% coverage overlay with the actual percent
const dashOffset = dashArray - dashArray * percentage / 100;
// console.log(dashOffset)

return (
    <Fragment>
        { bars.map((bar, i) => {
            return <svg
                        key={i}

                        width={sqSize}
                        height={sqSize}
                        viewBox={viewBox}

                        onClick={() => barTriggerHandler()}
                    >
                        { i === barIndex ?  
                            <Fragment>
                                <circle
                                    className="circle-progress"
                                    cx={sqSize / 2}
                                    cy={sqSize / 2}
                                    r={radius}
                                    strokeWidth={`${strokeWidth}px`}
                                    // Start progress marker at 12 O'Clock
                                    transform={`rotate(-90 ${sqSize / 2} ${sqSize / 2})`}
                                    style={{
                                        strokeDasharray: dashArray,
                                        strokeDashoffset: dashOffset
                                    }} 
                                /> 
                            </Fragment>
                        : null }
                        <circle
                            className="circle-center"
                            cx="50%"
                            cy="50%"
                            r="3"
                        /> 
                        
                    </svg>
        }) }
    </Fragment>
);
}

export default ProgressBar

我正在使用元素svgcircle 创建那个栏,也许问题就在这里,因为直到昨天我什至不知道这些标签,我有点迷茫。

如果有人可以帮助我,我将不胜感激。这已经把我逼疯了。

附:我以这个笔为例来创建这个栏:https://codepen.io/bbrady/pen/ozrjKE?editors=1010

【问题讨论】:

    标签: javascript html css reactjs slider


    【解决方案1】:

    我只使用了一个 setTimeout 而不是两个。我删除了第二个,它用于将1 添加到包含点的数组的索引中,并将此步骤放在第一个setTimeout 中,现在而不是检查添加的时间我只是检查圆圈是否已填充 99%,如果是这种情况,则圆圈转到下一个点。

    这是第一个逻辑:

    if (trigger) {
        setTimeout(() => {
            percentage < 99 ? setPercentage(percentage + 1) : setPercentage(0)
        }, timer / 100);
    
        setTimeout(() => {
            barIndex < bars.length - 1 ? setBarIndex(barIndex + 1) : setBarIndex(0)
        }, timer);
        
    }
    

    现在我正在这样做:

    if (trigger) {
        setTimeout(() => {
            percentage < 99 ? setPercentage(percentage + 1) : setPercentage(0)
    
            if (percentage === 99) {
                 barIndex < bars.length - 1 ? setBarIndex(barIndex + 1) : setBarIndex(0)
            }
    
        }, timer / 100);        
    }
    

    由于两个步骤都在同一个setTimeout 内,因此不再有任何区间冲突。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-12
      • 2019-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多