blob: e7c9f1b535319acff3be301ff51e891d18d2fd85 [file]
// One path of thousands of segments, rebuilt in advance from the time
// advanced so far every frame, then filled and stroked.
import { Layout, Context } from "rive/host";
import { Vector } from "rive/vector";
import { Path } from "rive/path";
import { Paint, PaintStyle } from "rive/paint";
import { Renderer } from "rive/renderer";
const SEGMENTS: i32 = 4096;
const CENTER: f32 = 128;
export class Main extends Layout {
path: Path = new Path();
fill: Paint = new Paint();
stroke: Paint = new Paint();
time: f32 = 0;
override init(context: Context): bool {
this.fill.style = PaintStyle.fill;
this.fill.color = 0xFF2E86DE;
this.stroke.style = PaintStyle.stroke;
this.stroke.thickness = 1.5;
this.stroke.color = 0xFFFFD166;
return true;
}
override advance(seconds: f64): bool {
this.time += <f32>seconds;
let path = this.path;
path.reset();
path.moveTo(this.point(0));
// Every fourth segment curves, so both verbs cross.
for (let i = 1; i < SEGMENTS; i++) {
if ((i & 3) == 0 && i + 2 < SEGMENTS) {
path.cubicTo(this.point(i), this.point(i + 1), this.point(i + 2));
i += 2;
} else {
path.lineTo(this.point(i));
}
}
path.close();
return true;
}
private point(i: i32): Vector {
let angle = <f32>i / <f32>SEGMENTS * 6.2831853;
let radius = 70 + 40 * Mathf.sin(angle * 12 + this.time * 2) *
Mathf.cos(angle * 7 - this.time);
return Vector.xy(CENTER + radius * Mathf.cos(angle),
CENTER + radius * Mathf.sin(angle));
}
override draw(renderer: Renderer): void {
renderer.drawPath(this.path, this.fill);
renderer.drawPath(this.path, this.stroke);
}
}