bigbluebutton-Github/bbb-export-annotations/shapes/Star.js

91 lines
2.7 KiB
JavaScript
Raw Normal View History

import {Polygon as SVGPolygon} from '@svgdotjs/svg.js';
import {Geo} from './Geo.js';
import {TAU} from './helpers.js';
/**
* Creates an SVG star shape from Tldraw v2 JSON data.
*
* @class Star
* @extends {Geo}
*/
export class Star extends Geo {
/**
* Calculates the vertices of an n-point star.
*
* @param {number} w - The width of the bounding box.
* @param {number} h - The height of the bounding box.
* @param {number} n - The number of points on the star.
* @return {Array} - An array of {x, y} objects representing star vertices.
* @see {@link https://github.com/tldraw/tldraw/blob/main/packages/editor/src/lib/primitives/utils.ts} Adapted from Tldraw.
*/
getStarVertices(w, h, n) {
const sides = n;
const step = TAU / sides / 2;
const rightMostIndex = Math.floor(sides / 4) * 2;
const leftMostIndex = sides * 2 - rightMostIndex;
const topMostIndex = 0;
const bottomMostIndex = Math.floor(sides / 2) * 2;
const maxX = (Math.cos(-(TAU/4) + rightMostIndex * step) * w) / 2;
const minX = (Math.cos(-(TAU/4) + leftMostIndex * step) * w) / 2;
const minY = (Math.sin(-(TAU/4) + topMostIndex * step) * h) / 2;
const maxY = (Math.sin(-(TAU/4) + bottomMostIndex * step) * h) / 2;
const diffX = w - Math.abs(maxX - minX);
const diffY = h - Math.abs(maxY - minY);
const offsetX = w / 2 + minX - (w / 2 - maxX);
const offsetY = h / 2 + minY - (h / 2 - maxY);
const ratio = 1;
const cx = (w - offsetX) / 2;
const cy = (h - offsetY) / 2;
const ox = (w + diffX) / 2;
const oy = (h + diffY) / 2;
const ix = (ox * ratio) / 2;
const iy = (oy * ratio) / 2;
const points = Array.from(Array(sides * 2)).map((_, i) => {
const theta = -(TAU/4) + i * step;
return {
x: cx + (i % 2 ? ix : ox) * Math.cos(theta),
y: cy + (i % 2 ? iy : oy) * Math.sin(theta),
};
});
return points;
}
/**
* Draws a star shape on the SVG canvas.
* @return {G} Returns the SVG group element containing the star.
*/
draw() {
const width = this.w;
const height = this.h + this.growY;
// Get the vertices of the star
const pointsOnPerimeter = this.getStarVertices(width, height, 5);
// Convert the vertices to SVG polygon points format
const points = pointsOnPerimeter.map((p) => `${p.x},${p.y}`).join(' ');
// Create the SVG polygon
const starGroup = this.shapeGroup;
const star = new SVGPolygon({
points,
'stroke': this.shapeColor,
'stroke-width': this.thickness,
'style': this.dasharray,
});
// Fill the polygon if required
this.setFill(star);
starGroup.add(star);
this.drawLabel(starGroup);
return starGroup;
}
}