user3550879
user3550879

Reputation: 3469

Quarter-circle in top right corner

I am looking to make a quarter-circle to place in the top right corner of my website (fixed) and I want it to animate towards its center when user scrolls ( I have the code working for shrinking the element but not for the element itself or its center)

I have the header shrinking with the following code:

HTML (script)

$(function(){
 var shrinkHeader = 50;
 $(window).scroll(function() {
 var scroll = getCurrentScroll();
  if ( scroll >= shrinkHeader ) {
       $('header').addClass('shrink');
    }
    else {
        $('header').removeClass('shrink');
    }
 });

with the shrink class applied to the header when the user scrolls. I will switch it over to the quarter circle when I figure it out.

NOTE: It will be white filled with an icon in the middle (acting as my nav toggle button)

EDIT: I am asking how to make a quarter-circle that sits top right of the screen (fixed) and can be animated from the top right corner (circle's center)

Upvotes: 1

Views: 3443

Answers (2)

Harry
Harry

Reputation: 89770

I am looking to make a quarter-circle to place in the top right corner of my website (fixed) I want it to animate towards its center when user scrolls

I am asking how to make a quarter-circle that sits top right of the screen (fixed) and can be animated from the top right corner (circle's center)

Judging by the above, it seems like you want to know how to create a quarter-circle and also make it shrink (such that it goes towards its own top-right corner).

Creating a quarter-circle is simple and can be done with CSS itself. SVG is generally recommended for creating shapes but this is simple. All that is needed is to create a square and set it's bottom-left border radius as 100%. Positioning it (fixed) on the top right corner of the page is also very simple. Just add position: fixed with top and right as 0px.

Now for the shape to shrink, just change the height and width of the element to 0px and add to it a transition effect. In the below snippet, I have done it using an animation so that it is easily visible in the snippet window but you can put those two properties in a class and toggle it on/off depending on whether the user has scrolled the page or not.

Note: The other div and body CSS in the snippet are only for demo.

.quarter-circle {
  position: fixed;
  top: 0px;
  right: 0px;
  height: 75px;
  width: 75px;
  line-height: 75px;
  text-align: center;
  background: yellowgreen;
  border-bottom-left-radius: 100%;
  border: 2px solid;
  font-size: 1.5rem;
  animation: shrink 2s ease infinite;
}
@keyframes shrink {
  to {
    height: 50px;
    width: 50px;
    line-height: 50px;
  }
}
.some-content {
  min-height: 125vh;
  background: tomato;
}
body {
  margin: 0;
  padding: 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='quarter-circle'><i class="fa fa-home fa-fw"></i>
</div>
<div class='some-content'></div>


As you would have noticed in the above snippet, the animation is a bit jerky (the shape shivers when animation reaches its end). This is because we are animating the height and width properties both of which are super expensive because they result in a relayout, repaint and compositing. Instead, we can use transform: scale to achieve a similar effect like in the below snippet.

.quarter-circle {
  position: fixed;
  top: 0px;
  right: 0px;
  height: 75px;
  width: 75px;
  line-height: 75px;
  text-align: center;
  background: yellowgreen;
  border-bottom-left-radius: 100%;
  border: 2px solid;
  font-size: 1.5rem;
  animation: shrink 2s ease infinite;
  transform-origin: top right;
}
@keyframes shrink {
  to {
    transform: scale(.75);
  }
}
.some-content {
  min-height: 125vh;
  background: tomato;
}
body {
  margin: 0;
  padding: 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='quarter-circle'><i class="fa fa-home fa-fw"></i>
</div>
<div class='some-content'></div>

One drawback of using transform: scale is that the icon or text inside the shape will also get scaled down. This may or may not be a desirable outcome for you and hence choose accordingly.

Upvotes: 3

Persijn
Persijn

Reputation: 15000

SVG solution

I used your code (modyfied a bit) to change the width attribute of an svg shape.
The svg shape is Created using the path element.

Added a trigger for scrolling when page loads.
So that the change is imidiate when loading the example.

Added a css transition so the change is not imidiate (and more beautiful).

$(document).ready(function() {
  var svg = document.getElementById("slice");
  var shrinkHeader = 5;

  $(window).scroll(function() {
    var scroll = $(window).scrollTop();
    if (scroll >= shrinkHeader) {
      svg.setAttribute('width', '200px');
    } else {
      svg.setAttribute('width', '100px');
    }
  });
  //Trigger scroll event
  $(window).scroll();
});
body {
  height: 300vh;
}
.header {
  background-color: rgba(0, 0, 0, 0.5);
  position: fixed;
  width: 100%;
  height: 200px;
}
.header svg {
  position: absolute;
  right: 5px;
  transition: width 2s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="header">
  <svg id="slice" viewBox="0 0 100 100" width="200px">
    <path d="M5,5 95,5 95,95 Q 5,95 5,5" stroke="white" />
  </svg>
</div>
<p>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>text
  <br>
</p>

Upvotes: 2

Related Questions