UNPKG

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
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;