216 lines
5.1 KiB
Java
216 lines
5.1 KiB
Java
![]() |
var Util = require('../../util/index');
|
|||
|
|
|||
|
var regexTags = /[MLHVQTCSAZ]([^MLHVQTCSAZ]*)/ig;
|
|||
|
var regexDot = /[^\s\,]+/ig;
|
|||
|
var regexLG = /^l\s*\(\s*([\d.]+)\s*\)\s*(.*)/i;
|
|||
|
var regexRG = /^r\s*\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)\s*(.*)/i;
|
|||
|
var regexPR = /^p\s*\(\s*([axyn])\s*\)\s*(.*)/i;
|
|||
|
var regexColorStop = /[\d.]+:(#[^\s]+|[^\)]+\))/ig; // const numColorCache = {};
|
|||
|
|
|||
|
function addStop(steps, gradient) {
|
|||
|
var arr = steps.match(regexColorStop);
|
|||
|
Util.each(arr, function (item) {
|
|||
|
item = item.split(':');
|
|||
|
gradient.addColorStop(item[0], item[1]);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
function parseLineGradient(color, self, context) {
|
|||
|
var arr = regexLG.exec(color);
|
|||
|
var angle = Util.mod(Util.toRadian(parseFloat(arr[1])), Math.PI * 2);
|
|||
|
var steps = arr[2];
|
|||
|
var box = self.getBBox();
|
|||
|
var start;
|
|||
|
var end;
|
|||
|
|
|||
|
if (angle >= 0 && angle < 0.5 * Math.PI) {
|
|||
|
start = {
|
|||
|
x: box.minX,
|
|||
|
y: box.minY
|
|||
|
};
|
|||
|
end = {
|
|||
|
x: box.maxX,
|
|||
|
y: box.maxY
|
|||
|
};
|
|||
|
} else if (0.5 * Math.PI <= angle && angle < Math.PI) {
|
|||
|
start = {
|
|||
|
x: box.maxX,
|
|||
|
y: box.minY
|
|||
|
};
|
|||
|
end = {
|
|||
|
x: box.minX,
|
|||
|
y: box.maxY
|
|||
|
};
|
|||
|
} else if (Math.PI <= angle && angle < 1.5 * Math.PI) {
|
|||
|
start = {
|
|||
|
x: box.maxX,
|
|||
|
y: box.maxY
|
|||
|
};
|
|||
|
end = {
|
|||
|
x: box.minX,
|
|||
|
y: box.minY
|
|||
|
};
|
|||
|
} else {
|
|||
|
start = {
|
|||
|
x: box.minX,
|
|||
|
y: box.maxY
|
|||
|
};
|
|||
|
end = {
|
|||
|
x: box.maxX,
|
|||
|
y: box.minY
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
var tanTheta = Math.tan(angle);
|
|||
|
var tanTheta2 = tanTheta * tanTheta;
|
|||
|
var x = (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.x;
|
|||
|
var y = tanTheta * (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.y;
|
|||
|
var gradient = context.createLinearGradient(start.x, start.y, x, y);
|
|||
|
addStop(steps, gradient);
|
|||
|
return gradient;
|
|||
|
}
|
|||
|
|
|||
|
function parseRadialGradient(color, self, context) {
|
|||
|
var arr = regexRG.exec(color);
|
|||
|
var fx = parseFloat(arr[1]);
|
|||
|
var fy = parseFloat(arr[2]);
|
|||
|
var fr = parseFloat(arr[3]);
|
|||
|
var steps = arr[4]; // 环半径为0时,默认无渐变,取渐变序列的最后一个颜色
|
|||
|
|
|||
|
if (fr === 0) {
|
|||
|
var colors = steps.match(regexColorStop);
|
|||
|
return colors[colors.length - 1].split(':')[1];
|
|||
|
}
|
|||
|
|
|||
|
var box = self.getBBox();
|
|||
|
var width = box.maxX - box.minX;
|
|||
|
var height = box.maxY - box.minY;
|
|||
|
var r = Math.sqrt(width * width + height * height) / 2;
|
|||
|
var gradient = context.createRadialGradient(box.minX + width * fx, box.minY + height * fy, fr * r, box.minX + width / 2, box.minY + height / 2, r);
|
|||
|
addStop(steps, gradient);
|
|||
|
return gradient;
|
|||
|
}
|
|||
|
|
|||
|
function parsePattern(color, self, context) {
|
|||
|
if (self.get('patternSource') && self.get('patternSource') === color) {
|
|||
|
return self.get('pattern');
|
|||
|
}
|
|||
|
|
|||
|
var pattern;
|
|||
|
var img;
|
|||
|
var arr = regexPR.exec(color);
|
|||
|
var repeat = arr[1];
|
|||
|
var source = arr[2]; // Function to be called when pattern loads
|
|||
|
|
|||
|
function onload() {
|
|||
|
// Create pattern
|
|||
|
pattern = context.createPattern(img, repeat);
|
|||
|
self.setSilent('pattern', pattern); // be a cache
|
|||
|
|
|||
|
self.setSilent('patternSource', color);
|
|||
|
}
|
|||
|
|
|||
|
switch (repeat) {
|
|||
|
case 'a':
|
|||
|
repeat = 'repeat';
|
|||
|
break;
|
|||
|
|
|||
|
case 'x':
|
|||
|
repeat = 'repeat-x';
|
|||
|
break;
|
|||
|
|
|||
|
case 'y':
|
|||
|
repeat = 'repeat-y';
|
|||
|
break;
|
|||
|
|
|||
|
case 'n':
|
|||
|
repeat = 'no-repeat';
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
repeat = 'no-repeat';
|
|||
|
}
|
|||
|
|
|||
|
img = new Image(); // If source URL is not a data URL
|
|||
|
|
|||
|
if (!source.match(/^data:/i)) {
|
|||
|
// Set crossOrigin for this image
|
|||
|
img.crossOrigin = 'Anonymous';
|
|||
|
}
|
|||
|
|
|||
|
img.src = source;
|
|||
|
|
|||
|
if (img.complete) {
|
|||
|
onload();
|
|||
|
} else {
|
|||
|
img.onload = onload; // Fix onload() bug in IE9
|
|||
|
|
|||
|
img.src = img.src;
|
|||
|
}
|
|||
|
|
|||
|
return pattern;
|
|||
|
}
|
|||
|
|
|||
|
module.exports = {
|
|||
|
parsePath: function parsePath(path) {
|
|||
|
path = path || [];
|
|||
|
|
|||
|
if (Util.isArray(path)) {
|
|||
|
return path;
|
|||
|
}
|
|||
|
|
|||
|
if (Util.isString(path)) {
|
|||
|
path = path.match(regexTags);
|
|||
|
Util.each(path, function (item, index) {
|
|||
|
item = item.match(regexDot);
|
|||
|
|
|||
|
if (item[0].length > 1) {
|
|||
|
var tag = item[0].charAt(0);
|
|||
|
item.splice(1, 0, item[0].substr(1));
|
|||
|
item[0] = tag;
|
|||
|
}
|
|||
|
|
|||
|
Util.each(item, function (sub, i) {
|
|||
|
if (!isNaN(sub)) {
|
|||
|
item[i] = +sub;
|
|||
|
}
|
|||
|
});
|
|||
|
path[index] = item;
|
|||
|
});
|
|||
|
return path;
|
|||
|
}
|
|||
|
},
|
|||
|
parseStyle: function parseStyle(color, self, context) {
|
|||
|
if (Util.isString(color)) {
|
|||
|
if (color[1] === '(' || color[2] === '(') {
|
|||
|
if (color[0] === 'l') {
|
|||
|
// regexLG.test(color)
|
|||
|
return parseLineGradient(color, self, context);
|
|||
|
} else if (color[0] === 'r') {
|
|||
|
// regexRG.test(color)
|
|||
|
return parseRadialGradient(color, self, context);
|
|||
|
} else if (color[0] === 'p') {
|
|||
|
// regexPR.test(color)
|
|||
|
return parsePattern(color, self, context);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return color;
|
|||
|
}
|
|||
|
}
|
|||
|
/* ,
|
|||
|
numberToColor(num) {
|
|||
|
// 增加缓存
|
|||
|
let color = numColorCache[num];
|
|||
|
if (!color) {
|
|||
|
let str = num.toString(16);
|
|||
|
for (let i = str.length; i < 6; i++) {
|
|||
|
str = '0' + str;
|
|||
|
}
|
|||
|
color = '#' + str;
|
|||
|
numColorCache[num] = color;
|
|||
|
}
|
|||
|
return color;
|
|||
|
}*/
|
|||
|
|
|||
|
};
|