假设您想要一个html页面,其中整个背景是一个svg,这样就会有一些动画不断进行。在这个愚蠢的例子中,我做了一个随意移动的笑脸。虽然有些人可能会发现布朗运动对眼睛有吸引力,但如果svg元素随着动量(方向和旋转)的出现而移动会更好。
有人可能会很快意识到,让一个物体沿着一条路径移动可以解决这个问题,它会......对于物体的第一次传递。但是,如果元素被屏幕限制,那么如何进行调整以适应偏转?
简而言之,问题如下:
使用d3.js v4如何在html页面中显示svg元素(例如下面的演示中的#Mr_Smiley
)?*
*让浮动意味着沿着svg空间内的矢量或弧线以恒定速度平稳地移动,在击中边界时反弹并正确偏转
var mr_s = d3.select("svg").append("g").attr("id", "Mr_Smiley")
mr_s.append("circle").attr("cx", 30).attr("cy", 30).attr("r", 30).style("fill","yellow").style("stroke", "black")
mr_s.append("circle").attr("cx", 20).attr("cy", 20).attr("r", 5).style("fill","black")
mr_s.append("circle").attr("cx", 40).attr("cy", 20).attr("r", 5).style("fill","black")
mr_s.append("path").attr("d", "M20 40 A 10 10 0 0 0 40 40").style("fill","black")
mr_s.datum({"x": 30, "y": 30, "r": 1})
mr_s.attr("transform", function(d) {"translate(" + d.x + ", " + d.y + ") rotate(" + d.r + ")"})
dur = 100
step = 10
// Lets have Mr. S go for a trip
d3.select("#Mr_Smiley")
.transition()
.duration(dur)
.on("start", function repeat() {
d3.active(this)
.attr("transform",
function(d)
{
// update y
if (Math.random() >= .5) {
d.y += step
} else {
d.y -= step
// basic bounds
if (d.y < 0) {
d.y = 0
}
}
// update x
if (Math.random() >= .5) {
d.x += step
} else {
d.x -= step
if (d.x < 0) {
d.x = 0
}
}
// update r
if (Math.random() >= .5) {
d.r += step
} else {
d.r -= step
}
return "translate(" + d.x + ", " + d.y + ") rotate(" + d.r + ")"
})
.transition()
.attr("transform",
function(d)
{
// update y
if (Math.random() >= .5) {
d.y += step
} else {
d.y -= step
}
// update x
if (Math.random() >= .5) {
d.x += step
} else {
d.x -= step
}
// update r
if (Math.random() >= .5) {
d.r += step
} else {
d.r -= step
}
return "translate(" + d.x + ", " + d.y + ") rotate(" + d.r + ")"
})
.transition()
.on("start", repeat)
})
mr_s.on("mouseover", mouseover)
mr_s.on("mouseout", mouseout)
function mouseover(d, i) {
var svg = d3.select("svg")
svg.append("text").attr("id", "mouseover_text").text("god help me, this is so unsmooth").attr("x", d.x).attr("y", d.y)
}
function mouseout(d, i) {
d3.select("#mouseover_text").remove()
}
&#13;
html, body {
width: 100%;
height: 100%;
}
svg {
position: absolute;
width: 100%;
height: 100%;
background-color: light-blue;
border: 1px black solid;
}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
<h1>
Mr. Smiley goes on a trip
</h1>
&#13;
答案 0 :(得分:1)
这是最简单的S.先生在我可以使用d3
惯例编码的房间周围反弹:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
var w = 250,
h = 250,
r = 30;
var svg = d3.select('body')
.append('svg')
.attr('width', w)
.attr('height', h)
.style('border', '1px solid steelblue');
var ix = Math.random() * ((Math.random() > 0.5) ? 5 : -5),
iy = Math.random() * ((Math.random() > 0.5) ? 5 : -5),
x = w / 2,
y = h / 2;
var mr_s = svg.append("g")
.attr("id", "Mr_Smiley")
mr_s.append("circle")
.attr("r", r)
.style("fill", "yellow")
.style("stroke", "black");
mr_s.append("circle")
.attr("cx", -10)
.attr("cy", -10)
.attr("r", 5)
.style("fill", "black");
mr_s.append("circle")
.attr("cx", 10)
.attr("cy", -10)
.attr("r", 5)
.style("fill", "black");
mr_s.append("path")
.attr("d", "M-10 10 A 10 10 0 0 0 10 10")
.style("fill", "black");
mr_s.attr('transform', 'translate(' + x + ',' + y + ')');
d3.interval(tick, 20);
function tick() {
x += ix;
y += iy;
if (x > (w - r) || x < r) {
ix = -ix;
}
if (y > (h - r) || y < r) {
iy = -iy;
}
mr_s.attr('transform', 'translate(' + x + ',' + y + ')');
}
</script>
</body>
</html>