rect 支持渐变色,修复一些bug

This commit is contained in:
CPPAlien 2019-01-04 14:41:32 +08:00
parent a1460da565
commit 9b30e002c1
2 changed files with 88 additions and 114 deletions

View File

@ -6,61 +6,54 @@
!(function () { !(function () {
var api = { var api = {
toPoint: function(percent) { isGradient: function(bg) {
let str = percent.replace('%', ''); if (bg.startsWith('linear') || bg.startsWith('radial')) {
str /= 100; return true;
return str; }
return false;
}, },
analizeRadial: function(bg, width, height) { doGradient: function(bg, width, height, ctx) {
let count = 0; if (bg.startsWith('linear')) {
const coordinate = bg.match(/(?:(\d{1,3})[,])/g); linearEffect(width, height, bg, ctx);
const colors = bg.match(/((?:#(?:\w{6}|\w{3}))|(?:rgba[(](?:(?:\d{1,3})\W\s){3}\d[)]))/g); } else if (bg.startsWith('radial')) {
const status = bg.match(/\d{1,3}[%]/g); radialEffect(width, height, bg, ctx);
for (let i = 0; i < colors.length; i++) {
if (colors[i].startsWith('rgba')) {
count += 3;
} }
}
const length = coordinate.length - count;
switch (length) {
case 3: radialParams.coordinate = [coordinate[0].replace(',', ''), coordinate[1].replace(',', ''), coordinate[2].replace(',', '')]; break;
case 2: radialParams.coordinate = [coordinate[0].replace(',', ''), coordinate[1].replace(',', ''), Math.sqrt(width * width / 4 + height * height / 4)]; break;
case 1: radialParams.coordinate = [0, 0, coordinate[0].replace(',', '')]; break;
default: radialParams.coordinate = [0, 0, Math.sqrt(width * width / 4 + height * height / 4)]; break;
}
radialParams.colors = colors;
radialParams.status = status;
return radialParams.coordinate;
}, },
}
radialEffect: function(width, height, grd, ctx) { function analizeGrad(string) {
if (radialParams.status && radialParams.status[0] && radialParams.status.length === radialParams.colors.length) { const colorPercents = string.substring(0, string.length - 1).split("%,");
for (let i = 0; i < radialParams.colors.length; i++) { const colors = [];
grd.addColorStop(this.toPoint(radialParams.status[i]), radialParams.colors[i]); const percents = [];
for (let colorPercent of colorPercents) {
colors.push(colorPercent.substring(0, colorPercent.lastIndexOf(" ")).trim());
percents.push(colorPercent.substring(colorPercent.lastIndexOf(" "), colorPercent.length) / 100);
} }
} else { return {colors: colors, percents: percents};
for (let i = 0; i < radialParams.colors.length; i++) {
grd.addColorStop(i / (radialParams.colors.length - 1), radialParams.colors[i]);
} }
function radialEffect(width, height, bg, ctx) {
const colorPer = analizeGrad(bg.match(/radial-gradient\((.+)\)/)[1]);
const grd = ctx.createCircularGradient(0, 0, width < height ? height / 2 : width / 2);
for (let i = 0; i < colorPer.colors.length; i++) {
grd.addColorStop(colorPer.percents[i], colorPer.colors[i]);
} }
ctx.setFillStyle(grd); ctx.setFillStyle(grd);
ctx.fillRect(-(width / 2), -(height / 2), width, height); ctx.fillRect(-(width / 2), -(height / 2), width, height);
}, }
analizeLinear: function(bg, width, height) { function analizeLinear(bg, width, height) {
const direction = bg.match(/([-]?\d{1,3})deg/); const direction = bg.match(/([-]?\d{1,3})deg/);
const colors = bg.match(/((?:#(?:\w{6}|\w{3}))|(?:rgba[(](?:(?:\d{1,3})\W\s){3}\d[)]))/g);
const status = bg.match(/\d{1,3}[%]/g);
const dir = direction && direction[1] ? parseFloat(direction[1]) : 0; const dir = direction && direction[1] ? parseFloat(direction[1]) : 0;
let coordinate;
switch (dir) { switch (dir) {
case 0: console.log('case 0:'); linearParams.coordinate = [0, -height / 2, 0, height / 2]; break; case 0: console.log('case 0:'); coordinate = [0, -height / 2, 0, height / 2]; break;
case 90: console.log('case 90:'); linearParams.coordinate = [width / 2, 0, -width / 2, 0]; break; case 90: console.log('case 90:'); coordinate = [width / 2, 0, -width / 2, 0]; break;
case -90: console.log('case -90:'); linearParams.coordinate = [-width / 2, 0, width / 2, 0]; break; case -90: console.log('case -90:'); coordinate = [-width / 2, 0, width / 2, 0]; break;
case 180: console.log('case 180:'); linearParams.coordinate = [0, height / 2, 0, -height / 2]; break; case 180: console.log('case 180:'); coordinate = [0, height / 2, 0, -height / 2]; break;
case -180: console.log('case -180:'); linearParams.coordinate = [0, -height / 2, 0, height / 2]; break; case -180: console.log('case -180:'); coordinate = [0, -height / 2, 0, height / 2]; break;
default: default:
console.log('default:');
let x1 = 0; let x1 = 0;
let y1 = 0; let y1 = 0;
let x2 = 0; let x2 = 0;
@ -86,39 +79,22 @@
x2 = -x1; x2 = -x1;
y1 = -y2; y1 = -y2;
} }
linearParams.coordinate = [x1, y1, x2, y2]; coordinate = [x1, y1, x2, y2];
break; break;
} }
linearParams.colors = colors; return coordinate;
linearParams.status = status; }
return linearParams.coordinate;
},
linearEffect: function(width, height, grd, ctx) { function linearEffect(width, height, bg, ctx) {
if (linearParams.status && linearParams.status[0] && linearParams.status.length === linearParams.colors.length) { const param = analizeLinear(bg, width, height);
for (let i = 0; i < linearParams.colors.length; i++) { const grd = ctx.createLinearGradient(param[0], param[1], param[2], param[3]);
grd.addColorStop(this.toPoint(linearParams.status[i]), linearParams.colors[i]); const content = bg.match(/linear-gradient\((.+)\)/)[1];
} const colorPer = analizeGrad(content.substring(content.indexOf(',') + 1));
} else { for (let i = 0; i < colorPer.colors.length; i++) {
for (let i = 0; i < linearParams.colors.length; i++) { grd.addColorStop(colorPer.percents[i], colorPer.colors[i]);
grd.addColorStop(i / (linearParams.colors.length - 1), linearParams.colors[i]);
}
} }
ctx.setFillStyle(grd); ctx.setFillStyle(grd);
ctx.fillRect(-(width / 2), -(height / 2), width, height); ctx.fillRect(-(width / 2), -(height / 2), width, height);
},
}
const linearParams = {
coordinate: [],
colors: [],
status: [],
}
const radialParams = {
coordinate: [],
colors: [],
status: [],
} }
module.exports = { api } module.exports = { api }

View File

@ -39,14 +39,8 @@ export default class Painter {
// 背景填充颜色 // 背景填充颜色
this.ctx.setFillStyle(bg); this.ctx.setFillStyle(bg);
this.ctx.fillRect(-(width / 2), -(height / 2), width, height); this.ctx.fillRect(-(width / 2), -(height / 2), width, height);
} else if (bg.startsWith('linear')) { } else if (GD.api.isGradient(bg)) {
const param = GD.api.analizeLinear(bg, width, height); GD.api.doGradient(bg, width, height, this.ctx);
const grd = this.ctx.createLinearGradient(param[0], param[1], param[2], param[3]);
GD.api.linearEffect(width, height, grd, this.ctx);
} else if (bg.startsWith('radial')) {
const param = GD.api.analizeRadial(bg, width, height);
const grd = this.ctx.createCircularGradient(param[0], param[1], param[2]);
GD.api.radialEffect(width, height, grd, this.ctx);
} else { } else {
// 背景填充图片 // 背景填充图片
this.ctx.drawImage(bg, -(width / 2), -(height / 2), width, height); this.ctx.drawImage(bg, -(width / 2), -(height / 2), width, height);
@ -355,7 +349,11 @@ export default class Painter {
width, width,
height, height,
} = this._preProcess(view); } = this._preProcess(view);
if (GD.api.isGradient(view.css.color)) {
GD.api.doGradient(view.css.color, width, height, this.ctx);
} else {
this.ctx.setFillStyle(view.css.color); this.ctx.setFillStyle(view.css.color);
}
this.ctx.fillRect(-(width / 2), -(height / 2), width, height); this.ctx.fillRect(-(width / 2), -(height / 2), width, height);
this.ctx.restore(); this.ctx.restore();
this._doBorder(view, width, height); this._doBorder(view, width, height);