so i found codepen with the perfect d3 drag rotate animation except that i need points to be smaller. I don't understand how do I customize them? I tried to fix size of points by adding a stroke but nothing seems to be working
I use d3.js v5
https://codepen.io/pr0da/pen/OmzKNq
here is CSS styles:
.point {
fill: #000;
stroke: #fff;
}
.edge {
fill: none;
stroke: #000;
stroke-opacity: .4;
}
.face {
fill: #eee;
fill-rule: nonzero;
}
and d3 script
/**
* Resources:
* https://bl.ocks.org/ivyywang/7c94cb5a3accd9913263
* https://bl.ocks.org/mbostock/3055104
*
*/
var width = 960, height = 500;
var sens = 0.25;
var velocity = [0.18, 0.06];
var projection = d3.geoOrthographic().scale(240);
var path = d3.geoPath().projection({
stream: function(out) {
return {
point: function(x, y) {
var p = projection([x, y]);
out.point(p[0], p[1]);
},
lineStart: function() {
out.lineStart();
},
lineEnd: function() {
out.lineEnd();
},
polygonStart: function() {
out.polygonStart();
},
polygonEnd: function() {
out.polygonEnd();
}
};
}
});
var svg = d3
.select("#root")
.append("svg")
.attr("width", width)
.attr("height", height);
var face = svg
.selectAll(".face")
.data(icosahedron_faces)
.enter()
.append("path")
.attr("class", "face");
const points = icosahedron_points();
console.log(JSON.stringify(points));
var edge = svg.append("path").datum(icosahedron_edges).attr("class", "edge");
var point = svg.append("path").datum({
type: "MultiPoint", coordinates: points
}).attr("class", "point");
var dragging = false;
var drag = d3.drag()
.subject(function() { var r = projection.rotate(); return {x: r[0] / sens, y: -r[1] / sens}; })
.on("start", () => {
dragging = true;
})
.on("end", () => {
dragging = false;
})
.on("drag", function() {
var rotate = projection.rotate();
projection.rotate([d3.event.x * sens, -d3.event.y * sens, rotate[2]]);
refresh();
});
svg.call(drag);
d3.timer(function(elapsed) {
if(!dragging) {
const r = projection.rotate();
projection.rotate([r[0] + velocity[0], r[1] + velocity[1]]);
refresh();
}
});
function refresh() {
point.attr("d", path);
edge.attr("d", path);
face.attr("d", path);
}
function icosahedron_points() {
var points = [], y = Math.atan2(1, 2) * 180 / Math.PI;
points.push([0, -90]);
for (var x = 0; x < 360; x += 36) {
points.push([x, -y], [(x += 36), y]);
}
points.push([0, 90]);
return points;
}
function icosahedron_edges() {
var edges = [], y = Math.atan2(1, 2) * 180 / Math.PI;
for (var x = 0; x < 360; x += 72) {
edges.push([[x + 0, -90], [x + 0, -y]]);
edges.push([[x + 0, -y], [x + 72, -y]]);
edges.push([[x + 36, y], [x - 36, y]]);
edges.push([[x + 36, y], [x + 0, -y]]);
edges.push([[x - 36, y], [x + 0, -y]]);
edges.push([[x + 36, 90], [x + 36, y]]);
}
console.log(JSON.stringify(edges));
return { type: "MultiLineString", coordinates: edges };
}
function icosahedron_faces() {
var faces = [], y = Math.atan2(1, 2) * 180 / Math.PI;
for (var x = 0; x < 360; x += 72) {
faces.push([[[x + 0, -90], [x + 0, -y], [x + 72, -y], [x + 0, -90]]]);
faces.push([[[x + 0, -y], [x + 72, -y], [x + 36, y], [x + 0, -y]]]);
faces.push([[[x + 36, y], [x + 0, -y], [x - 36, y], [x + 36, y]]]);
faces.push([[[x - 36, 90], [x - 36, y], [x + 36, y], [x + 36, 90]]]);
}
return faces.map(function(face) {
return { type: "Polygon", coordinates: face };
});
///
}
Call pointRadius()
on the d3.geoPath()
.
Example settings the radius to 10:
var path = d3.geoPath()
.pointRadius(10)
.projection({
stream: function(out) {
return {
...
Reference: https://d3js.org/d3-geo/path#path_pointRadius
Found the solution here: https://stackoverflow.com/a/23109568/7376577