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
494 lines
13 KiB
JavaScript
4 months ago
|
"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;
|
||
|
};
|