{
const context = DOM.context2d(width, height);
const curve = d3.curveBasis(context);
const canvas = context.canvas;
const path = d3.geoPath(projection, context);
const colors = [];
const colorRange = d3.interpolateCool;
const n = 5;
for (let i = 0; i < n; i++) {
colors.push(d3.rgb(colorRange(i / (n - 1))));
}
function drawWardsCities(offsetX, offsetY, strokeColor) {
context.beginPath();
path(tokyoOutline);
context.strokeStyle = strokeColor;
context.lineWidth = 0.5;
context.stroke();
}
function drawArea(strokeColor, fillColor, feature) {
context.beginPath();
path(feature);
context.strokeStyle = strokeColor;
context.fillStyle = fillColor;
context.lineWidth = 0.2;
context.fill();
context.stroke();
}
function draw(drawAreas) {
drawWardsCities(0, 0, colors[0], 0);
if (drawAreas) {
const areaStrokeColor = colors[1];
const areaFillColor = d3.color(colors[2]).copy({ opacity: 0.5 });
for (let feature of tokyoMainlandAreas.features) {
drawArea(areaStrokeColor, areaFillColor, feature);
}
}
}
let cachedImage = null;
function cacheCanvas() {
cachedImage = context.getImageData(
0,
0,
context.canvas.width,
context.canvas.height
);
}
function drawFromCache() {
if (cachedImage) {
context.putImageData(cachedImage, 0, 0);
}
}
function render(transform) {
context.save();
context.clearRect(0, 0, width, height);
if (transform) {
context.translate(transform.x, transform.y);
context.scale(transform.k, transform.k);
}
draw(true);
if (context.canvas.coordinates) {
context.lineWidth = 1;
context.strokeStyle = "#d00";
context.beginPath(),
path({ type: "Point", coordinates: context.canvas.coordinates }),
context.stroke();
}
context.restore();
}
let zoomTransform = d3.zoomIdentity;
let zoomer = d3.zoom().scaleExtent([1, 8]);
d3.select(context.canvas).call(
zoomer.on("zoom", function (evt) {
zoomTransform = evt.transform;
render(zoomTransform);
})
);
draw(true);
cacheCanvas();
render(zoomTransform);
return context.canvas;
}