literyzjs-timeline/bbtimeline-canvas.js
Ray 0bbed0dfee Changed to multi-layer for hot-tracking and other flourishes
Changed default colours
Added X-Axis top and bottom positions
2023-10-22 22:14:12 +01:00

177 lines
3.6 KiB
JavaScript

class BBTimelineCanvas {
constructor(parentEl, el) {
const a = this;
a.Parent = parentEl;
a.Container = el;
a.CTX = a.Container.getContext("2d");
a.initialiseComponents();
}
initialiseComponents() {
const a = this;
a.Container.style.width = a.Parent.Size.W + "px";
a.Container.style.height = a.Parent.Size.H + "px";
a.Container.style.position = 'absolute';
a.Container.style.border = 'none';
a.CTX.canvas.width = a.Parent.Size.W;
a.CTX.canvas.height = a.Parent.Size.H;
a.Clear();
}
get ClientRectangle() {
const a = this;
return {
X: a.Parent.Padding.Left,
Y: a.Parent.Padding.Top,
W: (a.Parent.Size.W - (a.Parent.Padding.Left + a.Parent.Padding.Right)),
H: (a.Parent.Size.H - (a.Parent.Padding.Top + a.Parent.Padding.Bottom))
};
}
Clear() {
const a = this;
a.CTX.clearRect(0, 0, a.CTX.canvas.width, a.CTX.canvas.height);
}
Invalidate() {
// placeholder
}
drawCircle(x, y, width, borderWidth, borderColour, backColour) {
const a = this;
const calcBorderWidth = (borderWidth * 2);
const calcWidth = width - calcBorderWidth;
const offset = a.half(width);
a.CTX.beginPath();
a.CTX.arc(x, y, calcWidth, 0, 2 * Math.PI, false);
a.CTX.fillStyle = backColour;
a.CTX.fill();
a.CTX.lineWidth = borderWidth;
a.CTX.strokeStyle = borderColour;
a.CTX.stroke();
const result = {
X: x - (offset + borderWidth),
Y: y - (offset + borderWidth),
W: (width + calcBorderWidth),
H: (width + calcBorderWidth)
};
return result;
}
drawRectangle(rectangle, colour) {
const a = this;
a.CTX.beginPath();
a.CTX.rect(rectangle.X, rectangle.Y, rectangle.W, rectangle.H);
//a.ctx.fillStyle = 'yellow';
//a.ctx.fill();
a.CTX.lineWidth = 1;
a.CTX.strokeStyle = colour;
a.CTX.stroke();
return rectangle;
}
drawText(x, y, label, font, foreColour, align) {
const a = this;
a.CTX.font = font;
a.CTX.fillStyle = foreColour;
let size = a.measureText(font, label);
size.Y = y;
switch (align) {
case "center":
size.X = (x - size.X);
break;
case "right":
size.X = (x - size.W);
break;
case "left":
default:
size.X = x;
break;
}
a.CTX.fillText(label, size.X, (size.Y + size.H));
return size;
}
drawVerticalLine(x, y1, y2, width, colour) {
const a = this;
a.CTX.beginPath();
a.CTX.moveTo(x, y1);
a.CTX.lineTo(x, (y2 - width));
a.CTX.lineWidth = width;
a.CTX.strokeStyle = colour;
a.CTX.stroke();
const result = {
X: x,
Y: y1,
W: width,
H: (y2 - y1)
};
return result;
}
half(value) {
return (value / 2);
}
measureText(font, value) {
const a = this;
a.CTX.font = font;
const size = a.CTX.measureText(value);
return {
W: size.width,
H: size.fontBoundingBoxAscent,
X: a.half(size.width),
Y: a.half(size.fontBoundingBoxAscent)
};
}
isPointInRectangle(rect, point) {
const x2 = (rect.X + rect.W);
const y2 = (rect.Y + rect.H);
return ((point.X >= rect.X) && (point.X <= x2) && (point.Y >= rect.Y) && (point.Y <= y2));
}
combineRectangle(rect1, rect2) {
const x2 = Math.max((rect1.X + rect1.W), (rect2.X + rect2.W));
const y2 = Math.max((rect1.Y + rect1.H), (rect2.Y + rect2.H));
const rect = {
X: Math.min(rect1.X, rect2.X),
Y: Math.min(rect1.Y, rect2.Y),
W: 0,
H: 0
};
rect.W = x2 - rect.X;
rect.H = y2 - rect.Y;
return rect;
}
}