Commit dd84b52d authored by Derek Schaab's avatar Derek Schaab

Support high-DPI output

parent 24d2a923
Pipeline #13775578 passed with stage
in 48 seconds
{
"name": "odv-js",
"version": "0.1.1",
"version": "0.1.2",
"description": "Parses Open Data Visualization Markup Language and renders to HTML 5 Canvas",
"main": "lib/main.js",
"types": "lib/main.d.ts",
......
......@@ -45,20 +45,30 @@ interface TextChunk {
export class CanvasTarget implements Target {
canvas: HTMLCanvasElement;
ctx: CanvasRenderingContext2D;
w: number;
h: number;
ratio: number;
private pendingTexts: TextChunk[] = [];
constructor(el: HTMLCanvasElement) {
this.canvas = el;
this.w = this.canvas.width;
this.h = this.canvas.height;
this.ratio = window.devicePixelRatio || 1;
this.canvas.width = this.w * this.ratio;
this.canvas.height = this.h * this.ratio;
this.canvas.style.width = `${this.w}px`;
this.canvas.style.height = `${this.h}px`;
const ctx = el.getContext('2d');
if (ctx === null) {
throw new Error('sdvml: unable to acquire 2D rendering context');
}
this.ctx = ctx;
this.canvas = el;
}
arc(x: number, y: number, r: number, a1: number, a2: number) {
this.ctx.arc(x, y, r, a1, a2, a1 > a2);
this.ctx.arc(this.ratio * x, this.ratio * y, this.ratio * r, a1, a2, a1 > a2);
}
begin() {
......@@ -75,7 +85,7 @@ export class CanvasTarget implements Target {
}
cube(c1x: number, c1y: number, c2x: number, c2y: number, x: number, y: number) {
this.ctx.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);
this.ctx.bezierCurveTo(this.ratio * c1x, this.ratio * c1y, this.ratio * c2x, this.ratio * c2y, this.ratio * x, this.ratio * y);
}
end() {
......@@ -93,36 +103,36 @@ export class CanvasTarget implements Target {
this.ctx.textAlign = t.align;
if (t.rotate) {
this.ctx.save();
this.ctx.translate(t.x, t.y);
this.ctx.translate(this.ratio * t.x, this.ratio * t.y);
this.ctx.rotate(t.rotate);
this.ctx.fillText(t.s, 0, 0);
this.ctx.restore();
} else {
this.ctx.fillText(t.s, t.x, t.y);
this.ctx.fillText(t.s, this.ratio * t.x, this.ratio * t.y);
}
}
});
}
height(): number {
return this.canvas.height;
return this.h;
}
line(x: number, y: number) {
this.ctx.lineTo(x, y);
this.ctx.lineTo(this.ratio * x, this.ratio * y);
}
move(x: number, y: number) {
this.ctx.moveTo(x, y);
this.ctx.moveTo(this.ratio * x, this.ratio * y);
}
quad(cx: number, cy: number, x: number, y: number) {
this.ctx.quadraticCurveTo(cx, cy, x, y);
this.ctx.quadraticCurveTo(this.ratio * cx, this.ratio * cy, this.ratio * x, this.ratio * y);
}
stroke(g: Gradient, width: number, cap: 'butt' | 'round' | 'square', join: 'miter' | 'round' | 'bevel', dash: string) {
this.paint(g, (style: string | CanvasGradient) => {
this.ctx.lineWidth = width;
this.ctx.lineWidth = this.ratio * width;
this.ctx.lineCap = cap;
this.ctx.lineJoin = join;
this.ctx.setLineDash(dash.split(',').map(d => parseFloat(d.trim()) || 0));
......@@ -139,7 +149,7 @@ export class CanvasTarget implements Target {
this.ctx.strokeText(t.s, 0, 0);
this.ctx.restore();
} else {
this.ctx.strokeText(t.s, t.x, t.y);
this.ctx.strokeText(t.s, this.ratio * t.x, this.ratio * t.y);
}
}
});
......@@ -152,13 +162,13 @@ export class CanvasTarget implements Target {
x: x,
y: y,
align: align,
font: `${style} ${w} ${size}px ${font}`,
font: `${style} ${w} ${this.ratio * size}px ${font}`,
rotate: rotate || 0
});
}
width(): number {
return this.canvas.width;
return this.w;
}
private paint(g: Gradient, apply: (style: string | CanvasGradient) => void) {
......@@ -171,7 +181,7 @@ export class CanvasTarget implements Target {
apply(`rgba(${Math.round(255 * color.r)},${Math.round(255 * color.g)},${Math.round(255 * color.b)},${color.a})`)
return;
}
const gradient = this.ctx.createLinearGradient(g.x1, g.y1, g.x2, g.y2);
const gradient = this.ctx.createLinearGradient(this.ratio * g.x1, this.ratio * g.y1, this.ratio * g.x2, this.ratio * g.y2);
for (let i = 0; i < g.colors.length; i++) {
const color = g.colors[i];
gradient.addColorStop(color.offset, `rgba(${Math.round(255 * color.r)},${Math.round(255 * color.g)},${Math.round(255 * color.b)},${color.a})`);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment