You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

494 lines
13 KiB
JavaScript

"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _color = require("@jiaminghi/color");
var _util = require("../plugin/util");
/**
* @description Class Style
* @param {Object} style Style configuration
* @return {Style} Instance of Style
*/
var Style = function Style(style) {
(0, _classCallCheck2["default"])(this, Style);
this.colorProcessor(style);
var defaultStyle = {
/**
* @description Rgba value of graph fill color
* @type {Array}
* @default fill = [0, 0, 0, 1]
*/
fill: [0, 0, 0, 1],
/**
* @description Rgba value of graph stroke color
* @type {Array}
* @default stroke = [0, 0, 0, 1]
*/
stroke: [0, 0, 0, 0],
/**
* @description Opacity of graph
* @type {Number}
* @default opacity = 1
*/
opacity: 1,
/**
* @description LineCap of Ctx
* @type {String}
* @default lineCap = null
* @example lineCap = 'butt'|'round'|'square'
*/
lineCap: null,
/**
* @description Linejoin of Ctx
* @type {String}
* @default lineJoin = null
* @example lineJoin = 'round'|'bevel'|'miter'
*/
lineJoin: null,
/**
* @description LineDash of Ctx
* @type {Array}
* @default lineDash = null
* @example lineDash = [10, 10]
*/
lineDash: null,
/**
* @description LineDashOffset of Ctx
* @type {Number}
* @default lineDashOffset = null
* @example lineDashOffset = 10
*/
lineDashOffset: null,
/**
* @description ShadowBlur of Ctx
* @type {Number}
* @default shadowBlur = 0
*/
shadowBlur: 0,
/**
* @description Rgba value of graph shadow color
* @type {Array}
* @default shadowColor = [0, 0, 0, 0]
*/
shadowColor: [0, 0, 0, 0],
/**
* @description ShadowOffsetX of Ctx
* @type {Number}
* @default shadowOffsetX = 0
*/
shadowOffsetX: 0,
/**
* @description ShadowOffsetY of Ctx
* @type {Number}
* @default shadowOffsetY = 0
*/
shadowOffsetY: 0,
/**
* @description LineWidth of Ctx
* @type {Number}
* @default lineWidth = 0
*/
lineWidth: 0,
/**
* @description Center point of the graph
* @type {Array}
* @default graphCenter = null
* @example graphCenter = [10, 10]
*/
graphCenter: null,
/**
* @description Graph scale
* @type {Array}
* @default scale = null
* @example scale = [1.5, 1.5]
*/
scale: null,
/**
* @description Graph rotation degree
* @type {Number}
* @default rotate = null
* @example rotate = 10
*/
rotate: null,
/**
* @description Graph translate distance
* @type {Array}
* @default translate = null
* @example translate = [10, 10]
*/
translate: null,
/**
* @description Cursor status when hover
* @type {String}
* @default hoverCursor = 'pointer'
* @example hoverCursor = 'default'|'pointer'|'auto'|'crosshair'|'move'|'wait'|...
*/
hoverCursor: 'pointer',
/**
* @description Font style of Ctx
* @type {String}
* @default fontStyle = 'normal'
* @example fontStyle = 'normal'|'italic'|'oblique'
*/
fontStyle: 'normal',
/**
* @description Font varient of Ctx
* @type {String}
* @default fontVarient = 'normal'
* @example fontVarient = 'normal'|'small-caps'
*/
fontVarient: 'normal',
/**
* @description Font weight of Ctx
* @type {String|Number}
* @default fontWeight = 'normal'
* @example fontWeight = 'normal'|'bold'|'bolder'|'lighter'|Number
*/
fontWeight: 'normal',
/**
* @description Font size of Ctx
* @type {Number}
* @default fontSize = 10
*/
fontSize: 10,
/**
* @description Font family of Ctx
* @type {String}
* @default fontFamily = 'Arial'
*/
fontFamily: 'Arial',
/**
* @description TextAlign of Ctx
* @type {String}
* @default textAlign = 'center'
* @example textAlign = 'start'|'end'|'left'|'right'|'center'
*/
textAlign: 'center',
/**
* @description TextBaseline of Ctx
* @type {String}
* @default textBaseline = 'middle'
* @example textBaseline = 'top'|'bottom'|'middle'|'alphabetic'|'hanging'
*/
textBaseline: 'middle',
/**
* @description The color used to create the gradient
* @type {Array}
* @default gradientColor = null
* @example gradientColor = ['#000', '#111', '#222']
*/
gradientColor: null,
/**
* @description Gradient type
* @type {String}
* @default gradientType = 'linear'
* @example gradientType = 'linear' | 'radial'
*/
gradientType: 'linear',
/**
* @description Gradient params
* @type {Array}
* @default gradientParams = null
* @example gradientParams = [x0, y0, x1, y1] (Linear Gradient)
* @example gradientParams = [x0, y0, r0, x1, y1, r1] (Radial Gradient)
*/
gradientParams: null,
/**
* @description When to use gradients
* @type {String}
* @default gradientWith = 'stroke'
* @example gradientWith = 'stroke' | 'fill'
*/
gradientWith: 'stroke',
/**
* @description Gradient color stops
* @type {String}
* @default gradientStops = 'auto'
* @example gradientStops = 'auto' | [0, .2, .3, 1]
*/
gradientStops: 'auto',
/**
* @description Extended color that supports animation transition
* @type {Array|Object}
* @default colors = null
* @example colors = ['#000', '#111', '#222', 'red' ]
* @example colors = { a: '#000', b: '#111' }
*/
colors: null
};
Object.assign(this, defaultStyle, style);
};
/**
* @description Set colors to rgba value
* @param {Object} style style config
* @param {Boolean} reverse Whether to perform reverse operation
* @return {Undefined} Void
*/
exports["default"] = Style;
Style.prototype.colorProcessor = function (style) {
var reverse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var processor = reverse ? _color.getColorFromRgbValue : _color.getRgbaValue;
var colorProcessorKeys = ['fill', 'stroke', 'shadowColor'];
var allKeys = Object.keys(style);
var colorKeys = allKeys.filter(function (key) {
return colorProcessorKeys.find(function (k) {
return k === key;
});
});
colorKeys.forEach(function (key) {
return style[key] = processor(style[key]);
});
var gradientColor = style.gradientColor,
colors = style.colors;
if (gradientColor) style.gradientColor = gradientColor.map(function (c) {
return processor(c);
});
if (colors) {
var colorsKeys = Object.keys(colors);
colorsKeys.forEach(function (key) {
return colors[key] = processor(colors[key]);
});
}
};
/**
* @description Init graph style
* @param {Object} ctx Context of canvas
* @return {Undefined} Void
*/
Style.prototype.initStyle = function (ctx) {
initTransform(ctx, this);
initGraphStyle(ctx, this);
initGradient(ctx, this);
};
/**
* @description Init canvas transform
* @param {Object} ctx Context of canvas
* @param {Style} style Instance of Style
* @return {Undefined} Void
*/
function initTransform(ctx, style) {
ctx.save();
var graphCenter = style.graphCenter,
rotate = style.rotate,
scale = style.scale,
translate = style.translate;
if (!(graphCenter instanceof Array)) return;
ctx.translate.apply(ctx, (0, _toConsumableArray2["default"])(graphCenter));
if (rotate) ctx.rotate(rotate * Math.PI / 180);
if (scale instanceof Array) ctx.scale.apply(ctx, (0, _toConsumableArray2["default"])(scale));
if (translate) ctx.translate.apply(ctx, (0, _toConsumableArray2["default"])(translate));
ctx.translate(-graphCenter[0], -graphCenter[1]);
}
var autoSetStyleKeys = ['lineCap', 'lineJoin', 'lineDashOffset', 'shadowOffsetX', 'shadowOffsetY', 'lineWidth', 'textAlign', 'textBaseline'];
/**
* @description Set the style of canvas ctx
* @param {Object} ctx Context of canvas
* @param {Style} style Instance of Style
* @return {Undefined} Void
*/
function initGraphStyle(ctx, style) {
var fill = style.fill,
stroke = style.stroke,
shadowColor = style.shadowColor,
opacity = style.opacity;
autoSetStyleKeys.forEach(function (key) {
if (key || typeof key === 'number') ctx[key] = style[key];
});
fill = (0, _toConsumableArray2["default"])(fill);
stroke = (0, _toConsumableArray2["default"])(stroke);
shadowColor = (0, _toConsumableArray2["default"])(shadowColor);
fill[3] *= opacity;
stroke[3] *= opacity;
shadowColor[3] *= opacity;
ctx.fillStyle = (0, _color.getColorFromRgbValue)(fill);
ctx.strokeStyle = (0, _color.getColorFromRgbValue)(stroke);
ctx.shadowColor = (0, _color.getColorFromRgbValue)(shadowColor);
var lineDash = style.lineDash,
shadowBlur = style.shadowBlur;
if (lineDash) {
lineDash = lineDash.map(function (v) {
return v >= 0 ? v : 0;
});
ctx.setLineDash(lineDash);
}
if (typeof shadowBlur === 'number') ctx.shadowBlur = shadowBlur > 0 ? shadowBlur : 0.001;
var fontStyle = style.fontStyle,
fontVarient = style.fontVarient,
fontWeight = style.fontWeight,
fontSize = style.fontSize,
fontFamily = style.fontFamily;
ctx.font = fontStyle + ' ' + fontVarient + ' ' + fontWeight + ' ' + fontSize + 'px' + ' ' + fontFamily;
}
/**
* @description Set the gradient color of canvas ctx
* @param {Object} ctx Context of canvas
* @param {Style} style Instance of Style
* @return {Undefined} Void
*/
function initGradient(ctx, style) {
if (!gradientValidator(style)) return;
var gradientColor = style.gradientColor,
gradientParams = style.gradientParams,
gradientType = style.gradientType,
gradientWith = style.gradientWith,
gradientStops = style.gradientStops,
opacity = style.opacity;
gradientColor = gradientColor.map(function (color) {
var colorOpacity = color[3] * opacity;
var clonedColor = (0, _toConsumableArray2["default"])(color);
clonedColor[3] = colorOpacity;
return clonedColor;
});
gradientColor = gradientColor.map(function (c) {
return (0, _color.getColorFromRgbValue)(c);
});
if (gradientStops === 'auto') gradientStops = getAutoColorStops(gradientColor);
var gradient = ctx["create".concat(gradientType.slice(0, 1).toUpperCase() + gradientType.slice(1), "Gradient")].apply(ctx, (0, _toConsumableArray2["default"])(gradientParams));
gradientStops.forEach(function (stop, i) {
return gradient.addColorStop(stop, gradientColor[i]);
});
ctx["".concat(gradientWith, "Style")] = gradient;
}
/**
* @description Check if the gradient configuration is legal
* @param {Style} style Instance of Style
* @return {Boolean} Check Result
*/
function gradientValidator(style) {
var gradientColor = style.gradientColor,
gradientParams = style.gradientParams,
gradientType = style.gradientType,
gradientWith = style.gradientWith,
gradientStops = style.gradientStops;
if (!gradientColor || !gradientParams) return false;
if (gradientColor.length === 1) {
console.warn('The gradient needs to provide at least two colors');
return false;
}
if (gradientType !== 'linear' && gradientType !== 'radial') {
console.warn('GradientType only supports linear or radial, current value is ' + gradientType);
return false;
}
var gradientParamsLength = gradientParams.length;
if (gradientType === 'linear' && gradientParamsLength !== 4 || gradientType === 'radial' && gradientParamsLength !== 6) {
console.warn('The expected length of gradientParams is ' + (gradientType === 'linear' ? '4' : '6'));
return false;
}
if (gradientWith !== 'fill' && gradientWith !== 'stroke') {
console.warn('GradientWith only supports fill or stroke, current value is ' + gradientWith);
return false;
}
if (gradientStops !== 'auto' && !(gradientStops instanceof Array)) {
console.warn("gradientStops only supports 'auto' or Number Array ([0, .5, 1]), current value is " + gradientStops);
return false;
}
return true;
}
/**
* @description Get a uniform gradient color stop
* @param {Array} color Gradient color
* @return {Array} Gradient color stop
*/
function getAutoColorStops(color) {
var stopGap = 1 / (color.length - 1);
return color.map(function (foo, i) {
return stopGap * i;
});
}
/**
* @description Restore canvas ctx transform
* @param {Object} ctx Context of canvas
* @return {Undefined} Void
*/
Style.prototype.restoreTransform = function (ctx) {
ctx.restore();
};
/**
* @description Update style data
* @param {Object} change Changed data
* @return {Undefined} Void
*/
Style.prototype.update = function (change) {
this.colorProcessor(change);
Object.assign(this, change);
};
/**
* @description Get the current style configuration
* @return {Object} Style configuration
*/
Style.prototype.getStyle = function () {
var clonedStyle = (0, _util.deepClone)(this, true);
this.colorProcessor(clonedStyle, true);
return clonedStyle;
};