如何用背景图像创建圆弧(扇形)? [英] How to create a circular arc (sector) with a background image?

查看:66
本文介绍了如何用背景图像创建圆弧(扇形)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种在给定角度的情况下绘制圆形扇形的方法.我希望该扇区显示一个(1:1)图像作为背景(仅是该扇区下方的平方尺寸图像的一部分).

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).

本质上,图像将具有相同的宽度和高度.图像的宽度和高度将等于将显示其扇形的圆的直径.我希望图像以及整个行业保持其长宽比,但要有所反应.我需要它们的大小以百分比或类似的形式显示,而不是像素,以便它们能够响应页面大小的变化.我尝试使用SVG路径来尝试完成此操作,但到目前为止,我还没有完全实现我的意图.

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.

我试图做的第一件事是设置我正在制作的SVG的背景图像.我提到了这个小提琴: http://jsfiddle.net/9zkfodwp/1/并最终结束了在这篇文章中尝试答案:用背景填充SVG路径元素-图片 接下来,我试图找到一种使角度呈圆形的扇形的方法,并在此处找到了一个令人惊奇的答案:

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

此处需要注意的事情:图片的尺寸不等于直径,并且图片也不断重复.另外,这里的SVG和路径大小是不同的,我希望SVG等于背景图片的大小,内部路径的直径等于平方SVG的大小.

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.

代码如下:

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>

我想要类似的结果,请忽略与此相关的问题,因为我使用了MS Paint绘制此.所以在这里,我只希望蓝色部分可见.蓝色部分是通过扇区可见的背景图像区域(即正方形).我不希望这个部门有任何边界或形象.我也不想重复图像.最后,如果答案是SVG,我希望路径完全适合SVG,因为我经常看到的答案导致SVG大于路径.我希望SVG等于(平方的)背景图像.

I want a result like this Please ignore the issues with this because I used MS Paint to draw this. So here, I want only the blue part to be visible. The blue part is the area of the background image (which is the square) that is visible through the sector. I don't want the sector to have any borders nor the image. I don't want the image to be repeated either. Lastly, if the answer is an SVG, I want the path to fit into the SVG completely because often, the answers I have seen result in the SVG to be bigger than the path. I want the SVG to be equal to the (squared) background image.

推荐答案

我将考虑我以前的两个答案 1 ,以便使用clip-path做到这一点.诀窍很简单,我们先将图像四舍五入,然后应用剪切路径显示/隐藏所需的部分.

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.

这是一个基本示例:

.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>

您还可以考虑动画:

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

  border-radius:50%;
  clip-path:polygon(50% 50%,0 0,0 0,0 0, 0 0,0 0);
  animation:change 2s linear forwards;
}

@keyframes change {
  25% {
    clip-path:polygon(50% 50%,0 0,   0 100%,0 100%,0 100%,0 100%);
  }
  50% {
    clip-path:polygon(50% 50%,0 0,0 100%,   100% 100%, 100% 100%,100% 100%);
  }
  75% {
    clip-path:polygon(50% 50%,0 0,0 100%,100% 100%,    100% 0,100% 0);
  }
  100% {
    clip-path:polygon(50% 50%,0 0,0 100%,100% 100%, 100% 0,     0% 0%);
  }
}

<div class="box">
</div>

1 相关答案可获取有关计算的更多详细信息,并根据需要轻松调整clip-path:

1 Related answers to get more details about the calculation and to easily adjust the clip-path like you want:

https://stackoverflow.com/a/56728104/8620333

https://stackoverflow.com/a/56799618/8620333

在不久的将来,我们可以考虑使用conic-gradient()mask-image轻松做到这一点.

In the near future we can consider conic-gradient() and mask-image to easily do this.

以下仅适用于Chrome

The below works only on Chrome

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

  
  -webkit-mask-image:conic-gradient(from 90deg, #fff 60deg,transparent 60deg);
  mask-image:conic-gradient(from 90deg, #fff 60deg,transparent 60deg);
  border-radius:50%;
}

<div class="box">
</div>

如您所见,我们只需定义起点(从),然后定义度数 扇区应填充(白色)

As you can see, we simply define the starting point (from) then the degree the sector should fill (the white color)

更新

基于另一个我在其中创建饼图的答案( https://stackoverflow.com/a/52205730/8620333)我们可以使用mask-imagelinear-gradient改进以前的方法,以获得更好的支持

Based on another answer where I am creating a pie chart (https://stackoverflow.com/a/52205730/8620333) we can improve the previous method using mask-image and linear-gradient to have better support

0%50%:

.box {
  width:100px;
  height:100px;
  display:inline-block;
  border-radius:50%;
  background:url(https://picsum.photos/id/1024/400/400) center/cover;
  clip-path:polygon(50% 0, 100% 0, 100% 100%, 50% 100%);
  -webkit-mask:
    linear-gradient(var(--v), transparent 50%, #fff 0);
}

<p>The formula is [x = (5/18) * p + 25]. <small>Where x is the percentage and p the degree</small></p>
<div class="box" style="--v:-90deg;"></div>
<div class="box" style="--v:-30deg;"></div>
<div class="box" style="--v:0deg;"></div>
<div class="box" style="--v:60deg;"></div>
<div class="box" style="--v:90deg;"></div>

50%100%:

.box {
  width:100px;
  height:100px;
  display:inline-block;
  border-radius:50%;
  background:url(https://picsum.photos/id/1024/400/400) center/cover;
  -webkit-mask:
    linear-gradient(var(--v), #fff 50%,transparent 0),
    linear-gradient(to right, transparent 50%,#fff 0);
}

<p>The formula is [x = (5/18) * p + 75]. <small>Where x is the percentage and p the degree</small></p>
<div class="box" style="--v:-90deg;"></div>
<div class="box" style="--v:-30deg;"></div>
<div class="box" style="--v:0deg;"></div>
<div class="box" style="--v:60deg;"></div>
<div class="box" style="--v:90deg;"></div>

这篇关于如何用背景图像创建圆弧(扇形)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆