英文:
How do I animate a gradient border of a circle?
问题
I have unsuccessfully been trying to animate a linear gradient border on a div
. I took inspiration from this image. I want the border to be transparent between the two gradients, like in the picture. But I also want the gradient to look like it is moving in a circle around the circle div
.
我一直在尝试对 div
上的线性渐变边框进行动画处理,但没有成功。我从 这个图片 中获取了灵感。我希望边框在两个渐变之间是透明的,就像图片中那样。但我还希望渐变看起来像是围绕 div
上的圆形移动。
I tried making the circle rotate in an animation, which works but I cannot add a gradient to a border-color
property so instead I used an ::after
property to add a circle behind the main div
so that it looks like a circle. All of this works with a on the background but the main problem from here is that I cannot get the gaps between 2 different gradient borders on opposite sides of the circle.
我尝试通过动画使圆形旋转,这个方法有效,但我无法将渐变添加到 border-color
属性,所以我使用了 ::after
属性在主 div
后面添加了一个圆,以使它看起来像一个圆。这一切都在背景上运行,但从这里主要问题是我无法在圆的相对两侧获取两个不同渐变边框之间的间隙。
scss:
#home-page {
i {
position: absolute;
color: $medium-red;
top: 50%;
left: 50%;
font-size: 400px;
animation: spin 4s linear infinite;
border-radius: 50%;
&::after {
content: "";
background: linear-gradient(60deg, $beige, $light-red);
position: absolute;
top: -3px;
left: -3px;
right: -3px;
bottom: -3px;
border-radius: 50%;
z-index: -1;
}
}
}
@keyframes spin {
0% {
transform: translate(-50%, -50%);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
html:
<div id="homepage">
<i>(font awesome icon of a circle)</i>
</div>
英文:
I have unsuccessfully been trying to animate a linear gradient border on a div
. I took inspiration from
this image. I want the border to be transparent between the two gradients, like in the picture. But I also want the gradient to look like it is moving in a circle around the circle div
.
I tried making the circle rotate in an animation, which works but I cannot add a gradient to a border-color
property so instead I used an ::after
property to add a circle behind the main div
so that it looks like a circle. All of this works with a on the background but the main problem from here is that I cannot get the gaps between 2 different gradient borders on opposite sides of the circle.
scss:
#home-page {
i {
position: absolute;
color: $medium-red;
top: 50%;
left: 50%;
font-size: 400px;
// border-width: 2px;
// border-style: solid;
animation: spin 4s linear infinite;
// border-color: transparent $beige;
border-radius: 50%;
&::after {
content: "";
background: linear-gradient(60deg, $beige, $light-red);
position: absolute;
top: -3px;
left: -3px;
right: -3px;
bottom: -3px;
border-radius: 50%;
z-index: -1;
}
}
}
@keyframes spin {
0% {
transform: translate(-50%, -50%);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
html:
<div id="homepage">
<i>(font awesome icon of a circle)</i>
</div>
答案1
得分: 0
以下是您提供的HTML和CSS代码的翻译:
HTML
<div id="homepage">
<div class="circle-gradient">
</div>
</div>
CSS:
.circle-gradient {
color: $medium-red;
animation: spin 4s linear infinite;
border-radius: 50%;
position: relative;
height: 300px;
width: 300px;
background: linear-gradient(60deg, $beige, $light-red);
border-radius: 50%;
z-index: -1;
position: relative;
}
.circle-gradient::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background-color: white;
border-radius: 50%;
z-index: 999;
border-inline: 5px solid rgba(0, 0, 0, 0.02);
}
@keyframes spin {
0% {
transform: translate(1%, 1%);
}
100% {
transform: translate(1%, 1%) rotate(360deg);
}
}
在此链接上测试它的工作原理这里。
英文:
HTML
<div id="homepage">
<div class="circle-gradient">
</div>
</div>
CSS:
.circle-gradient {
color: $medium-red;
animation: spin 4s linear infinite;
border-radius: 50%;
position: relative;
height: 300px;
width: 300px;
background: linear-gradient(60deg, $beige, $light-red);
border-radius: 50%;
z-index: -1;
position: relative;
&:after{
content: '';
position: absolute;
width: 100%;
height: 100%;
background-color: white;
border-radius: 50%;
z-index: 999;
border-inline: 5px solid rgba(0,0,0,0.02);
}
}
@keyframes spin {
0% {
transform: translate(1%, 1%);
}
100% {
transform: translate(1%, 1%) rotate(360deg);
}
}
test how it works HERE
答案2
得分: 0
以下是翻译好的部分:
* { margin: 0; }
body { background: #1a0a0a; }
.circle {
position: relative;
width: 10rem;
aspect-ratio: 1;
border-radius: 50%;
background: url("https://i.stack.imgur.com/p2rd3.png") no-repeat center / 60%;
}
.circle svg {
position: absolute;
animation: arcRotation 2s linear infinite ;
}
@keyframes arcRotation {
100% { rotate: 360deg; }
}
<div class="circle">
<svg id="arc1" viewBox="0 0 1 1">
<defs>
<linearGradient id="gradient1" gradientUnits="userSpaceOnUse" x1="1" y1="1" x2="0" y2="1">
<stop offset=".42" stop-color="#fff" />
<stop offset=".58" stop-color="#f00" />
</linearGradient>
</defs>
<path stroke="url(#gradient1)" stroke-width="0.01" fill="none" d="M 0.74 0.0843078061834695 A 0.48 0.48 0 0 0 0.2600000000000001 0.08430780618346945"></path>
</svg>
<svg id="arc2" viewBox="0 0 1 1">
<defs>
<linearGradient id="gradient2" gradientUnits="userSpaceOnUse" x1="1" y1="1" x2="0" y2="1">
<stop offset=".42" stop-color="#f00" />
<stop offset=".58" stop-color="#fff" />
</linearGradient>
</defs>
<path stroke="url(#gradient2)" stroke-width="0.01" fill="none" d="M 0.37576685835079 0.9636443966187528 A 0.48 0.48 0 0 0 0.62423314164921 0.9636443966187528"></path>
</svg>
</div>
// https://stackoverflow.com/a/18473154/383904
const polarToCartesian = (centerX, centerY, radius, angleInDegrees) => {
const angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
};
const describeArc = (x, y, radius, startAngle, endAngle) => {
const start = polarToCartesian(x, y, radius, endAngle);
const end = polarToCartesian(x, y, radius, startAngle);
const largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
const d = [
"M", start.x, start.y,
"A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
].join(" ");
return d;
};
document.querySelector("#arc1 path").setAttribute("d", describeArc(0.5, 0.5, 0.48, -30, 30));
document.querySelector("#arc2 path").setAttribute("d", describeArc(0.5, 0.5, 0.48, 180 - 15, 180 + 15));
英文:
You could use SVG for the gradient arcs like:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
* { margin: 0; }
body { background: #1a0a0a; }
.circle {
position: relative;
width: 10rem;
aspect-ratio: 1;
border-radius: 50%;
background: url("https://i.stack.imgur.com/p2rd3.png") no-repeat center / 60%;
}
.circle svg {
position: absolute;
animation: arcRotation 2s linear infinite ;
}
@keyframes arcRotation {
100% { rotate: 360deg; }
}
<!-- language: lang-html -->
<div class="circle">
<svg id="arc1" viewBox="0 0 1 1">
<defs>
<linearGradient id="gradient1" gradientUnits="userSpaceOnUse" x1="1" y1="1" x2="0" y2="1">
<stop offset=".42" stop-color="#fff" />
<stop offset=".58" stop-color="#f00" />
</linearGradient>
</defs>
<path stroke="url(#gradient1)" stroke-width="0.01" fill="none" d="M 0.74 0.0843078061834695 A 0.48 0.48 0 0 0 0.2600000000000001 0.08430780618346945"></path>
</svg>
<svg id="arc2" viewBox="0 0 1 1">
<defs>
<linearGradient id="gradient2" gradientUnits="userSpaceOnUse" x1="1" y1="1" x2="0" y2="1">
<stop offset=".42" stop-color="#f00" />
<stop offset=".58" stop-color="#fff" />
</linearGradient>
</defs>
<path stroke="url(#gradient2)" stroke-width="0.01" fill="none" d="M 0.37576685835079 0.9636443966187528 A 0.48 0.48 0 0 0 0.62423314164921 0.9636443966187528"></path>
</svg>
</div>
<!-- end snippet -->
PS, the <path>
elements d
attribute was generated thanks to this snippet:
<!-- begin snippet: js hide: true console: true babel: false -->
<!-- language: lang-js -->
// https://stackoverflow.com/a/18473154/383904
const polarToCartesian = (centerX, centerY, radius, angleInDegrees) => {
const angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
};
const describeArc = (x, y, radius, startAngle, endAngle) => {
const start = polarToCartesian(x, y, radius, endAngle);
const end = polarToCartesian(x, y, radius, startAngle);
const largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
const d = [
"M", start.x, start.y,
"A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
].join(" ");
return d;
};
document.querySelector("#arc1 path").setAttribute("d", describeArc(0.5, 0.5, 0.48, -30, 30));
document.querySelector("#arc2 path").setAttribute("d", describeArc(0.5, 0.5, 0.48, 180 - 15, 180 + 15));
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论