jab-image-editor
Version:
JAB TOAST UI Component: ImageEditor
346 lines (299 loc) • 8.64 kB
JavaScript
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhn.com>
* @fileoverview Util
*/
import {forEach, sendHostname, extend, isString, pick, inArray} from 'tui-code-snippet';
import Promise from 'core-js-pure/features/promise';
import {SHAPE_FILL_TYPE, SHAPE_TYPE} from './consts';
const FLOATING_POINT_DIGIT = 2;
const CSS_PREFIX = 'tui-image-editor-';
const {min, max} = Math;
let hostnameSent = false;
/**
* Export Promise Class (for simplified module path)
* @returns {Promise} promise class
*/
export {Promise};
/**
* Clamp value
* @param {number} value - Value
* @param {number} minValue - Minimum value
* @param {number} maxValue - Maximum value
* @returns {number} clamped value
*/
export function clamp(value, minValue, maxValue) {
let temp;
if (minValue > maxValue) {
temp = minValue;
minValue = maxValue;
maxValue = temp;
}
return max(minValue, min(value, maxValue));
}
/**
* Make key-value object from arguments
* @returns {object.<string, string>}
*/
export function keyMirror(...args) {
const obj = {};
forEach(args, key => {
obj[key] = key;
});
return obj;
}
/**
* Make CSSText
* @param {Object} styleObj - Style info object
* @returns {string} Connected string of style
*/
export function makeStyleText(styleObj) {
let styleStr = '';
forEach(styleObj, (value, prop) => {
styleStr += `${prop}: ${value};`;
});
return styleStr;
}
/**
* Get object's properties
* @param {Object} obj - object
* @param {Array} keys - keys
* @returns {Object} properties object
*/
export function getProperties(obj, keys) {
const props = {};
const {length} = keys;
let i = 0;
let key;
for (i = 0; i < length; i += 1) {
key = keys[i];
props[key] = obj[key];
}
return props;
}
/**
* ParseInt simpliment
* @param {number} value - Value
* @returns {number}
*/
export function toInteger(value) {
return parseInt(value, 10);
}
/**
* String to camelcase string
* @param {string} targetString - change target
* @returns {string}
* @private
*/
export function toCamelCase(targetString) {
return targetString.replace(/-([a-z])/g, ($0, $1) => $1.toUpperCase());
}
/**
* Check browser file api support
* @returns {boolean}
* @private
*/
export function isSupportFileApi() {
return !!(window.File && window.FileList && window.FileReader);
}
/**
* hex to rgb
* @param {string} color - hex color
* @param {string} alpha - color alpha value
* @returns {string} rgb expression
*/
export function getRgb(color, alpha) {
if (color.length === 4) {
color = `${color}${color.slice(1, 4)}`;
}
const r = parseInt(color.slice(1, 3), 16);
const g = parseInt(color.slice(3, 5), 16);
const b = parseInt(color.slice(5, 7), 16);
const a = alpha || 1;
return `rgba(${r}, ${g}, ${b}, ${a})`;
}
/**
* send hostname
*/
export function sendHostName() {
if (hostnameSent) {
return;
}
hostnameSent = true;
sendHostname('image-editor', 'UA-129999381-1');
}
/**
* Apply css resource
* @param {string} styleBuffer - serialized css text
* @param {string} tagId - style tag id
*/
export function styleLoad(styleBuffer, tagId) {
const [head] = document.getElementsByTagName('head');
const linkElement = document.createElement('link');
const styleData = encodeURIComponent(styleBuffer);
if (tagId) {
linkElement.id = tagId;
// linkElement.id = 'tui-image-editor-theme-style';
}
linkElement.setAttribute('rel', 'stylesheet');
linkElement.setAttribute('type', 'text/css');
linkElement.setAttribute('href', `data:text/css;charset=UTF-8,${styleData}`);
head.appendChild(linkElement);
}
/**
* Get selector
* @param {HTMLElement} targetElement - target element
* @returns {Function} selector
*/
export function getSelector(targetElement) {
return str => targetElement.querySelector(str);
}
/**
* Change base64 to blob
* @param {String} data - base64 string data
* @returns {Blob} Blob Data
*/
export function base64ToBlob(data) {
const rImageType = /data:(image\/.+);base64,/;
let mimeString = '';
let raw, uInt8Array, i;
raw = data.replace(rImageType, (header, imageType) => {
mimeString = imageType;
return '';
});
raw = atob(raw);
const rawLength = raw.length;
uInt8Array = new Uint8Array(rawLength); // eslint-disable-line
for (i = 0; i < rawLength; i += 1) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {type: mimeString});
}
/**
* Fix floating point diff.
* @param {number} value - original value
* @returns {number} fixed value
*/
export function fixFloatingPoint(value) {
return Number(value.toFixed(FLOATING_POINT_DIGIT));
}
/**
* Assignment for destroying objects.
* @param {Object} targetObject - object to be removed.
*/
export function assignmentForDestroy(targetObject) {
forEach(targetObject, (value, key) => {
targetObject[key] = null;
});
}
/**
* Make class name for ui
* @param {String} str - main string of className
* @param {String} prefix - prefix string of className
* @returns {String} class name
*/
export function cls(str = '', prefix = '') {
if (str.charAt(0) === '.') {
return `.${CSS_PREFIX}${prefix}${str.slice(1)}`;
}
return `${CSS_PREFIX}${prefix}${str}`;
}
/**
* Change object origin
* @param {fabric.Object} fObject - fabric object
* @param {Object} origin - origin of fabric object
* @param {string} originX - horizontal basis.
* @param {string} originY - vertical basis.
*/
export function changeOrigin(fObject, origin) {
const {originX, originY} = origin;
const {x: left, y: top} = fObject.getPointByOrigin(originX, originY);
fObject.set({
left,
top,
originX,
originY
});
fObject.setCoords();
}
/**
* Object key value flip
* @param {Object} targetObject - The data object of the key value.
* @returns {Object}
*/
export function flipObject(targetObject) {
const result = {};
Object.keys(targetObject).forEach(key => {
result[targetObject[key]] = key;
});
return result;
}
/**
* Set custom properties
* @param {Object} targetObject - target object
* @param {Object} props - custom props object
*/
export function setCustomProperty(targetObject, props) {
targetObject.customProps = targetObject.customProps || {};
extend(targetObject.customProps, props);
}
/**
* Get custom property
* @param {fabric.Object} fObject - fabric object
* @param {Array|string} propNames - prop name array
* @returns {object | number | string}
*/
export function getCustomProperty(fObject, propNames) {
const resultObject = {};
if (isString(propNames)) {
propNames = [propNames];
}
forEach(propNames, propName => {
resultObject[propName] = fObject.customProps[propName];
});
return resultObject;
}
/**
* Capitalize string
* @param {string} targetString - target string
* @returns {string}
*/
export function capitalizeString(targetString) {
return targetString.charAt(0).toUpperCase() + targetString.slice(1);
}
/**
* Array includes check
* @param {Array} targetArray - target array
* @param {string|number} compareValue - compare value
* @returns {boolean}
*/
export function includes(targetArray, compareValue) {
return targetArray.indexOf(compareValue) >= 0;
}
/**
* Get fill type
* @param {Object | string} fillOption - shape fill option
* @returns {string} 'color' or 'filter'
*/
export function getFillTypeFromOption(fillOption = {}) {
return pick(fillOption, 'type') || SHAPE_FILL_TYPE.COLOR;
}
/**
* Get fill type of shape type object
* @param {fabric.Object} shapeObj - fabric object
* @returns {string} 'transparent' or 'color' or 'filter'
*/
export function getFillTypeFromObject(shapeObj) {
const {fill = {}} = shapeObj;
if (fill.source) {
return SHAPE_FILL_TYPE.FILTER;
}
return SHAPE_FILL_TYPE.COLOR;
}
/**
* Check if the object is a shape object.
* @param {fabric.Object} obj - fabric object
* @returns {boolean}
*/
export function isShape(obj) {
return inArray(obj.get('type'), SHAPE_TYPE) >= 0;
}