Circle fill in on hover

So if I have:

bb

And on hover, I want it to fill in whole border starting from bottom to up, until it touches right, making a full circle.

But, I don’t have that transition effect, nor was I able to make it a circle with just 50% of the bottom and right border (as I don’t know how to make it work with the transition as well).

What is the structure of the thing you are showing us? What’s the HTML? What’s the CSS? How have you currently achieved a quarter-circle?

well it ain’t much, just static for now:

 <div className="flex justify-center items-center flex-col economicsItem">
                <p className="font-semibold">1</p>
                <p className="text-xl font-semibold text-red_first" >Loans</p>
                <img src="home/ellipse.svg" alt="Ellipse" class="ellipse-image"></img>
                
            </div>
.economicsItem {
    
    position: relative;

    width: 100px;
    height: 100px;
    border-radius: 50%;  
    background: white;
}

.ellipse-image {
    position: absolute;
    width: 50px;
    height: 50px;
    bottom: 0;
    right: 0;
  }

okay… so your semicircle is an SVG? What’s the code inside the SVG?

this is like what I’ve exported from figma (designer made it)

<svg width="144" height="137" viewBox="0 0 144 137" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.350305 130.032C0.735899 134.018 4.28388 136.954 8.24906 136.39C41.1012 131.716 71.7825 117.022 96.0568 94.2261C120.331 71.4301 136.921 41.7313 143.647 9.23714C144.459 5.31517 141.752 1.58997 137.797 0.954985V0.954985C133.843 0.320002 130.14 3.01647 129.311 6.9348C123.105 36.2615 108.063 63.0539 86.1281 83.6535C64.1926 104.253 36.5092 117.584 6.85083 121.937C2.88819 122.519 -0.0352884 126.045 0.350305 130.032V130.032Z" fill="#AF2626"/>
</svg>

That’s… a lot of SVG for drawing a circle.

Someone will do this better than me, but…

I’ma clean that up a bit. I’m also going to steal code shamelessly from elsewhere, because people with bigger brains than me have done this already.

First, we’re going to pull the SVG out of the file and slap it into the HTML. This is so that the CSS can fiddle with it (it can’t muck with the contents of a file).
I’m also going to make the following changes:

  1. Your SVG’s width and height are 144x137, for a circle you’re drawing in a 100x100 space. That seems arbitrary, and the numbers will make more sense if we just make it 100x100 to start with.
  2. Same goes for the viewBox.

<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg" class="ellipse-image">

Now that the world is in a cohesive grid system that makes sense to my brain, let’s draw a circle using… a circle.
<circle class="fillme"></circle>
(No, I didnt set any of the values for it yet. You’ll see.)

Now we… close the SVG. Because we’re done with it.
</svg>

Now the messy part. The CSS to make it work. Here comes the part where i steal shamelessly a lot.

First, we’re going to use a bunch of variables to let the browser do math and make our numbers easier.

.ellipse-image {
    position: absolute;
    width: 100px;
    height: 100px;
    bottom: 0;
    right: 0; /* All this was your code */
  --size: 100px;
  --half-size: calc(var(--size) / 2);
  --stroke-width: 5px;
  --radius: calc((var(--size) - var(--stroke-width)) / 2);
  --circumference: calc(var(--radius) * pi * 2);
  --dash: calc((var(--progress) * var(--circumference)) / 100);   
  --progress: 25; /* We start at a quarter-circle. */
  }

Could we have done the math ourselves? Sure. Am i going to when the entire thing is based off of the size of the circle? Nope. Computers away!

We also need to tell our circle what its parameters are, because circles are picky like that and want to know things like… where they should be centered and how big they should be and whatnot. We’ve already got values kicking around in variables, we might as well use them here too.

.fillme {
  cx: var(--half-size);
  cy: var(--half-size);
  r: var(--radius);
  stroke-width: var(--stroke-width);
  fill: none;
  stroke-linecap: round;
  stroke-dasharray: var(--dash) calc(var(--circumference) - var(--dash));
  stroke: #AF2626;
  transition: stroke-dasharray 0.3s linear 0s;    
}

The transition will be necessary to ‘undo’ the animation when the hover ends. Note that the dasharray is based on --dash, which itself is based on --progress.

We then attach the change in progress value to a hover and let the transition kick in:

.ellipse-image:hover {
  --progress: 100
}

and we get…

(Note that i’m missing some of your CSS, so the text doesnt look right, but you get the point.)

[EDIT: And eventually i’ll remember i gave my circle a class.

2 Likes

You don’t actually need the svg at all…you could do it with a pseudo-element with a clipped border…

Edit: It looks better when you go to the codepen…honest :lol:

Edit2: Oops. Sorry. Just realized the result you were looking for was different. Still applies, but the clip path animation would have to change. Probably too much work for your needs, though. Apologies

2 Likes

yea, was able to use this.

I just could change this, and get smaller/bigger dimensions…


.economicsItem { ... 
    width: 150px;
    height: 150px;
}

 .ellipse-image {
...
width: 150px;
height: 150px;
}


I know this has been solved but just for fun here’s another version. :slight_smile:

(Modern browsers only)

2 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.