UNPKG

@patricksurry/g3

Version:

A flexible Javascript framework for building steam gauge instrument panels that display live external metrics from flight (or other) simulators like XPlane or MS FS2020

86 lines (72 loc) 2.53 kB
<!DOCTYPE html> <html> <head> <style> svg text { font-family: Gill Sans,Gill Sans MT,Calibri,sans-serif; text-anchor: middle; dominant-baseline: central; font-stretch: condensed; } </style> <body> <script src="https://d3js.org/d3.v7.min.js"></script> <svg width=1200 height=600> </svg> <script> const projection = d3.geoProjection(function(lngrad, latrad) { return [Math.sin(lngrad), 2*latrad/Math.PI]; }).scale(100).translate([0,0]).clipAngle(90).rotate([45,0]); projection.gradient = ([lng, lat]) => { const [rlng, rlat] = projection.rotate(); return [Math.cos((lng + rlng)*Math.PI/180), 1]; }; projection.deformation = ([lng, lat]) => { // returns an SVG transformation representing how a an infinitesimal square at [lng, lat] // is projected to a rhombus centered at the projected [x, y], // see https://en.wikipedia.org/wiki/Infinitesimal_strain_theory // TOOD make clipping and absolute/relative (i.e. including translate) options const [x,y] = projection([lng, lat]); var [sx, sy] = projection.gradient([lng, lat]); if (sx <= 0) sx = sy = 0; // clip rear-facing objects return `translate(${x},${y}) scale(${sx},${sy})`; } projection.path = d3.geoPath(projection); var svg = d3.select('svg') .append('g') .attr('transform', 'translate(600, 300)'); svg.append('path') .attr('style', 'stroke: red; stroke-width: 3; fill: none') .attr('d', projection.path({ type: "LineString", coordinates: d3.range(-540, 541, 5).map(v => [v, v/6]) }) ); var ticks = svg.selectAll(null) .data(d3.range(0, 360, 30)) .enter().append('g'); var tickmarks = ticks.append('path') .datum(v => {return {type: 'LineString', coordinates: [[v,-5], [v, 5]]}}) .attr('style', 'stroke: grey; fill: none') .attr('d', projection.path); var ticklabels = ticks.append('text') .text(v => v) .datum(v => [v, 10]) .attr('transform', projection.deformation) svg.append('path') .attr('style', 'stroke: blue; stroke-width: 3; fill: none') .attr('d', projection.path({ type: "LineString", coordinates: d3.range(-180, 180, 30).map(v => [v, 0]) }) ); setInterval(function() { const [lng, lat] = projection.rotate(); projection.rotate([lng+5,lat]); tickmarks.transition().duration(250).attr('d', projection.path); ticklabels.transition().duration(250).attr('transform', projection.deformation); }, 250); </script> </body> </html>