fix(2d): handle lines with no points (#233)

Lines with no points no longer crash the editor.
When a line with no points is detected, a warning message is logged to the
console.

Closes: #212
This commit is contained in:
Jacob
2023-02-07 13:34:15 +01:00
committed by GitHub
parent a953b64540
commit 81084743df
4 changed files with 64 additions and 17 deletions

View File

@@ -23,6 +23,8 @@ import {
getPointAtDistance,
CurvePoint,
} from '../curves';
import {useLogger} from '@motion-canvas/core/lib/utils';
import lineWithoutPoints from './__logs__/line-without-points.md';
export interface LineProps extends ShapeProps {
children?: Node[];
@@ -88,6 +90,13 @@ export class Line extends Shape {
public constructor(props: LineProps) {
super(props);
if (props.children === undefined && props.points === undefined) {
useLogger().warn({
message: 'No points specified for the line',
remarks: lineWithoutPoints,
inspect: this.key,
});
}
}
@computed()
@@ -286,14 +295,16 @@ export class Line extends Shape {
const points = this.parsedPoints().map(point =>
point.transformAsPoint(matrix),
);
moveTo(path, points[0]);
for (const point of points) {
lineTo(path, point);
context.beginPath();
arc(context, point, 4);
context.closePath();
context.fill();
context.stroke();
if (points.length > 0) {
moveTo(path, points[0]);
for (const point of points) {
lineTo(path, point);
context.beginPath();
arc(context, point, 4);
context.closePath();
context.fill();
context.stroke();
}
}
context.strokeStyle = 'white';

View File

@@ -1000,17 +1000,19 @@ export class Node implements Promisable<Node> {
this.transformContext(context);
if (this.requiresCache()) {
this.setupDrawFromCache(context);
const cacheContext = this.cachedCanvas();
const cacheRect = this.cacheRect();
const compositeOverride = this.compositeOverride();
context.drawImage(cacheContext.canvas, cacheRect.x, cacheRect.y);
if (compositeOverride > 0) {
context.save();
context.globalAlpha *= compositeOverride;
context.globalCompositeOperation = 'source-over';
if (cacheRect.width !== 0 && cacheRect.height !== 0) {
this.setupDrawFromCache(context);
const cacheContext = this.cachedCanvas();
const compositeOverride = this.compositeOverride();
context.drawImage(cacheContext.canvas, cacheRect.x, cacheRect.y);
context.restore();
if (compositeOverride > 0) {
context.save();
context.globalAlpha *= compositeOverride;
context.globalCompositeOperation = 'source-over';
context.drawImage(cacheContext.canvas, cacheRect.x, cacheRect.y);
context.restore();
}
}
} else {
this.draw(context);

View File

@@ -0,0 +1,30 @@
The line won't be visible unless you specify at least two points:
```tsx
<Line
stroke="#fff"
lineWidth={8}
points={[
[100, 0],
[0, 0],
[0, 100],
]}
/>
```
Alternatively, you can define the points using the children:
```tsx
<Line stroke="#fff" lineWidth={8}>
<Node x={100} />
<Node />
<Node y={100} />
</Line>
```
If you did this intentionally, and want to disable this message, set the
`points` property to `null`:
```tsx
<Line stroke="#fff" lineWidth={8} points={null} />
```

View File

@@ -13,6 +13,10 @@ export function getPolylineProfile(
segments: [],
};
if (points.length === 0) {
return profile;
}
if (closed) {
const middle = points[0].add(points[points.length - 1]).scale(0.5);
points.unshift(middle);