Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
272 views
in Technique[技术] by (71.8m points)

javascript - How to create a circular arc (sector) with a background image?

I am looking for a way to draw a circle sector given an angle. I want this sector to show an (1:1) image as its background (Only the part of the squared dimension image that is beneath the sector).

Essentially, the image will have the same width and height. The image's width and height will be equal to the diameter of the circle whose sector will be shown. I want the image as well as the sector to maintain their aspect ratios but be responsive. I need their sizes to be in percentages or something similar and not pixels so they are responsive to page size changes. I have tried using SVG paths to try to accomplish this but so far I have failed to completely produce what I intend to.

The first thing I tried to do was set the background image of the SVG I was making. I referred to this fiddle: http://jsfiddle.net/9zkfodwp/1/ and finally ended up trying the answer in this post: Fill SVG path element with a background-image Next, I tried to find a way to make a circular sector given an angle and found an amazing answer here: How to calculate the SVG Path for an arc (of a circle) However, this answer did not use a background image so now merging both things together did not work out for me. I ended up with this

Things to note here: The picture's dimensions are not equal to the diameter and the picture is getting repeated as well. Plus, here the SVG and path sizes are different and I want the SVG to be equal to the background picture's size and the inside path to have its diameter to be equal to the dimensions of the squared SVG.

The code is below:

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
  var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
  return {
    x: centerX + (radius * Math.cos(angleInRadians)),
    y: centerY + (radius * Math.sin(angleInRadians))
  };
}

function describeArc(x, y, radius, startAngle, endAngle) {
  var start = polarToCartesian(x, y, radius, endAngle);
  var end = polarToCartesian(x, y, radius, startAngle);
  var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
  var d = [
    "M", start.x, start.y,
    "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
  ].join(" ");
  return d;
}
window.onload = function() {
  document.getElementById("arc1").setAttribute("d", describeArc(150, 150, 100, 0, 359.99));
};
<svg width="600" height="600">
        <defs>
            <pattern id="imgpattern" x="0" y="0" width="1" height="1">
                <image width="300" height="300"
                       xlink:href="https://146c4de20826c5857a80-8e5c4ea3a7a874d38c0915883796d18e.ssl.cf2.rackcdn.com/product-hugerect-669768-163734-1461140647-16fe8eceec8ee6c425577133b2b557b1.jpg" />
            </pattern>
        </defs>
        <path id="arc1" fill="none" stroke="url(#imgpattern)" stroke-width="90" />
    </svg>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I Will consider two of my previous answers1 in order to do this with clip-path. The trick is simple, we make the image rounded then we apply clip-path to show/hide the needed part.

Here is a basic example:

.box {
  width:150px;
  height:150px;
  background:url(https://picsum.photos/id/1003/300/300) center/cover;

  clip-path:polygon(50% 50%,0 0,   0 50%);
  border-radius:50%;
}
<div class="box">
</div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...