Skip to content

Commit

Permalink
feat: rough ellipse, polyline and path
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoiver committed Nov 12, 2024
1 parent 5a24a03 commit 0180b33
Show file tree
Hide file tree
Showing 27 changed files with 1,775 additions and 772 deletions.
41 changes: 41 additions & 0 deletions packages/core/examples/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import {
Canvas,
Rect,
RoughCircle,
RoughEllipse,
RoughRect,
RoughPolyline,
RoughPath,
Path,
fromSVGElement,
deserializeNode,
Expand Down Expand Up @@ -39,6 +42,21 @@ const circle = new RoughCircle({
});
canvas.appendChild(circle);

const ellipse = new RoughEllipse({
cx: 0,
cy: 0,
rx: 50,
ry: 20,
fill: 'black',
strokeWidth: 2,
stroke: 'red',
seed: 1,
roughness: 1,
fillStyle: 'dots',
});
canvas.appendChild(ellipse);
ellipse.position.x = 200;

const rect = new RoughRect({
x: 0,
y: 0,
Expand All @@ -50,6 +68,7 @@ const rect = new RoughRect({
seed: 1,
roughness: 1,
fillStyle: 'dots',
opacity: 0.5,
});
rect.position.x = 200;
rect.position.y = 200;
Expand All @@ -62,6 +81,28 @@ rect.addEventListener('pointerleave', () => {
rect.fill = 'black';
});

const polyline = new RoughPolyline({
points: [
[0, 0],
[100, 0],
[100, 100],
[0, 100],
[0, 0],
],
strokeWidth: 2,
stroke: 'red',
});
canvas.appendChild(polyline);
polyline.position.x = 400;

const path = new RoughPath({
d: 'M10 80 Q 95 10 180 80',
fill: 'none',
strokeWidth: 2,
stroke: 'red',
});
canvas.appendChild(path);

// setTimeout(() => {
// ring.seed = 1000;
// ring.roughness = 5;
Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/drawcalls/BatchManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import {
Polyline,
Rect,
RoughCircle,
RoughEllipse,
RoughPath,
RoughPolyline,
RoughRect,
type Shape,
} from '../shapes';
Expand Down Expand Up @@ -35,13 +38,27 @@ SHAPE_DRAWCALL_CTORS.set(RoughCircle, [
SmoothPolyline, // fill
SmoothPolyline, // stroke
]);
// @ts-expect-error Property 'getGeometryBounds' is missing in type 'RoughEllipse'
SHAPE_DRAWCALL_CTORS.set(RoughEllipse, [
Mesh, // fillStyle === 'solid'
SmoothPolyline, // fill
SmoothPolyline, // stroke
]);
// @ts-expect-error Property 'getGeometryBounds' is missing in type 'RoughRect'
SHAPE_DRAWCALL_CTORS.set(RoughRect, [
ShadowRect,
Mesh, // fillStyle === 'solid'
SmoothPolyline, // fill
SmoothPolyline, // stroke
]);
// @ts-expect-error Property 'getGeometryBounds' is missing in type 'RoughPolyline'
SHAPE_DRAWCALL_CTORS.set(RoughPolyline, [SmoothPolyline]);
// @ts-expect-error Property 'getGeometryBounds' is missing in type 'RoughPath'
SHAPE_DRAWCALL_CTORS.set(RoughPath, [
Mesh, // fillStyle === 'solid'
SmoothPolyline, // fill
SmoothPolyline, // stroke
]);

export class BatchManager {
/**
Expand Down
13 changes: 11 additions & 2 deletions packages/core/src/drawcalls/Mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ import {
Texture,
StencilOp,
} from '@antv/g-device-api';
import { Path, RoughCircle, RoughRect, TesselationMethod } from '../shapes';
import {
Path,
RoughCircle,
RoughEllipse,
RoughPath,
RoughRect,
TesselationMethod,
} from '../shapes';
import { Drawcall, ZINDEX_FACTOR } from './Drawcall';
import { vert, frag, Location } from '../shaders/mesh';
import { isString, paddingMat3, triangulate } from '../utils';
Expand Down Expand Up @@ -93,7 +100,9 @@ export class Mesh extends Drawcall {
tessellationMethod = instance.tessellationMethod;
} else if (
instance instanceof RoughCircle ||
instance instanceof RoughRect
instance instanceof RoughEllipse ||
instance instanceof RoughRect ||
instance instanceof RoughPath
) {
rawPoints = instance.fillPathPoints;
tessellationMethod = TesselationMethod.EARCUT;
Expand Down
35 changes: 29 additions & 6 deletions packages/core/src/drawcalls/SmoothPolyline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ import {
Polyline,
Rect,
RoughCircle,
RoughEllipse,
RoughRect,
RoughPolyline,
Shape,
hasValidStroke,
RoughPath,
} from '../shapes';
import { Drawcall, ZINDEX_FACTOR } from './Drawcall';
import { vert, frag, Location, JointType } from '../shaders/polyline';
Expand All @@ -47,7 +50,10 @@ export class SmoothPolyline extends Drawcall {
return (
shape instanceof Polyline ||
shape instanceof RoughCircle ||
shape instanceof RoughEllipse ||
shape instanceof RoughRect ||
shape instanceof RoughPolyline ||
shape instanceof RoughPath ||
((shape instanceof Rect ||
shape instanceof Circle ||
shape instanceof Ellipse) &&
Expand Down Expand Up @@ -83,7 +89,10 @@ export class SmoothPolyline extends Drawcall {
instance instanceof Polyline ||
instance instanceof Path ||
instance instanceof RoughCircle ||
instance instanceof RoughRect
instance instanceof RoughEllipse ||
instance instanceof RoughRect ||
instance instanceof RoughPolyline ||
instance instanceof RoughPath
) {
return this.pointsBuffer.length / strideFloats - 3;
} else if (instance instanceof Rect) {
Expand All @@ -104,8 +113,12 @@ export class SmoothPolyline extends Drawcall {
this.shapes.forEach((shape: Polyline) => {
const { pointsBuffer: pBuffer, travelBuffer: tBuffer } = updateBuffer(
shape,
(shape instanceof RoughCircle && this.index === 2) ||
(shape instanceof RoughRect && this.index === 3),
((shape instanceof RoughCircle ||
shape instanceof RoughEllipse ||
shape instanceof RoughPath) &&
this.index === 2) ||
(shape instanceof RoughRect && this.index === 3) ||
shape instanceof RoughPolyline,
);

pointsBuffer.push(...pBuffer);
Expand Down Expand Up @@ -480,8 +493,12 @@ export class SmoothPolyline extends Drawcall {
];

if (
(instance instanceof RoughCircle && this.index === 1) ||
(instance instanceof RoughRect && this.index === 2)
((instance instanceof RoughCircle ||
instance instanceof RoughEllipse ||
instance instanceof RoughPath) &&
this.index === 1) ||
(instance instanceof RoughRect && this.index === 2) ||
instance instanceof RoughPolyline
) {
u_StrokeColor = [fr / 255, fg / 255, fb / 255, fo];
u_Opacity[2] = fillOpacity;
Expand Down Expand Up @@ -541,7 +558,13 @@ export function updateBuffer(object: Shape, useRoughStroke = true) {
let points: number[] = [];
// const triangles: number[] = [];

if (object instanceof RoughCircle || object instanceof RoughRect) {
if (
object instanceof RoughCircle ||
object instanceof RoughEllipse ||
object instanceof RoughRect ||
object instanceof RoughPolyline ||
object instanceof RoughPath
) {
const { strokePoints, fillPoints } = object;
points = (useRoughStroke ? strokePoints : fillPoints)
.map((subPathPoints, i) => {
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/shapes/Circle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export function CircleWrapper<TBase extends GConstructor>(Base: TBase) {
#cy: number;
#r: number;

onGeometryChanged?: () => void;

static getGeometryBounds(
attributes: Partial<Pick<CircleAttributes, 'cx' | 'cy' | 'r'>>,
) {
Expand Down Expand Up @@ -67,6 +69,7 @@ export function CircleWrapper<TBase extends GConstructor>(Base: TBase) {
this.geometryBoundsDirtyFlag = true;
this.renderBoundsDirtyFlag = true;
this.boundsDirtyFlag = true;
this.onGeometryChanged?.();
}
}

Expand All @@ -81,6 +84,7 @@ export function CircleWrapper<TBase extends GConstructor>(Base: TBase) {
this.geometryBoundsDirtyFlag = true;
this.renderBoundsDirtyFlag = true;
this.boundsDirtyFlag = true;
this.onGeometryChanged?.();
}
}

Expand All @@ -95,6 +99,7 @@ export function CircleWrapper<TBase extends GConstructor>(Base: TBase) {
this.geometryBoundsDirtyFlag = true;
this.renderBoundsDirtyFlag = true;
this.boundsDirtyFlag = true;
this.onGeometryChanged?.();
}
}

Expand Down
Loading

0 comments on commit 0180b33

Please sign in to comment.