gpt4 book ai didi

javascript - 使用 tweendash 制作动画的曲线 d3 线

转载 作者:行者123 更新时间:2023-12-03 06:46:56 28 4
gpt4 key购买 nike

嗨,我正在尝试像 fiddle http://jsfiddle.net/nj37gkgq/ 中给出的那样弯曲线串。线是一系列链接,具有坐标形式的源和目的地。这条线连接 d3.geo map 中的两个标记。我怎样才能实现这个目标?

<!DOCTYPE html>
<html lang='en'>

<style type="text/css">



<body>


<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>

<div id="map"></div>

<script type="text/javascript">

var width = 650,
height = 600;

var projection = d3.geo.albersUsa()
.scale(2500)
.translate([1000, 360]);


var path = d3.geo.path()
.projection(projection);

var svg = d3.select("#map").append("svg")
.attr("width", width)
.attr("height", height);

var coordinates = [
[ -122.762, 40.801 ],
[ -117.0978, 34.1178]
];


d3.json(url, function(ca) {

svg.append("path")
.datum(topojson.mesh(ca, ca.objects.subunits, function(a, b) { return a === b;}))
.attr("d", path);

//for stroke of lines
var gradient = svg.append("svg:defs")
.append("svg:linearGradient")
.attr("id", "gradient")
.attr("x1", "0%")
.attr("y1", "0%")
.attr("x2", "100%")
.attr("y2", "100%")
.attr("spreadMethod", "pad");

gradient.append("svg:stop")
.attr("offset", "0%")
.attr("stop-color","darkblue")
.attr("stop-opacity", 1);

gradient.append("svg:stop")
.attr("offset", "100%")
.attr("stop-color","#85c1e9")
.attr("stop-opacity", 1);

var lF = d3.svg.line()
.interpolate("basis")
.x(function(d){ return d[0] })
.y(function(d){ return d[1] });

//update
var line = svg.append("path")
.datum(coordinates)
.attr("d", function(c){

var d = {
source: projection(c[0]),
target: projection(c[1])
},

points = [];

points.push(d.source);
points.push([(d.target[0] + d.source[0]) * .4, d.target[1]]);
points.push([(d.target[0] + d.source[0]) * .8, d.source[1]]);
points.push(d.target);
console.log(points);

return lF(points);
})
.attr("stroke-width", "2.5")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.style("stroke", "url(#gradient)");

anim();

function anim() {
line.transition()
.duration(2000)
.attrTween("stroke-dasharray", function() {
var len = this.getTotalLength();
return function(t) {
return (d3.interpolateString("0," + len, len + ",0"))(t)
};
})
.each('end', anim);
}

});


</script>

最佳答案

使用更好的曲线进行编辑

对于更通用的波形曲线公式,我认为中点的两个相反的弧看起来不错(c 是 long、lat 的 [[x1,y1], [x2,y2]] 数组):

function twoArc(c){
var source = projection(c[0]),
target = projection(c[1]),
mid = [(source[0] + target[0])/2, (source[1] + target[1])/2],
dx1 = mid[0] - source[0],
dx2 = target[0] - mid[0],
dy1 = mid[1] - source[1],
dy2 = target[1] - mid[1],
dr1 = Math.sqrt(dx1 * dx1 + dy1 * dy1),
dr2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);

var rv = "M";
rv += source[0] + "," + source[1];
rv += "A" + dr1 + "," + dr1 + " 0 0,1 ";
rv += mid[0] + "," + mid[1];
rv += "A" + dr2 + "," + dr2 + " 0 0,0 ";
rv += target[0] + "," + target[1];

return rv;
}

这是一个具有各种“随机”坐标的运行示例:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
fill: none;
stroke: #000;
stroke-linejoin: round;
stroke-linecap: round;
}
</style>

<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 600,
height = 350;

var coordinates = [
[-118, 34],
[-74, 40],
[-86.75, 33.57],
[-92.38, 35.22],
[-84.87, 34.53],
[-83.80, 41.60],
[-96.07, 33.07],
[-112.02, 41.18],
[-111.0, 41.33]
];

var projection = d3.geo.albersUsa()
.scale(700)
.translate([width / 2, height / 2]);

var path = d3.geo.path()
.projection(projection);

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

d3.json("https://rawgit.com/jgoodall/us-maps/master/topojson/state.json", function(error, us) {
if (error) return console.error(error);

svg.append("path")
.datum(topojson.mesh(us))
.attr("d", path);

var line = svg.append("path")
.datum(twoRand())
.attr("d", twoArc)
.style("stroke", "steelblue")
.style("stroke-width", 3)
.style("fill", "none");

anim();

function twoArc(c){
var source = projection(c[0]),
target = projection(c[1]),
mid = [(source[0] + target[0])/2, (source[1] + target[1])/2],
dx1 = mid[0] - source[0],
dx2 = target[0] - mid[0],
dy1 = mid[1] - source[1],
dy2 = target[1] - mid[1],
dr1 = Math.sqrt(dx1 * dx1 + dy1 * dy1),
dr2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);

var rv = "M";
rv += source[0] + "," + source[1];
rv += "A" + dr1 + "," + dr1 + " 0 0,1 ";
rv += mid[0] + "," + mid[1];
rv += "A" + dr2 + "," + dr2 + " 0 0,0 ";
rv += target[0] + "," + target[1];

return rv;
}

function twoRand(){
var i1 = Math.floor(Math.random() * coordinates.length),
i2 = Math.floor(Math.random() * coordinates.length);
return [coordinates[i1], coordinates[i2]];
}

function anim() {

line.datum(twoRand())
.attr("d", twoArc);

line.transition()
.duration(2000)
.attrTween("stroke-dasharray", function() {
var len = this.getTotalLength();
return function(t) {
return (d3.interpolateString("0," + len, len + ",0"))(t)
};
})
.each('end', anim);
}
});
</script>

首次尝试使用波形曲线进行编辑

这是一个带有“波浪线”的示例。我通过将抖动点插入数组并使用 d3 线拟合插值来生成它:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
fill: none;
stroke: #000;
stroke-linejoin: round;
stroke-linecap: round;
}
</style>

<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 600,
height = 350;

var coordinates = [
[-118, 34], //start point
[-74, 40] //end point
];

var projection = d3.geo.albersUsa()
.scale(700)
.translate([width / 2, height / 2]);

var path = d3.geo.path()
.projection(projection);

var lF = d3.svg.line()
.interpolate("basis")
.x(function(d){ return d[0] })
.y(function(d){ return d[1] });

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

d3.json("https://rawgit.com/jgoodall/us-maps/master/topojson/state.json", function(error, us) {
if (error) return console.error(error);

svg.append("path")
.datum(topojson.mesh(us))
.attr("d", path);

var line = svg.append("path")
.datum(coordinates)
.attr("d", function(c) {
var d = {
source: projection(c[0]),
target: projection(c[1])
},
points = [];

points.push(d.source);
points.push([(d.target[0] - d.source[0]) * 0.4, d.target[1]]);
points.push([(d.target[0] - d.source[0]) * 0.8, d.source[1]]);
points.push(d.target);

return lF(points);
})
.style("stroke", "steelblue")
.style("stroke-width", 3)
.style("fill", "none");

anim();

function anim() {
line.transition()
.duration(2000)
.attrTween("stroke-dasharray", function() {
var len = this.getTotalLength();
return function(t) {
return (d3.interpolateString("0," + len, len + ",0"))(t)
};
})
.each('end', anim);
}
});
</script>

<小时/>

单弧

在我看到你的评论之前就已经编码了,但你似乎不是被困在补间破折号上,而是被困在如何计算路径上。我知道您想要一条弯曲的路径,但这里有一个 map 上有简单弧线的示例(从洛杉矶到纽约):

<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
fill: none;
stroke: #000;
stroke-linejoin: round;
stroke-linecap: round;
}
</style>

<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 600,
height = 350;

var coordinates = [
[-118, 34], //start point
[-74, 40] //end point
];

var projection = d3.geo.albersUsa()
.scale(700)
.translate([width / 2, height / 2]);

var path = d3.geo.path()
.projection(projection);

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

d3.json("https://rawgit.com/jgoodall/us-maps/master/topojson/state.json", function(error, us) {
if (error) return console.error(error);

svg.append("path")
.datum(topojson.mesh(us))
.attr("d", path);

var line = svg.append("path")
.datum(coordinates)
.attr("d", function(c) {
var d = {
source: projection(c[0]),
target: projection(c[1])
};
var dx = d.target[0] - d.source[0],
dy = d.target[1] - d.source[1],
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source[0] + "," + d.source[1] + "A" + dr + "," + dr +
" 0 0,1 " + d.target[0] + "," + d.target[1];
})
.style("stroke", "steelblue")
.style("stroke-width", 3)
.style("fill", "none");

anim();

function anim() {
line.transition()
.duration(2000)
.attrTween("stroke-dasharray", function() {
var len = this.getTotalLength();
return function(t) {
return (d3.interpolateString("0," + len, len + ",0"))(t)
};
})
.each('end', anim);
}
});
</script>

给我几分钟时间,大家都会看到一条“蛇形”线路。

关于javascript - 使用 tweendash 制作动画的曲线 d3 线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37696253/

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