Skip to content

Commit

Permalink
Merge pull request #1355 from VisActor/feat/rect-corner-array
Browse files Browse the repository at this point in the history
feat: support rect corner array with array stroke
  • Loading branch information
neuqzxy authored Aug 8, 2024
2 parents 9f03adf + c43c207 commit 7e7c35b
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vrender-core",
"comment": "feat: support rect corner array with array stroke",
"type": "none"
}
],
"packageName": "@visactor/vrender-core"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vrender",
"comment": "",
"type": "none"
}
],
"packageName": "@visactor/vrender"
}
23 changes: 18 additions & 5 deletions packages/vrender-core/src/common/shape/rect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import type { IContext2d, ICustomPath2D } from '../../interface';

const halfPi = pi / 2;

type IEdgeCb = (x1: number, y1: number, x2: number, y2: number) => void;
export function createRectPath(
path: ICustomPath2D | IContext2d,
x: number,
y: number,
width: number,
height: number,
rectCornerRadius: number | number[]
rectCornerRadius: number | number[],
edgeCb?: IEdgeCb[]
) {
if (width < 0) {
x += width;
Expand Down Expand Up @@ -98,7 +100,11 @@ export function createRectPath(
const leftBottomPoint2: vec2 = [leftBottom[0], leftBottom[1] - _cornerRadius[3]];

path.moveTo(leftTopPoint1[0], leftTopPoint1[1]);
path.lineTo(rightTopPoint1[0], rightTopPoint1[1]);

// 上边
edgeCb && edgeCb[0]
? edgeCb[0](leftTopPoint1[0], leftTopPoint1[1], rightTopPoint1[0], rightTopPoint1[1])
: path.lineTo(rightTopPoint1[0], rightTopPoint1[1]);
if (!arrayEqual(rightTopPoint1, rightTopPoint2)) {
const centerX = rightTopPoint1[0];
const centerY = rightTopPoint1[1] + _cornerRadius[1];
Expand All @@ -115,7 +121,10 @@ export function createRectPath(
// path.arcTo(rightTop[0], rightTop[1], rightTopPoint2[0], rightTopPoint2[1], _cornerRadius[1]);
}

path.lineTo(rightBottomPoint2[0], rightBottomPoint2[1]);
// 右边
edgeCb && edgeCb[1]
? edgeCb[1](rightTopPoint1[0], rightTopPoint1[1], rightBottomPoint2[0], rightBottomPoint2[1])
: path.lineTo(rightBottomPoint2[0], rightBottomPoint2[1]);
if (!arrayEqual(rightBottomPoint1, rightBottomPoint2)) {
const centerX = rightBottomPoint2[0] - _cornerRadius[2];
const centerY = rightBottomPoint2[1];
Expand All @@ -132,7 +141,9 @@ export function createRectPath(
// path.arcTo(rightBottom[0], rightBottom[1], rightBottomPoint1[0], rightBottomPoint1[1], _cornerRadius[2]);
}

path.lineTo(leftBottomPoint1[0], leftBottomPoint1[1]);
edgeCb && edgeCb[2]
? edgeCb[2](rightBottomPoint2[0], rightBottomPoint2[1], leftBottomPoint1[0], leftBottomPoint1[1])
: path.lineTo(leftBottomPoint1[0], leftBottomPoint1[1]);
if (!arrayEqual(leftBottomPoint1, leftBottomPoint2)) {
const centerX = leftBottomPoint1[0];
const centerY = leftBottomPoint1[1] - _cornerRadius[3];
Expand All @@ -149,7 +160,9 @@ export function createRectPath(
// path.arcTo(leftBottom[0], leftBottom[1], leftBottomPoint2[0], leftBottomPoint2[1], _cornerRadius[3]);
}

path.lineTo(leftTopPoint2[0], leftTopPoint2[1]);
edgeCb && edgeCb[3]
? edgeCb[3](leftBottomPoint1[0], leftBottomPoint1[1], leftTopPoint2[0], leftTopPoint2[1])
: path.lineTo(leftTopPoint2[0], leftTopPoint2[1]);
if (!arrayEqual(leftTopPoint1, leftTopPoint2)) {
const centerX = leftTopPoint1[0];
const centerY = leftTopPoint1[1] + _cornerRadius[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ export class SplitRectAfterRenderContribution implements IRectRenderContribution
y1,
x: originX = groupAttribute.x,
y: originY = groupAttribute.y,
stroke = groupAttribute.stroke
stroke = groupAttribute.stroke,
cornerRadius = groupAttribute.cornerRadius
} = rect.attribute as any;

let { width, height } = rect.attribute;
Expand All @@ -227,6 +228,35 @@ export class SplitRectAfterRenderContribution implements IRectRenderContribution
}

context.setStrokeStyle(rect, rect.attribute, x, y, groupAttribute);

// 带不同stroke边框
if (!(cornerRadius === 0 || (isArray(cornerRadius) && (<number[]>cornerRadius).every(num => num === 0)))) {
let lastStrokeI = 0;
let lastStroke: any;
createRectPath(
context,
x,
y,
width,
height,
cornerRadius,
new Array(4).fill(0).map((_, i) => (x1: number, y1: number, x2: number, y2: number) => {
if (stroke[i]) {
if (!(lastStrokeI === i - 1 && stroke[i] === lastStroke)) {
context.setStrokeStyle(rect, { ...rect.attribute, stroke: stroke[i] }, x, y, groupAttribute);
context.beginPath();
context.moveTo(x1, y1);
lastStroke = stroke[i];
}
lastStrokeI = i;
context.lineTo(x2, y2);
context.stroke();
}
})
);
return;
}

// 单独处理每条边界,目前不考虑圆角
context.beginPath();
context.moveTo(x, y);
Expand Down
4 changes: 3 additions & 1 deletion packages/vrender/__tests__/browser/src/pages/rect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ export const page = () => {
scaleY: 2,
width: 200,
height: 200,
cornerRadius: [0, 10, 10, 0],
stroke: ['red', 'red', 'red', false],
// scaleCenter: ['50%', '50%'],
_debug_bounds: true,
// _debug_bounds: true,
fill: 'conic-gradient(from 90deg, rgba(5,0,255,1) 16%, rgba(0,255,10,1) 41%, rgba(9,9,121,1) 53%, rgba(0,212,255,1) 100%)',
// cornerRadius: [5, 10, 15, 20],
lineWidth: 5
Expand Down

0 comments on commit 7e7c35b

Please sign in to comment.