Fanu2's picture
Deploy full app to HF Space
b456468
import Range from '@/ui/tools/range';
import Colorpicker from '@/ui/tools/colorpicker';
import Submenu from '@/ui/submenuBase';
import templateHtml from '@/ui/template/submenu/text';
import { assignmentForDestroy } from '@/util';
import { defaultTextRangeValues, eventNames, selectorNames } from '@/consts';
/**
* Crop ui class
* @class
* @ignore
*/
class Text extends Submenu {
constructor(subMenuElement, { locale, makeSvgIcon, menuBarPosition, usageStatistics }) {
super(subMenuElement, {
locale,
name: 'text',
makeSvgIcon,
menuBarPosition,
templateHtml,
usageStatistics,
});
this.effect = {
bold: false,
italic: false,
underline: false,
};
this.align = 'tie-text-align-left';
this._els = {
textEffectButton: this.selector('.tie-text-effect-button'),
textAlignButton: this.selector('.tie-text-align-button'),
textColorpicker: new Colorpicker(this.selector('.tie-text-color'), {
defaultColor: '#ffbb3b',
toggleDirection: this.toggleDirection,
usageStatistics: this.usageStatistics,
}),
textRange: new Range(
{
slider: this.selector('.tie-text-range'),
input: this.selector('.tie-text-range-value'),
},
defaultTextRangeValues
),
};
this.colorPickerInputBox = this._els.textColorpicker.colorpickerElement.querySelector(
selectorNames.COLOR_PICKER_INPUT_BOX
);
}
/**
* Destroys the instance.
*/
destroy() {
this._removeEvent();
this._els.textColorpicker.destroy();
this._els.textRange.destroy();
assignmentForDestroy(this);
}
/**
* Add event for text
* @param {Object} actions - actions for text
* @param {Function} actions.changeTextStyle - change text style
*/
addEvent(actions) {
const setTextEffect = this._setTextEffectHandler.bind(this);
const setTextAlign = this._setTextAlignHandler.bind(this);
this.eventHandler = {
setTextEffect,
setTextAlign,
};
this.actions = actions;
this._els.textEffectButton.addEventListener('click', setTextEffect);
this._els.textAlignButton.addEventListener('click', setTextAlign);
this._els.textRange.on('change', this._changeTextRnageHandler.bind(this));
this._els.textColorpicker.on('change', this._changeColorHandler.bind(this));
this.colorPickerInputBox.addEventListener(
eventNames.FOCUS,
this._onStartEditingInputBox.bind(this)
);
this.colorPickerInputBox.addEventListener(
eventNames.BLUR,
this._onStopEditingInputBox.bind(this)
);
}
/**
* Remove event
* @private
*/
_removeEvent() {
const { setTextEffect, setTextAlign } = this.eventHandler;
this._els.textEffectButton.removeEventListener('click', setTextEffect);
this._els.textAlignButton.removeEventListener('click', setTextAlign);
this._els.textRange.off();
this._els.textColorpicker.off();
this.colorPickerInputBox.removeEventListener(
eventNames.FOCUS,
this._onStartEditingInputBox.bind(this)
);
this.colorPickerInputBox.removeEventListener(
eventNames.BLUR,
this._onStopEditingInputBox.bind(this)
);
}
/**
* Returns the menu to its default state.
*/
changeStandbyMode() {
this.actions.stopDrawingMode();
}
/**
* Executed when the menu starts.
*/
changeStartMode() {
this.actions.modeChange('text');
}
/**
* Get text color
* @returns {string} - text color
*/
get textColor() {
return this._els.textColorpicker.color;
}
set textColor(color) {
this._els.textColorpicker.color = color;
}
/**
* Get text size
* @returns {string} - text size
*/
get fontSize() {
return this._els.textRange.value;
}
/**
* Set text size
* @param {Number} value - text size
*/
set fontSize(value) {
this._els.textRange.value = value;
}
/**
* get font style
* @returns {string} - font style
*/
get fontStyle() {
return this.effect.italic ? 'italic' : 'normal';
}
/**
* get font weight
* @returns {string} - font weight
*/
get fontWeight() {
return this.effect.bold ? 'bold' : 'normal';
}
/**
* get text underline text underline
* @returns {boolean} - true or false
*/
get underline() {
return this.effect.underline;
}
setTextStyleStateOnAction(textStyle = {}) {
const { fill, fontSize, fontStyle, fontWeight, textDecoration, textAlign } = textStyle;
this.textColor = fill;
this.fontSize = fontSize;
this.setEffectState('italic', fontStyle);
this.setEffectState('bold', fontWeight);
this.setEffectState('underline', textDecoration);
this.setAlignState(`tie-text-align-${textAlign}`);
}
setEffectState(effectName, value) {
const effectValue = value === 'italic' || value === 'bold' || value === 'underline';
const button = this._els.textEffectButton.querySelector(
`.tui-image-editor-button.${effectName}`
);
this.effect[effectName] = effectValue;
button.classList[effectValue ? 'add' : 'remove']('active');
}
setAlignState(value) {
const button = this._els.textAlignButton;
button.classList.remove(this.align);
button.classList.add(value);
this.align = value;
}
/**
* text effect set handler
* @param {object} event - add button event object
* @private
*/
_setTextEffectHandler(event) {
const button = event.target.closest('.tui-image-editor-button');
if (button) {
const [styleType] = button.className.match(/(bold|italic|underline)/);
const styleObj = {
bold: { fontWeight: 'bold' },
italic: { fontStyle: 'italic' },
underline: { textDecoration: 'underline' },
}[styleType];
this.effect[styleType] = !this.effect[styleType];
button.classList.toggle('active');
this.actions.changeTextStyle(styleObj);
}
}
/**
* text effect set handler
* @param {object} event - add button event object
* @private
*/
_setTextAlignHandler(event) {
const button = event.target.closest('.tui-image-editor-button');
if (button) {
const styleType = this.getButtonType(button, ['left', 'center', 'right']);
const styleTypeAlias = `tie-text-align-${styleType}`;
event.currentTarget.classList.remove(this.align);
if (this.align !== styleTypeAlias) {
event.currentTarget.classList.add(styleTypeAlias);
}
this.actions.changeTextStyle({ textAlign: styleType });
this.align = styleTypeAlias;
}
}
/**
* text align set handler
* @param {number} value - range value
* @param {boolean} isLast - Is last change
* @private
*/
_changeTextRnageHandler(value, isLast) {
this.actions.changeTextStyle(
{
fontSize: value,
},
!isLast
);
}
/**
* change color handler
* @param {string} color - change color string
* @private
*/
_changeColorHandler(color) {
color = color || 'transparent';
this.actions.changeTextStyle({
fill: color,
});
}
}
export default Text;