Skip to content

Commit

Permalink
Merge pull request #1748 from VisActor/feat/drawMode
Browse files Browse the repository at this point in the history
Feat/draw mode
  • Loading branch information
neuqzxy authored Feb 21, 2025
2 parents 6f3aea5 + 28df5ea commit f938ae6
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vrender-core",
"comment": "feat: group support drawMode attribute",
"type": "none"
}
],
"packageName": "@visactor/vrender-core"
}
3 changes: 3 additions & 0 deletions packages/vrender-core/src/canvas/contributions/base-canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ export abstract class BaseCanvas implements ICanvas {
get nativeCanvas(): HTMLCanvasElement {
return this._nativeCanvas;
}
set nativeCanvas(nativeCanvas: HTMLCanvasElement) {
this._nativeCanvas = nativeCanvas;
}

get width(): number {
return this._pixelWidth;
Expand Down
4 changes: 3 additions & 1 deletion packages/vrender-core/src/graphic/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,9 @@ export const DefaultGroupAttribute: Required<IGroupGraphicAttribute> = {
alignContent: 'flex-start',
baseOpacity: 1,
cornerType: 'round'
};
// 默认是0,不需要主题
// drawMode: 0
} as any;

export const DefaultGlyphAttribute: Required<IGlyphGraphicAttribute> = {
...DefaultAttribute,
Expand Down
7 changes: 7 additions & 0 deletions packages/vrender-core/src/interface/graphic/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ export type IGroupAttribute = {
* 基准的透明度,用于控制group下面整体图元的透明度
*/
baseOpacity?: number;
/**
* 绘制模式
* 0 - 直接绘制
* 1 - 绘制到新Canvas上,再绘制回来,需要绘制背景,然后绘制group
* 2 - 绘制到新Canvas上,再绘制回来,不需要绘制背景,只需要绘制group
*/
drawMode?: 0 | 1 | 2;
};

export type IGroupGraphicAttribute = Partial<IGraphicAttribute> & Partial<IGroupAttribute>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { GROUP_NUMBER_TYPE } from '../../../graphic/constants';
import { BaseRenderContributionTime } from '../../../common/enums';
import { defaultGroupBackgroundRenderContribution } from './contributions';
import { multiplyMat4Mat4 } from '../../../common/matrix';
import { vglobal } from '../../../modules';

@injectable()
export class DefaultCanvasGroupRender implements IGraphicRender {
Expand Down Expand Up @@ -220,8 +221,47 @@ export class DefaultCanvasGroupRender implements IGraphicRender {
if (!context) {
return;
}

// debugger;
const { clip, baseOpacity = 1 } = group.attribute;
const { clip, baseOpacity = 1, drawMode, x, y, width, height } = group.attribute;
const lastNativeContext = context.nativeContext;
const lastNativeCanvas = context.canvas.nativeCanvas;

if (drawMode > 0) {
// 绘制到新的Canvas上,然后再绘制回来
const canvas = context.canvas;
const newCanvas = vglobal.createCanvas({ width: canvas.width, height: canvas.height, dpr: 1 });
const newContext = newCanvas.getContext('2d');
const transform = context.nativeContext.getTransform();
// 首先应用transform
newContext.setTransform(transform.a, transform.b, transform.c, transform.d, transform.e, transform.f);
// 然后将背景绘制到新的canvas上,只绘制group的Bounds区域
// 如果drawMode === 1,则需要背景
// 如果drawMode === 2,则不需要背景,只需要group即可
if (drawMode === 1) {
newContext.save();
newContext.clearRect(0, 0, canvas.width, canvas.height);
newContext.beginPath();

newContext.rect(x, y, width, height);
newContext.clip();
newContext.drawImage(
canvas.nativeCanvas,
0,
0,
canvas.width,
canvas.height,
0,
0,
canvas.displayWidth,
canvas.displayHeight
);
newContext.restore();
}
// 狸猫换太子,把新的context赋值给context
context.nativeContext = newContext;
canvas.nativeCanvas = newCanvas;
}
if (clip) {
context.save();
} else {
Expand Down Expand Up @@ -304,6 +344,34 @@ export class DefaultCanvasGroupRender implements IGraphicRender {

context.baseGlobalAlpha = baseGlobalAlpha;

if (drawMode > 0) {
// 将原始的context和canvas恢复,另外将newCanvas上的内容绘制到lastCanvas上
const newContext = context.nativeContext;
const newCanvas = context.canvas.nativeCanvas;
lastNativeContext.save();
lastNativeContext.setTransform(context.dpr, 0, 0, context.dpr, 0, 0, true);
// 如果drawMode === 1,则需要清一下之前的背景,否则背景就重复绘制了一次
if (drawMode === 1) {
newContext.rect(x, y, width, height);
}
lastNativeContext.drawImage(
newCanvas,
0,
0,
newCanvas.width,
newCanvas.height,
0,
0,
context.canvas.displayWidth,
context.canvas.displayHeight
);
const transform = newContext.getTransform();
lastNativeContext.setTransform(transform.a, transform.b, transform.c, transform.d, transform.e, transform.f);
context.nativeContext = lastNativeContext;
context.canvas.nativeCanvas = lastNativeCanvas;
lastNativeContext.restore();
}

if (p && p.then) {
p.then(() => {
if (clip) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1075,15 +1075,11 @@ export class BrowserContext2d implements IContext2d {
if (blur) {
_context.filter = `blur(${blur}px)`;
this._clearFilterStyle = true;
} else if (this._clearFilterStyle) {
_context.filter = 'blur(0px)';
this._clearFilterStyle = false;
}
if (filter) {
} else if (filter) {
_context.filter = filter;
this._clearFilterStyle = true;
} else if (this._clearFilterStyle) {
_context.filter = '';
_context.filter = 'blur(0px)';
this._clearFilterStyle = false;
}

Expand Down
68 changes: 68 additions & 0 deletions packages/vrender/__tests__/browser/src/pages/image-cloud.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { createStage, createImage, createGroup } from '@visactor/vrender';
import { addShapesToStage, colorPools } from '../utils';

const urlPng = 'https://vega.github.io/images/idl-logo.png';
const svg =
'<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" r="6" fill="#FD9C87"></circle><circle opacity="0.6" cx="6" cy="6" r="1" stroke="white" stroke-width="2"></circle></svg>';
const svg1 =
'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g><rect x="2" y="1" width="20" height="20" rx="10" fill="#1E54C9"/><rect x="2.5" y="1.5" width="19" height="19" rx="9.5" stroke="#141414" stroke-opacity="0.2"/></g><path d="M14.9492 9.39531C15.0086 9.31911 15.0165 9.21887 14.9698 9.1356C14.923 9.05234 14.8294 9 14.7273 9L9.27273 9C9.17057 9 9.07697 9.05234 9.03023 9.1356C8.98348 9.21887 8.99142 9.31911 9.0508 9.39531L11.7781 12.8953C11.8293 12.961 11.9119 13 12 13C12.0881 13 12.1707 12.961 12.2219 12.8953L14.9492 9.39531Z" fill="white"/></svg>';
const base64 =
'data:image/png;base64,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';
// const urlSvg = 'https://replace-with-svg-link.svg';

const dogImage = 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/vrender/lovely_dog.jpg';
const visactorIcon = 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/vrender/vsactor-icon.png';

export const page = () => {
const shapes = [];

shapes.push(
createImage({
x: 0,
y: 0,
image: dogImage,
height: 600
})
);

const group = createGroup({
x: 200,
y: 200,
width: 300,
height: 300,
background: visactorIcon,
drawMode: 2
});

for (let i = 0; i < 300; i++) {
const image = createImage({
x: Math.random() * 350 - 25,
y: Math.random() * 350 - 25,
width: 100,
image: dogImage,
globalCompositeOperation: 'source-atop'
});
group.add(image);
}
shapes.push(group);

shapes.forEach(g => {
g.addEventListener('click', () => {
console.log('click', g._uid);
});
});

const stage = createStage({
canvas: 'main',
width: 1200,
height: 600,
viewWidth: 1200,
viewHeight: 600
});

stage.render();

shapes.forEach(shape => {
stage.defaultLayer.add(shape);
});
};
4 changes: 4 additions & 0 deletions packages/vrender/__tests__/browser/src/pages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export const pages = [
name: '手势事件测试',
path: 'gesture-test'
},
{
name: 'image-cloud',
path: 'image-cloud'
},
{
name: 'arc绘制',
path: 'arc'
Expand Down

0 comments on commit f938ae6

Please sign in to comment.