presentationmaker_js/src/rendertree/rtoptions.ts
2024-07-05 20:14:52 +02:00

125 lines
3.3 KiB
TypeScript

/**
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
* SPDX-License-Identifier: GPL-3.0-or-later
* @author Author: Sascha Nitsch (grumpydeveloper)
* @internal
**/
import { PresentationMaker } from '../presentationmaker';
import { RTNode } from './rtnode';
import { RenderTree } from './rendertree';
/**
* transform subtree by given options
*/
export class RTOptions extends RTNode {
/** blend mode */
private blendmode: string;
/** flip axis */
private flip: string;
/** opactity */
private opacity: string;
/** rotate */
private rotate: string;
/** subtee to transform */
private subtree: RenderTree;
/** y position when flipping */
private y: string;
/**
* clone function
* @return a copy of us
*/
clone(): RTOptions {
return new RTOptions(
this.root,
this.subtree,
this.opacity,
this.blendmode,
this.flip,
this.rotate,
this.y
);
}
/**
* constructor
* @param root parent RenderTree
* @param subtree child sub tree
* @param opacity opacity value
* @param blendmode blend mode
* @param flip flip axis
* @param rotate rotation in degree X, Y, Z
* @param y y position when flipping
*/
constructor(root: RenderTree, subtree: RenderTree, opacity: string, blendmode: string, flip: string, rotate: string, y: string) {
super(root);
this.subtree = subtree;
this.opacity = opacity;
this.blendmode = blendmode;
this.flip = flip;
this.rotate = rotate;
this.y = y;
}
/**
* create RTOptions from given node into given RenderTree
* @param root render tree to insert to
* @param node input node
* @returns new RTOptions node
*/
static fromElem(main: PresentationMaker, root: RenderTree, node: HTMLElement): RTOptions {
const subtree = new RenderTree(main);
subtree.createFromElem(node);
return new RTOptions(
root,
subtree,
this.getField(node, 'opacity') || '',
this.getField(node, 'blend') || '',
this.getField(node, 'flip') || '',
this.getField(node, 'rotate') || '',
this.getField(node, 'y') || ''
);
}
/**
* render our element into target
* @param target target to render into
*/
render(target: HTMLElement): void {
const div = document.createElement('div');
div.classList.add('option');
if (this.opacity !== '') {
div.style.opacity = this.opacity;
}
if (this.blendmode !== '') {
div.style.mixBlendMode = this.blendmode;
}
if (this.flip !== '') {
if (this.flip == 'v') {
div.style.transform = 'scaleY(-1)';
}
}
if (this.y) {
div.style.position = 'absolute';
div.style.bottom = '0px';
}
if (this.rotate !== '') {
const r = this.rotate.split(',');
let transform = '';
if (r[0]) {
transform += 'rotateX(' + (this.calc(this.resolveString(r[0]))) + 'deg)';
}
if (r[1]) {
transform += 'rotateY(' + (this.calc(this.resolveString(r[1]))) + 'deg)';
}
if (r[2]) {
transform += 'rotateZ(' + (this.calc(this.resolveString(r[2]))) + 'deg)';
}
div.style.transform = transform;
div.style.transformOrigin = 'top left';
}
this.subtree.render(div);
target.append(div);
}
}