bigbluebutton-Github/bbb-export-annotations/shapes/Frame.js
2024-03-19 20:08:48 +01:00

100 lines
2.3 KiB
JavaScript

import {Shape} from './Shape.js';
import {Rect, Text, ClipPath, Defs, G} from '@svgdotjs/svg.js';
import {ColorTypes} from '../shapes/Shape.js';
import {overlayAnnotation} from '../workers/process.js';
/**
* Creates an SVG frame from Tldraw v2 pencil data.
*
* @class Frane
* @extends {Shape}
*/
export class Frame extends Shape {
/**
* @param {Object} frame - The Frame shape JSON.
*/
constructor(frame) {
super(frame);
this.name = this.props?.name;
this.w = this.props?.w;
this.h = this.props?.h;
this.children = frame.children;
}
/**
* Renders the frame object as an SVG group element.
*
* @return {G} - An SVG group element.
*/
draw() {
// Parent group
const frameGroup = this.shapeGroup;
// Group for clipped elements
const clipGroup = new G();
const fillColor = Shape.colorToHex(ColorTypes.SemiFillColor,
ColorTypes.SemiFillColor);
const frameLabel = this.name || 'Frame';
// The text element is not clipped
const textElement = new Text()
.text(frameLabel)
.move(0, -20)
.font({
'family': 'Arial',
'size': 12,
})
.fill('black');
// The frame rectangle that is not clipped
const frame = new Rect({
'x': 0,
'y': 0,
'width': this.w,
'height': this.h,
'stroke': 'black',
'stroke-width': 1,
'fill': fillColor,
});
// Create the clip path with the same properties as the frame
const clipPath = new ClipPath().id(`clipFrame-${this.id}`);
const clipFrame = new Rect({
'x': 0,
'y': 0,
'width': this.w,
'height': this.h,
});
clipPath.add(clipFrame);
// Definitions for clip paths
const defs = new Defs();
defs.add(clipPath);
// Add defs to the parent group
frameGroup.add(defs);
const children = this.children || [];
// Add the children to the clipGroup so they will be clipped
children.forEach((child) => {
overlayAnnotation(clipGroup, child);
});
// Apply clipping to the clipGroup only
clipGroup.clipWith(clipPath);
// Add non-clipped...
frameGroup.add(frame);
frameGroup.add(textElement);
// ...and clipped elements to the frame group
frameGroup.add(clipGroup);
return frameGroup;
}
}