feat: add Grid node

This commit is contained in:
aarthificial
2022-12-06 12:55:26 +01:00
committed by Jacob
parent c107259f7c
commit e1f83da1f4
7 changed files with 105 additions and 6 deletions

View File

@@ -1,10 +1,50 @@
import {Shape} from './Shape';
import {Shape, ShapeProps} from './Shape';
import {Signal, SignalValue} from '@motion-canvas/core/lib/utils';
import {initial, property} from '../decorators';
export interface CircleProps extends ShapeProps {
startAngle?: SignalValue<number>;
endAngle?: SignalValue<number>;
}
export class Circle extends Shape {
@initial(0)
@property()
public declare readonly startAngle: Signal<number, this>;
@initial(360)
@property()
public declare readonly endAngle: Signal<number, this>;
public constructor(props: CircleProps) {
super(props);
}
protected override getPath(): Path2D {
const path = new Path2D();
const start = (this.startAngle() / 180) * Math.PI;
const end = (this.endAngle() / 180) * Math.PI;
const {width, height} = this.computedSize();
path.ellipse(0, 0, width / 2, height / 2, 0, 0, Math.PI * 2);
path.ellipse(0, 0, width / 2, height / 2, 0, start, end);
return path;
}
protected override getRipplePath(): Path2D {
const path = new Path2D();
const rippleSize = this.rippleSize();
const start = (this.startAngle() / 180) * Math.PI;
const end = (this.endAngle() / 180) * Math.PI;
const size = this.size();
path.ellipse(
0,
0,
size.x / 2 + rippleSize,
size.y / 2 + rippleSize,
0,
start,
end,
);
return path;
}
}

View File

@@ -0,0 +1,44 @@
import {Shape, ShapeProps} from './Shape';
import {SignalValue} from '@motion-canvas/core/lib/utils';
import {PossibleVector2, Vector2} from '@motion-canvas/core/lib/types';
import {initial, vector2Property, Vector2Property} from '../decorators';
export interface GridProps extends ShapeProps {
spacing?: SignalValue<PossibleVector2>;
}
export class Grid extends Shape {
@initial(80)
@vector2Property('spacing')
public declare readonly spacing: Vector2Property<this>;
public constructor(props: GridProps) {
super(props);
}
protected override drawShape(context: CanvasRenderingContext2D) {
context.save();
this.applyStyle(context);
this.drawRipple(context);
const spacing = this.spacing();
const size = this.computedSize().scale(0.5);
const steps = size.div(spacing).floored;
for (let x = -steps.x; x <= steps.x; x++) {
context.beginPath();
context.moveTo(spacing.x * x, -size.height);
context.lineTo(spacing.x * x, size.height);
context.stroke();
}
for (let y = -steps.y; y <= steps.y; y++) {
context.beginPath();
context.moveTo(-size.width, spacing.y * y);
context.lineTo(size.width, spacing.y * y);
context.stroke();
}
context.restore();
}
}

View File

@@ -459,15 +459,24 @@ export class Layout extends Node {
@computed()
protected requestLayoutUpdate() {
const parent = this.parentTransform();
if (this.isLayoutRoot() || !parent) {
this.view()?.element.append(this.element);
if (this.appendedToView()) {
parent?.requestFontUpdate();
this.updateLayout();
} else {
parent.requestLayoutUpdate();
parent!.requestLayoutUpdate();
}
}
@computed()
protected appendedToView() {
const root = this.isLayoutRoot();
if (root) {
this.view()?.element.append(this.element);
}
return root;
}
/**
* Apply any new layout changes to this node and its children.
*/

View File

@@ -98,6 +98,7 @@ export abstract class Shape extends Layout {
return super.getCacheRect().expand(this.lineWidth() / 2);
}
@computed()
protected getPath(): Path2D {
return new Path2D();
}

View File

@@ -1,5 +1,6 @@
export * from './Circle';
export * from './Image';
export * from './Grid';
export * from './Layout';
export * from './Line';
export * from './Node';

View File

@@ -222,7 +222,7 @@ export class Project {
if (this.background) {
this.context.save();
this.context.fillStyle = this.background;
this.context.fillRect(0, 0, this.width, this.height);
this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
this.context.restore();
} else {
this.context.clearRect(0, 0, this.width, this.height);

View File

@@ -119,6 +119,10 @@ export class Vector2 implements Type {
return new Vector2(-this.x, -this.y);
}
public get floored(): Vector2 {
return new Vector2(Math.floor(this.x), Math.floor(this.y));
}
public get perpendicular(): Vector2 {
return new Vector2(this.y, -this.x);
}