Skip to content

Commit

Permalink
feat: add config and dash effect
Browse files Browse the repository at this point in the history
  • Loading branch information
chenshenhai committed Nov 5, 2023
1 parent 127d600 commit 14b8436
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 12 deletions.
33 changes: 24 additions & 9 deletions packages/renderer/src/draw/base.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { ViewContext2D, Element, ElementType, ElementSize, ViewScaleInfo, ViewSizeInfo, TransformAction } from '@idraw/types';
import { istype, isColorStr, generateSVGPath, rotateElement, is } from '@idraw/util';
import { istype, isColorStr, generateSVGPath, rotateElement, is, getDefaultElementDetailConfig } from '@idraw/util';
import { createColorStyle } from './color';

const defaultElemConfig = getDefaultElementDetailConfig();

export function drawBox(
ctx: ViewContext2D,
viewElem: Element<ElementType>,
Expand Down Expand Up @@ -66,7 +68,6 @@ function drawClipPath(
ctx.scale(totalScale * scaleW, totalScale * scaleH);
const pathStr = generateSVGPath(clipPath.commands || []);
const path2d = new Path2D(pathStr);
// ctx.fillStyle = clipPath.fill || '#FFFFFF';
ctx.clip(path2d);
ctx.translate(0 - (internalX as number), 0 - (internalY as number));
ctx.setTransform(1, 0, 0, 1, 0, 0);
Expand All @@ -89,7 +90,7 @@ function drawBoxBackground(
const { pattern, viewScaleInfo } = opts;
const { scale } = viewScaleInfo;
let transform: TransformAction[] = [];
let { borderRadius, boxSizing, borderWidth } = viewElem.detail;
let { borderRadius, boxSizing = defaultElemConfig.boxSizing, borderWidth } = viewElem.detail;
if (typeof borderWidth !== 'number') {
// TODO: If borderWidth is an array, borderRadius will not take effect and will become 0.
borderRadius = 0;
Expand Down Expand Up @@ -189,6 +190,9 @@ function drawBoxBackground(
}

function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>, opts: { viewScaleInfo: ViewScaleInfo; viewSizeInfo: ViewSizeInfo }): void {
if (viewElem.detail.borderWidth === 0) {
return;
}
if (!isColorStr(viewElem.detail.borderColor)) {
return;
}
Expand All @@ -199,11 +203,11 @@ function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>, opts:
}
const { viewScaleInfo } = opts;
const { scale } = viewScaleInfo;
let borderColor = '#000000';
let borderColor = defaultElemConfig.borderColor;
if (isColorStr(viewElem.detail.borderColor) === true) {
borderColor = viewElem.detail.borderColor as string;
}
const { borderWidth, borderRadius, borderDash, boxSizing } = viewElem.detail;
const { borderWidth, borderRadius, borderDash, boxSizing = defaultElemConfig.boxSizing } = viewElem.detail;
let bw: number = 0;
if (typeof borderWidth === 'number') {
bw = borderWidth || 1;
Expand All @@ -217,7 +221,10 @@ function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>, opts:
radiusList = [borderRadius[0] * scale, borderRadius[1] * scale, borderRadius[2] * scale, borderRadius[3] * scale];
}
ctx.strokeStyle = borderColor;
ctx.setLineDash(borderDash || []);
let viewBorderDash: number[] = [];
if (Array.isArray(borderDash) && borderDash.length > 0) {
viewBorderDash = borderDash.map((num) => Math.ceil(num * scale));
}

let borderTop = 0;
let borderRight = 0;
Expand All @@ -229,7 +236,9 @@ function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>, opts:
borderBottom = (borderWidth[2] || 0) * scale;
borderLeft = (borderWidth[3] || 0) * scale;
}

if (borderLeft || borderRight || borderTop || borderBottom) {
ctx.lineCap = 'butt';
let { x, y, w, h } = viewElem;
if (boxSizing === 'border-box') {
x = x + borderLeft / 2;
Expand Down Expand Up @@ -306,9 +315,14 @@ function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>, opts:
// if (r < w / 2 && r < h / 2) {
// r = r + bw / 2;
// }
ctx.beginPath();
ctx.lineCap = 'square';
if (viewBorderDash.length > 0) {
ctx.lineCap = 'butt';
} else {
ctx.lineCap = 'square';
}
ctx.setLineDash(viewBorderDash);
ctx.lineWidth = bw;
ctx.beginPath();
ctx.moveTo(x + radiusList[0], y);
ctx.arcTo(x + w, y, x + w, y + h, radiusList[1]);
ctx.arcTo(x + w, y + h, x, y + h, radiusList[2]);
Expand All @@ -318,6 +332,7 @@ function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>, opts:
ctx.stroke();
ctx.globalAlpha = 1;
}
ctx.setLineDash([]);
}

export function drawBoxShadow(
Expand All @@ -330,7 +345,7 @@ export function drawBoxShadow(
const { shadowColor, shadowOffsetX, shadowOffsetY, shadowBlur } = detail;
if (is.number(shadowBlur)) {
ctx.save();
ctx.shadowColor = shadowColor || '#000000';
ctx.shadowColor = shadowColor || defaultElemConfig.shadowColor;
ctx.shadowOffsetX = (shadowOffsetX || 0) * viewScaleInfo.scale;
ctx.shadowOffsetY = (shadowOffsetY || 0) * viewScaleInfo.scale;
ctx.shadowBlur = (shadowBlur || 0) * viewScaleInfo.scale;
Expand Down
15 changes: 13 additions & 2 deletions packages/renderer/src/draw/elements.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import type { Data, RendererDrawElementOptions, ViewContext2D } from '@idraw/types';

import { getDefaultElementDetailConfig } from '@idraw/util';
import { drawElement } from './group';

const defaultDetail = getDefaultElementDetailConfig();

export function drawElementList(ctx: ViewContext2D, data: Data, opts: RendererDrawElementOptions) {
const { elements = [] } = data;
for (let i = 0; i < elements.length; i++) {
const elem = elements[i];
const element = elements[i];
const elem = {
...element,
...{
detail: {
...defaultDetail,
...element?.detail
}
}
};
// TODO
if (!opts.calculator.isElementInView(elem, opts.viewScaleInfo, opts.viewSizeInfo)) {
continue;
Expand Down
1 change: 1 addition & 0 deletions packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export * from './lib/context2d';
export * from './lib/controller';
export * from './lib/html';
export * from './lib/svg-path';
export * from './lib/config';
3 changes: 3 additions & 0 deletions packages/types/src/lib/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { ElementBaseDetail } from './element';

export type DefaultElementDetailConfig = Required<Omit<ElementBaseDetail, 'clipPath' | 'background'>>;
1 change: 1 addition & 0 deletions packages/util/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,4 @@ export { generateHTML, parseHTML } from './lib/html';
export { compressImage } from './lib/image';
export { formatNumber } from './lib/number';
export { matrixToAngle, matrixToRadian } from './lib/matrix';
export { getDefaultElementDetailConfig } from './lib/config';
17 changes: 17 additions & 0 deletions packages/util/src/lib/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { DefaultElementDetailConfig } from '@idraw/types';

export function getDefaultElementDetailConfig(): DefaultElementDetailConfig {
const config: DefaultElementDetailConfig = {
boxSizing: 'border-box',
borderWidth: 0,
borderColor: '#000000',
shadowColor: '#000000',
borderRadius: 0,
borderDash: [],
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 0,
opacity: 1
};
return config;
}
3 changes: 2 additions & 1 deletion packages/util/src/lib/context2d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ export class Context2D implements ViewContext2D {
}

setLineDash(nums: number[]) {
return this._ctx.setLineDash(nums.map((n) => this.$doPixelRatio(n)));
const dash = nums.map((n) => this.$doPixelRatio(n));
return this._ctx.setLineDash(dash);
}

stroke(path?: Path2D) {
Expand Down

0 comments on commit 14b8436

Please sign in to comment.