d3.js でドラッグ可能で、かつ、簡単な物理シミュレーションをする任意の画像を描画するサンプルです。
ソースコードです。コピペで動くと思います。
<svg width="800" height="600"></svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"
integrity="sha512-M7nHCiNUOwFt6Us3r8alutZLm9qMt4s9951uo8jqO4UwJ1hziseL6O3ndFyigx6+LREfZqnhHxYjKRJ8ZQ69DQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
const width = document.querySelector("svg").clientWidth;
const height = document.querySelector("svg").clientHeight;
const nodeCount = 51;
const nodesData = [];
for (let i = 0; i < nodeCount; i++) {
nodesData.push({
"x": width * Math.random(),
"y": height * Math.random(),
"r": 50
});
}
const images = d3.select("svg")
.selectAll("image")
.data(nodesData)
.enter()
.append("image")
.attr("href", "images/Sora.png")
.attr("height", 100)
.attr("width", 100)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
const simulation = d3.forceSimulation()
.force("collide",
d3.forceCollide()
.radius(function (d) { return d.r; })
.strength(1.1)
.iterations(16))
.force("x", d3.forceX().strength(0.02).x(width / 2))
.force("y", d3.forceY().strength(0.02).y(height / 2));
simulation
.nodes(nodesData)
.on("tick", ticked);
function ticked() {
images
.attr("x", d => d.x)
.attr("y", d => d.y);
}
function dragstarted(e, d) {
if (!e.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(e, d) {
d.fx = e.x;
d.fy = e.y;
}
function dragended(e, d) {
if (!e.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
</script>