英文:
Is there are anyway to animate this like a running conveyor belt?
问题
I need to animate this so that it'll look like a running conveyor belt, is there any way to achieve it?
这部分内容是关于如何使其看起来像一个运行的传送带,有没有办法实现?
英文:
I need to animate this so that it'll look like a running conveyor belt, is there are any way to achieve it?
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const cx = 50;
const cy = 50;
const width = 40;
const radius = 100; // CV size
const TwoPi = Math.PI * 0.5;
const circ = TwoPi * radius;
const height = circ / 4; // Roller counts
const parent = document.getElementById("bend");
for (let i = 0; i < circ; i += height) {
let seg = document.createElementNS("http://www.w3.org/2000/svg", "path");
let rs = (i / circ) * TwoPi;
let re = ((i + height) / circ) * TwoPi;
let ss = Math.sin(rs);
let cs = Math.cos(rs);
let se = Math.sin(re);
let ce = Math.cos(re);
seg.setAttribute("d",
`M${(cs * radius) + cx},${(ss * radius) + cy}` +
`A${radius},${radius} ${((re - rs) / Math.PI) * 180},0,1 ${(ce * radius) + cx},${(se * radius) + cy}` +
`L${(ce * (radius - width)) + cx},${(se * (radius - width)) + cy}` +
`A${radius - width},${radius - width} ${((re - rs) / Math.PI) * -180},0,0 ${(cs * (radius - width)) + cx},${(ss * (radius - width)) + cy}z`
);
seg.setAttribute("fill", "url(#grad2)");
seg.setAttribute("stroke", "#008000");
parent.appendChild(seg);
}
<!-- language: lang-html -->
<svg width="200" height="200" viewBox="0 0 200 200" style="transform: rotate(-90deg)">
<defs>
<linearGradient id="grad2" x1="0%" y1="0%" x2="40%" y2="100%">
<stop offset="0%" style="stop-color:#008000;stop-opacity:1"/>
<stop offset="100%" style="stop-color:#c7fdc7;stop-opacity:1"/>
</linearGradient>
</defs>
<g id="bend"></g>
</svg>
<!-- end snippet -->
Here's the preview of the above code, and this is the running animation example.
Thankyou.
答案1
得分: 3
这是一个使用重复的圆片段制作的版本。动画是使用 <animateTransform>
元素创建的。
减少了计算,增加了构建。
<svg width="200" viewBox="0 0 200 200">
<defs>
<linearGradient id="grad" x1="60%" y1="60%" x2="90%" y2="90%">
<stop offset="0%" stop-color="#008000" stop-opacity="1"/>
<stop offset="100%" stop-color="#c7fdc7" stop-opacity="1"/>
</linearGradient>
<mask id="m1">
<rect x="50" y="50" width="100" height="100" fill="white"/>
</mask>
<circle id="c1" cx="0" cy="0" r="70" fill="none"
stroke="url(#grad)" stroke-width="28" pathLength="360"
stroke-dasharray="19 360" />
</defs>
<g mask="url(#m1)">
<g transform="translate(50 150) rotate(-180)">
<g>
<circle id="c1" cx="0" cy="0" r="70" fill="none"
stroke="darkgreen" stroke-width="30" />
<use href="#c1"/>
<use href="#c1" transform="rotate(20)"/>
<use href="#c1" transform="rotate(40)"/>
<use href="#c1" transform="rotate(60)"/>
<use href="#c1" transform="rotate(80)"/>
<use href="#c1" transform="rotate(100)"/>
<use href="#c1" transform="rotate(120)"/>
<use href="#c1" transform="rotate(140)"/>
<use href="#c1" transform="rotate(160)"/>
<animateTransform
attributeName="transform"
attributeType="XML"
type="rotate"
from="0"
to="80"
dur="5s"
repeatCount="indefinite" />
</g>
</g>
</g>
</svg>
英文:
Here is a version made with a slice of a circle that is repeated. The animation is made with the <animateTransform>
element.
Less calculations and more construction.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<svg width="200" viewBox="0 0 200 200">
<defs>
<linearGradient id="grad" x1="60%" y1="60%" x2="90%" y2="90%">
<stop offset="0%" stop-color="#008000" stop-opacity="1"/>
<stop offset="100%" stop-color="#c7fdc7" stop-opacity="1"/>
</linearGradient>
<mask id="m1">
<rect x="50" y="50" width="100" height="100" fill="white"/>
</mask>
<circle id="c1" cx="0" cy="0" r="70" fill="none"
stroke="url(#grad)" stroke-width="28" pathLength="360"
stroke-dasharray="19 360" />
</defs>
<g mask="url(#m1)">
<g transform="translate(50 150) rotate(-180)" >
<g>
<circle id="c1" cx="0" cy="0" r="70" fill="none"
stroke="darkgreen" stroke-width="30" />
<use href="#c1"/>
<use href="#c1" transform="rotate(20)"/>
<use href="#c1" transform="rotate(40)"/>
<use href="#c1" transform="rotate(60)"/>
<use href="#c1" transform="rotate(80)"/>
<use href="#c1" transform="rotate(100)"/>
<use href="#c1" transform="rotate(120)"/>
<use href="#c1" transform="rotate(140)"/>
<use href="#c1" transform="rotate(160)"/>
<animateTransform
attributeName="transform"
attributeType="XML"
type="rotate"
from="0"
to="80"
dur="5s"
repeatCount="indefinite" />
</g>
</g>
</g>
</svg>
<!-- end snippet -->
答案2
得分: 1
以下是您要翻译的代码部分:
const drawSegment = (fromAngle, toAngle, innerRadius, outerRadius, centerX, centerY) => {
const svg = d3.select('svg');
const x1 = centerX + innerRadius * Math.sin(fromAngle);
const y1 = centerY - innerRadius * Math.cos(fromAngle);
const x2 = centerX + outerRadius * Math.sin(fromAngle);
const y2 = centerY - outerRadius * Math.cos(fromAngle);
const x3 = centerX + outerRadius * Math.sin(toAngle);
const y3 = centerY - outerRadius * Math.cos(toAngle);
const x4 = centerX + innerRadius * Math.sin(toAngle);
const y4 = centerY - innerRadius * Math.cos(toAngle);
const path = `M ${x1},${y1} L ${x2},${y2} A ${outerRadius},${outerRadius} 0 0 1 ${x3},${y3} L ${x4},${y4} A ${innerRadius}, ${innerRadius} 0 0 0 ${x1},${y1} Z`;
svg.append('path')
.attr('d', path)
.attr('stroke', '#008000')
.attr('fill', 'url(#grad)')
}
const a = Math.PI / 8;
let start = 0;
setInterval(() => {
d3.select('svg').selectAll('path').remove();
if (start < 1) {
start += 0.02;
} else
start = 0;
if (start > 0) {
drawSegment(0, start * a, 50, 80, 20, 100);
}
for (let i = start; i < 4; i++) {
drawSegment(a * i, Math.min((i + 1) * a, a * 4), 50, 80, 20, 100);
}
}, 50);
svg {
border: 1px solid #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="200" height="120">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="40%" y2="100%">
<stop offset="0%" style="stop-color:#008000;stop-opacity:1" />
<stop offset="100%" style="stop-color:#c7fdc7;stop-opacity:1" />
</linearGradient>
</defs>
<g id="bend"></g>
</svg>
英文:
Here is a possible solution (run the snippet below):
<!-- begin snippet: js hide: false console: false babel: false -->
<!-- language: lang-js -->
const drawSegment = (fromAngle, toAngle, innerRadius, outerRadius, centerX, centerY) => {
const svg = d3.select('svg');
const x1 = centerX + innerRadius * Math.sin(fromAngle);
const y1 = centerY - innerRadius * Math.cos(fromAngle);
const x2 = centerX + outerRadius * Math.sin(fromAngle);
const y2 = centerY - outerRadius * Math.cos(fromAngle);
const x3 = centerX + outerRadius * Math.sin(toAngle);
const y3 = centerY - outerRadius * Math.cos(toAngle);
const x4 = centerX + innerRadius * Math.sin(toAngle);
const y4 = centerY - innerRadius * Math.cos(toAngle);
const path = M ${x1},${y1} L ${x2},${y2} A ${outerRadius},${outerRadius} 0 0 1 ${x3},${y3} L ${x4},${y4} A ${innerRadius}, ${innerRadius} 0 0 0 ${x1},${y1} Z
;
svg.append('path')
.attr('d', path)
.attr('stroke', '#008000')
.attr('fill', 'url(#grad)')
}
const a = Math.PI / 8;
let start = 0;
setInterval(() => {
d3.select('svg').selectAll('path').remove();
if (start < 1) {
start += 0.02;
}
else
start = 0;
if (start > 0) {
drawSegment(0, start * a, 50, 80, 20, 100);
}
for (let i = start; i < 4; i++) {
drawSegment(a * i, Math.min((i + 1) * a, a * 4), 50, 80, 20, 100);
}
}, 50);
<!-- language: lang-css -->
svg {
border: 1px solid #000;
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="200" height="120">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="40%" y2="100%">
<stop offset="0%" style="stop-color:#008000;stop-opacity:1"/>
<stop offset="100%" style="stop-color:#c7fdc7;stop-opacity:1"/>
</linearGradient>
</defs>
<g id="bend"></g>
</svg>
<!-- end snippet -->
答案3
得分: 0
这是一个反向动画:
const drawSegment = (fromAngle, toAngle,
innerRadius, outerRadius, centerX, centerY) => {
const svg = d3.select('svg');
const x1 = centerX + innerRadius * Math.sin(fromAngle);
const y1 = centerY - innerRadius * Math.cos(fromAngle);
const x2 = centerX + outerRadius * Math.sin(fromAngle);
const y2 = centerY - outerRadius * Math.cos(fromAngle);
const x3 = centerX + outerRadius * Math.sin(toAngle);
const y3 = centerY - outerRadius * Math.cos(toAngle);
const x4 = centerX + innerRadius * Math.sin(toAngle);
const y4 = centerY - innerRadius * Math.cos(toAngle);
const path = `M ${x1},${y1} L ${x2},${y2} A ${outerRadius},${outerRadius} 0 0 1 ${x3},${y3} L ${x4},${y4} A ${innerRadius}, ${innerRadius} 0 0 0 ${x1},${y1} Z`;
svg.append('path')
.attr('d', path)
.attr('stroke', '#0F0')
.attr('fill', 'url(#grad)')
}
const seg = Math.PI / 8;
let delta = 0, start, end;
setInterval(() => {
d3.select('svg').selectAll('path').remove();
if (delta < 1) {
delta += 0.02;
}
else {
delta = 0;
}
if (delta > 0) {
start = seg * (4 - delta);
end = seg * 4;
drawSegment(start, end, 50, 80, 20, 100);
}
else {
start = seg * 4;
}
while (start > 0) {
end = start;
start = Math.max (0, end - seg);
drawSegment(start, end, 50, 80, 20, 100);
}
}, 100);
svg {
border: 1px solid #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="200" height="120">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="40%" y2="100%">
<stop offset="0%" style="stop-color:#008000;stop-opacity:1"/>
<stop offset="100%" style="stop-color:#c7fdc7;stop-opacity:1"/>
</linearGradient>
</defs>
<g id="bend"></g>
</svg>
英文:
Here is a reverse animation:
<!-- begin snippet: js hide: false console: false babel: false -->
<!-- language: lang-js -->
const drawSegment = (fromAngle, toAngle,
innerRadius, outerRadius, centerX, centerY) => {
const svg = d3.select('svg');
const x1 = centerX + innerRadius * Math.sin(fromAngle);
const y1 = centerY - innerRadius * Math.cos(fromAngle);
const x2 = centerX + outerRadius * Math.sin(fromAngle);
const y2 = centerY - outerRadius * Math.cos(fromAngle);
const x3 = centerX + outerRadius * Math.sin(toAngle);
const y3 = centerY - outerRadius * Math.cos(toAngle);
const x4 = centerX + innerRadius * Math.sin(toAngle);
const y4 = centerY - innerRadius * Math.cos(toAngle);
const path = `M ${x1},${y1} L ${x2},${y2} A ${outerRadius},${outerRadius} 0 0 1 ${x3},${y3} L ${x4},${y4} A ${innerRadius}, ${innerRadius} 0 0 0 ${x1},${y1} Z`;
svg.append('path')
.attr('d', path)
.attr('stroke', '#0F0')
.attr('fill', 'url(#grad)')
}
const seg = Math.PI / 8;
let delta = 0, start, end;
setInterval(() => {
d3.select('svg').selectAll('path').remove();
if (delta < 1) {
delta += 0.02;
}
else {
delta = 0;
}
if (delta > 0) {
start = seg * (4 - delta);
end = seg * 4;
drawSegment(start, end, 50, 80, 20, 100);
}
else {
start = seg * 4;
}
while (start > 0) {
end = start;
start = Math.max (0, end - seg);
drawSegment(start, end, 50, 80, 20, 100);
}
}, 100);
<!-- language: lang-css -->
svg {
border: 1px solid #000;
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="200" height="120">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="40%" y2="100%">
<stop offset="0%" style="stop-color:#008000;stop-opacity:1"/>
<stop offset="100%" style="stop-color:#c7fdc7;stop-opacity:1"/>
</linearGradient>
</defs>
<g id="bend"></g>
</svg>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论