vydimitrov / react-countdown-circle-timer

Lightweight React/React Native countdown timer component with color and progress animation based on SVG
MIT License
692 stars 87 forks source link

Change the view of user interface #178

Closed berkaygurbuz closed 2 years ago

berkaygurbuz commented 3 years ago

I want to change the circle user interface. Is there any way to change circle as follows image: 1

vydimitrov commented 3 years ago

Hey, the component does not offer any API that you can do it right the way. I am not even sure what is the best way to make it. I will try to think about it and let you know if I come up with something. It is a good one to make :)

berkaygurbuz commented 3 years ago

I got something that similar like above but is not. I have some idea to figure out. Maybe we can solve this problem changing strokeWidth, strokeDasharray and strokeDashOffset. Also we have to change getPathProps function which change the path.

If it is convenient for you, we can look together when you are available.

Plesae inform me.

vydimitrov commented 3 years ago

May be you can fork the repo and try your idea and I can take a look on it after that.

berkaygurbuz commented 3 years ago

@vydimitrov You can follow the idea in this forked repository

vydimitrov commented 3 years ago

Great, it looks good so far. Let me know if you want me to look at some part of it and help you.

berkaygurbuz commented 3 years ago

@vydimitrov I can't figure out the getPathProps method. I create svg but it doesn't rotate. I think we have to change it to our custom svg. Maybe you can help me in this method. I am not good at SVG properties 😅

vydimitrov commented 3 years ago

I tried a few different things but I was not really able to get it 100% as on the design. I would recommend you to dig in a bit more in to ClipPath function. Unfortunately, the strokeDasharray on the clip path is not taken and it is not applied on the animated path. Check the snippet below:

<ClipPath id="myClip">
  <Path
    fill="none"
    d={path}
    strokeWidth="20"
    strokeDasharray="2"  // This will not apply on the animated path when used as a clip path
  />
</ClipPath>
<AnimatedPath
  stroke="#000"
  d={path}
  strokeDasharray={pathLength}
  strokeDashoffset={strokeDashoffset}
  strokeWidth={strokeWidth}
  clipPath="url(#myClip)"
/>

I'd suggest to try to find a different way how you can clip the animated path. One idea is to use an image from your design instead, like so (sudo code below):

<ClipPath id="myClip">
  <Image src="./image/from/design.png" />
</ClipPath>
<AnimatedPath
    stroke="#000"
    d={path}
    strokeDasharray={pathLength}
    strokeDashoffset={strokeDashoffset}
    strokeWidth={strokeWidth}
    clipPath="url(#myClip)"
/>
vydimitrov commented 3 years ago

This is my best attempt IMO. Make the animated path transparent and put behind your path with the strokeDasharray="2"

berkaygurbuz commented 3 years ago

Can you animate the circle? It looks not bad I think.

vydimitrov commented 3 years ago

Yes, you need to just this one

{isProgressPathVisible && (
  <>
    <Path
      fill="none"
      stroke="#ccc"
      d={path}
      strokeWidth="20"
      strokeDasharray="2"
    />
    <AnimatedPath
      fill="none"
      stroke="rgba(0,0,0,0.3)"
      d={path}
      strokeWidth="20"
      strokeDasharray={pathLength}
      strokeDashoffset={strokeDashoffset}
    />
  </>
)}
berkaygurbuz commented 3 years ago

Maybe we have to know how to add some margin between circle stick.

vydimitrov commented 3 years ago

Try this strokeDasharray="2 4"

berkaygurbuz commented 3 years ago

I change strokeDashArray="3 8". I got similar design but the working logic is a little different. Circle starts blank screen because I choose stroke="white" in animatedPath and when time is increasing, design is rotating.

        <Path
          fill="none"
          strokeWidth={trailStrokeWidth ?? strokeWidth}
          stroke={trailColor}
          d={path}
        />
        {isProgressPathVisible && (
          <>
          <Path
      fill="none"
      stroke="black"
      d={path}
      strokeWidth="20"
      strokeDasharray="3 8"
    />
          <AnimatedPath
             fill="none"
             stroke="white"
             d={path}
             strokeWidth="22"
             strokeDasharray={pathLength}
             strokeDashoffset={strokeDashoffset}
          />
          </>

trailColor is also white. You can change colors depends on your background color.

image

Maybe you can help smooth rotation effects and develop working logic same as my first design.

vydimitrov commented 3 years ago

May be you can try to add one new Path after the AnimatedPath so it will be always shown since it will be on top of it. If the new Path has some opacity on it, you can make it looks close to the design but inverted - the remaining time will have lighter color and the elapsed time will have darker color. Is that going to work for you?

berkaygurbuz commented 2 years ago

I think this solution is enough for me. Thanks for the help.