<!DOCTYPE html>
<meta charset="UTF-8">
<title>HTML Canvas Library</title>
<style>
canvas {
border: 2px gray ridge;
}
</style>
<body>
<canvas width="500" height="250"></canvas>
<canvas width="500" height="250"></canvas>
<canvas width="500" height="250"></canvas>
<canvas width="500" height="250"></canvas>
<canvas width="500" height="250"></canvas>
<script>
class Canvas {
#col = 'black'; #view = [ ];
constructor (canvas, option) {
this.canvas = canvas;
this.option = Object.assign ({ }, this.constructor.defOption, option);
this.ctx = canvas.getContext ('2d');
}
cls () {
this.canvas.width = this.canvas.clientWidth;
this.viewport (...this.#view);
return this;
}
line (x, y, x1, y1) {
let { ctx } = this;
ctx.beginPath ();
ctx.moveTo (x, y);
ctx.lineTo (x1, y1);
ctx.closePath ();
ctx.stroke ();
return this;
}
viewport (maxX = this.canvas.clientWidth, maxY = this.canvas.clientHeight, minX = 0, minY = 0, deg = 0) {
const
{ canvas, ctx, option } = this,
{ sin, cos, trunc: int, abs, log10, PI: pi } = Math,
digitNum = n=> int (log10 (n) + 1);//桁数を求める
let
w = canvas.clientWidth,
h = canvas.clientHeight,
dx = maxX - minX,
dy = maxY - minY,
uw = w / dx,
uh = h / dy,
ur = deg * (pi / 180);
ctx.setTransform (
uw * cos (ur),
-sin (ur) * uh,
-sin (ur) * uw ,
-uh * cos (ur),
-minX * uw,
maxY * uh,
);
ctx.lineWidth = 1 / (uw + uh) * 1.;//線の太さは、縦横軸の平均から算出
if (option.grid) {
ctx.save ();
//グリッドの間隔を2点の距離から算出する
let
mx = 10 ** (digitNum (uw)),
my = 10 ** (digitNum (uh)),
nx = mx / 10,
ny = my / 10,
sx = int ((minX - abs (dx)) / nx) * nx,
ex = int ((maxX + abs (dx)) / nx) * nx,
sy = int ((minY - abs (dy)) / ny) * ny,
ey = int ((maxY + abs (dy)) / ny) * ny;
console.log(uw, uh,mx,my, sx,ex,sy,ey);
this.color = 'silver';
// for (let p = sx; p < ex; p += nx / 100) this.line (p, sy, p, ey);
// for (let p = sy; p < ey; p += nx / 100) this.line (sx, p, ex, p);
this.color = 'silver';
// for (let p = sx; p < ex; p += nx / 10) this.line (p, sy, p, ey);
// for (let p = sy; p < ey; p += nx / 10) this.line (sx, p, ex, p);
this.color = 'gray';
for (let p = sx; p < ex; p += nx) this.line (p, sy, p, ey);
for (let p = sy; p < ey; p += ny) this.line (sx, p, ex, p);
this.color = 'black';
this.line (0, sy, 0, ey);
this.line (sx, 0, ex, 0);
ctx.restore ();
}
this.#view = [maxX, maxY, minX, minY, deg];
return this;
}
set color (arg) {this.ctx.strokeStyle = this.#col = arg; }
get color () { return this.#col; }
static defOption = {
grid: true,
}
static create (canvas = document.querySelector ('canvas'), option = { }) {
return new this (canvas, option);
}
}
</script>