js-draw
Version:
Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript.
117 lines (116 loc) • 5.03 kB
JavaScript
import { Color4 } from '@js-draw/math';
import { EditorEventType } from '../../types.mjs';
import { toolbarCSSPrefix } from '../constants.mjs';
import makeColorInput from './components/makeColorInput.mjs';
import BaseToolWidget from './BaseToolWidget.mjs';
class TextToolWidget extends BaseToolWidget {
constructor(editor, tool, localization) {
super(editor, tool, 'text-tool-widget', localization);
this.tool = tool;
this.updateDropdownInputs = null;
editor.notifier.on(EditorEventType.ToolUpdated, (evt) => {
if (evt.kind === EditorEventType.ToolUpdated && evt.tool === tool) {
this.updateIcon();
this.updateDropdownInputs?.();
}
});
}
getTitle() {
return this.targetTool.description;
}
createIcon() {
const textStyle = this.tool.getTextStyle();
return this.editor.icons.makeTextIcon(textStyle);
}
fillDropdown(dropdown) {
const container = document.createElement('div');
container.classList.add(`${toolbarCSSPrefix}spacedList`, `${toolbarCSSPrefix}nonbutton-controls-main-list`);
const fontRow = document.createElement('div');
const colorRow = document.createElement('div');
const sizeRow = document.createElement('div');
const fontInput = document.createElement('select');
const fontLabel = document.createElement('label');
const sizeInput = document.createElement('input');
const sizeLabel = document.createElement('label');
const { input: colorInput, container: colorInputContainer, setValue: setColorInputValue, } = makeColorInput(this.editor, (color) => {
this.tool.setColor(color);
});
const colorLabel = document.createElement('label');
const fontsInInput = new Set();
const addFontToInput = (fontName) => {
const option = document.createElement('option');
option.value = fontName;
option.textContent = fontName;
fontInput.appendChild(option);
fontsInInput.add(fontName);
};
sizeInput.setAttribute('type', 'number');
sizeInput.min = '1';
sizeInput.max = '128';
fontLabel.innerText = this.localizationTable.fontLabel;
colorLabel.innerText = this.localizationTable.colorLabel;
sizeLabel.innerText = this.localizationTable.textSize;
colorInput.id = `${toolbarCSSPrefix}-text-color-input-${TextToolWidget.idCounter++}`;
colorLabel.setAttribute('for', colorInput.id);
sizeInput.id = `${toolbarCSSPrefix}-text-size-input-${TextToolWidget.idCounter++}`;
sizeLabel.setAttribute('for', sizeInput.id);
const defaultFonts = this.editor.getCurrentSettings().text?.fonts ?? [];
for (const font of defaultFonts) {
addFontToInput(font);
}
fontInput.classList.add('font-selector');
fontInput.id = `${toolbarCSSPrefix}-text-font-input-${TextToolWidget.idCounter++}`;
fontLabel.setAttribute('for', fontInput.id);
fontInput.onchange = () => {
this.tool.setFontFamily(fontInput.value);
};
sizeInput.onchange = () => {
const size = parseInt(sizeInput.value);
if (!isNaN(size) && size > 0) {
this.tool.setFontSize(size);
}
};
colorRow.appendChild(colorLabel);
colorRow.appendChild(colorInputContainer);
fontRow.appendChild(fontLabel);
fontRow.appendChild(fontInput);
sizeRow.appendChild(sizeLabel);
sizeRow.appendChild(sizeInput);
this.updateDropdownInputs = () => {
const style = this.tool.getTextStyle();
setColorInputValue(style.renderingStyle.fill);
if (!fontsInInput.has(style.fontFamily)) {
addFontToInput(style.fontFamily);
}
fontInput.value = style.fontFamily;
sizeInput.value = `${style.size}`;
};
this.updateDropdownInputs();
container.replaceChildren(colorRow, sizeRow, fontRow);
dropdown.appendChild(container);
return true;
}
serializeState() {
const textStyle = this.tool.getTextStyle();
return {
...super.serializeState(),
fontFamily: textStyle.fontFamily,
textSize: textStyle.size,
color: textStyle.renderingStyle.fill.toHexString(),
};
}
deserializeFrom(state) {
if (state.fontFamily && typeof state.fontFamily === 'string') {
this.tool.setFontFamily(state.fontFamily);
}
if (state.color && typeof state.color === 'string') {
this.tool.setColor(Color4.fromHex(state.color));
}
if (state.textSize && typeof state.textSize === 'number') {
this.tool.setFontSize(state.textSize);
}
super.deserializeFrom(state);
}
}
TextToolWidget.idCounter = 0;
export default TextToolWidget;