gpt4 book ai didi

javascript - d3 按弧动画路径

转载 作者:行者123 更新时间:2023-12-04 08:32:34 25 4
gpt4 key购买 nike

我开始使用 d3。有一个问题,我怎样才能沿着填充路径正确地设置三 Angular 形的动画?我为仪表图创建了一个基础并对其进行了动画处理。

var chart = d3.select("#speedometer");

const arc = d3
.arc()
.outerRadius(120)
.innerRadius(90)
.startAngle(-Math.PI / 2);

chart
.append("path")
.datum({
endAngle: Math.PI / 2
})
.attr("transform", "translate(160, 180)")
.attr("class", "background")
.style("fill", "#495270")
.attr("d", arc);

const triangle = chart
.append('g')
.attr('transform', 'translate(30, 180) rotate(90)')
.style('width', '100%')
.append("path").attr("d", "M3.937,0,7.873,14H0Z");

const newAngle = (70 / 100) * Math.PI - Math.PI / 2;

const foreground = chart
.append("path")
.datum({ endAngle: -Math.PI / 2 })
.style("fill", "rgb(50, 188, 228)")
.attr("transform", "translate(160, 180)")
.attr("d", arc);

foreground
.transition()
.duration(3000)
.attrTween("d", function (d) {
const interpolate = d3.interpolate(d.endAngle, newAngle);
return function (t) {
d.endAngle = interpolate(t);
return arc(d);
};
});

triangle
.transition()
.duration(3000)

function pathTween(path) {
const length = path.node().getTotalLength(); // Get the length of the path
const r = d3.interpolate(0, length); // Set up interpolation from 0 to the path length
return function (t) {
const point = path.node().getPointAtLength(r(t)); // Get the next point along the path
d3
.select(this) // Select the circle
.attr("transform", `translate(${point.x}, ${point.y})`);
};
}
.main-wrapper{
max-width: 80%;
margin: 20px auto;
}

.element{
display: flex;
flex-flow: column nowrap;
margin-bottom: 20px;
border: 1px solid rgba(0,0,0,.4);
padding: 20px;
border-radius: 6px;
}

.title{
margin-bottom: 4px;
font-weight: 500;
}
.description{
margin-bottom: 10px;
color: rgba(0,0,0,.4);
}

#speedometer {
width: 300px;
height: 300px;
}

canvas{
width: 100%;
height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
<div class="main-wrapper">
<section class="ui-section">
<div class="element">
<div class="title">
Speedometr
</div>

<div class="content">
<svg id="speedometer" viewbox="0 0 300 300"></svg>
</div>
</div>
</section>
</div>

问题是,如何将三 Angular 形链接到图片中的动画弧的边缘?
我知道我应该使用
tween('path'....)
但不确定
enter image description here

最佳答案

我会使用 SVG transform: rotate ,因为它允许您指定相对于您应该旋转的内容,并且因为您可以链接转换。在这种情况下,我将 Angular 转换为圆弧的中心,然后将其旋转到正确的方向,然后将其向上移动到比外半径大一点的位置,以便平滑地沿着线移动。
它不是像素完美的,我认为这是因为三 Angular 形不是整数像素宽。

var chart = d3.select("#speedometer");

const arc = d3
.arc()
.outerRadius(120)
.innerRadius(90)
.startAngle(-Math.PI / 2);

chart
.append("path")
.datum({
endAngle: Math.PI / 2
})
.attr("transform", "translate(160, 180)")
.attr("class", "background")
.style("fill", "#495270")
.attr("d", arc);

const triangle = chart
.append('g')
.datum({ endAngle: -Math.PI / 2 })
.style('width', '100%')
.append("path").attr("d", "M3.937,0,7.873,14H0Z");

const newAngle = (70 / 100) * Math.PI - Math.PI / 2;

const foreground = chart
.append("path")
.datum({ endAngle: -Math.PI / 2 })
.style("fill", "rgb(50, 188, 228)")
.attr("transform", "translate(160, 180)")
.attr("d", arc);

foreground
.transition()
.duration(3000)
.attrTween("d", function (d) {
const interpolate = d3.interpolate(d.endAngle, newAngle);
return function (t) {
d.endAngle = interpolate(t);
return arc(d);
};
});

triangle
.transition()
.duration(3000)
.attrTween("transform", function (d) {
const interpolate = d3.interpolate(d.endAngle, newAngle);
return function (t) {
const angleRadians = interpolate(t);
const angleDegrees = 360 * angleRadians / (2 * Math.PI);
return `
translate(158 176)
rotate(${angleDegrees + 180} 3.5 7)
translate(0 132)
`;
};
});

function pathTween(path) {
const length = path.node().getTotalLength(); // Get the length of the path
const r = d3.interpolate(0, length); // Set up interpolation from 0 to the path length
return function (t) {
const point = path.node().getPointAtLength(r(t)); // Get the next point along the path
d3
.select(this) // Select the circle
.attr("transform", `translate(${point.x}, ${point.y})`);
};
}
.main-wrapper{
max-width: 80%;
margin: 20px auto;
}

.element{
display: flex;
flex-flow: column nowrap;
margin-bottom: 20px;
border: 1px solid rgba(0,0,0,.4);
padding: 20px;
border-radius: 6px;
}

.title{
margin-bottom: 4px;
font-weight: 500;
}
.description{
margin-bottom: 10px;
color: rgba(0,0,0,.4);
}

#speedometer {
width: 300px;
height: 300px;
}

canvas{
width: 100%;
height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
<div class="main-wrapper">
<section class="ui-section">
<div class="element">
<div class="title">
Speedometr
</div>

<div class="content">
<svg id="speedometer" viewbox="0 0 300 300"></svg>
</div>
</div>
</section>
</div>

关于javascript - d3 按弧动画路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64954518/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com