mirror of
https://github.com/bspeice/speice.io
synced 2025-07-29 03:25:03 -04:00
@ -1,99 +0,0 @@
|
||||
import {createContext, useEffect, useRef, useState} from "react";
|
||||
import {Transform} from "./transform";
|
||||
import {randomBiUnit} from "./randomBiunit";
|
||||
import {useColorMode} from "@docusaurus/theme-common";
|
||||
import {randomChoice} from "./randomChoice";
|
||||
|
||||
export interface Flame {
|
||||
transforms: [number, Transform][];
|
||||
final: Transform;
|
||||
palette: Uint8Array;
|
||||
}
|
||||
|
||||
interface IFlameContext {
|
||||
setQuality?: (quality: number) => void;
|
||||
setFlame?: (flame: Flame) => void;
|
||||
}
|
||||
|
||||
export const FlameContext = createContext<IFlameContext>({});
|
||||
|
||||
abstract class Renderer {
|
||||
protected readonly _size: number;
|
||||
protected _x: number = randomBiUnit();
|
||||
protected _y: number = randomBiUnit();
|
||||
protected _iterations: number = 0;
|
||||
|
||||
protected _flame?: Flame;
|
||||
|
||||
protected constructor(size: number) {
|
||||
this._size = size;
|
||||
}
|
||||
|
||||
abstract plot(x: number, y: number, c: number): void;
|
||||
abstract run(iterations: number): void;
|
||||
abstract paint(image: ImageData): void;
|
||||
|
||||
public get size(): number {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
public get iterations(): number {
|
||||
return this._iterations;
|
||||
}
|
||||
|
||||
public set flame(value: Flame) {
|
||||
[this._x, this._y] = [randomBiUnit(), randomBiUnit()];
|
||||
this._iterations = 0;
|
||||
}
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
renderer: Renderer;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const FlameCanvas: React.FC<Props> = ({renderer, children}) => {
|
||||
const ITER_STEP = 10000;
|
||||
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
||||
|
||||
const colorMode = useColorMode();
|
||||
const [quality, setQuality] = useState<number>();
|
||||
const [flame, setFlame] = useState<Flame>(null);
|
||||
|
||||
var image: ImageData = null;
|
||||
|
||||
function animate() {
|
||||
renderer.run(ITER_STEP);
|
||||
paint();
|
||||
|
||||
if (renderer.iterations < quality * renderer.size * renderer.size) {
|
||||
requestAnimationFrame(this);
|
||||
}
|
||||
}
|
||||
|
||||
function paint() {
|
||||
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
renderer.flame = flame;
|
||||
requestAnimationFrame(animate);
|
||||
}, [quality, flame]);
|
||||
|
||||
useEffect(() => { paint(); }, [colorMode]);
|
||||
|
||||
return (
|
||||
<FlameContext.Provider value={{setFlame, setQuality}}>
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
width={renderer.size}
|
||||
height={renderer.size}
|
||||
style={{
|
||||
aspectRatio: '1 / 1',
|
||||
width: '100%',
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</FlameContext.Provider>
|
||||
)
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export function randomBiUnit() {
|
||||
return Math.random() * 2 - 1;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/**
|
||||
* @param choices array of [weight, value] pairs
|
||||
* @returns pair of [index, value]
|
||||
*/
|
||||
export function randomChoice<T>(choices: [number, T][]): [number, T] {
|
||||
const weightSum = choices.reduce(
|
||||
(current, [weight, _]) => current + weight,
|
||||
0
|
||||
);
|
||||
var choice = Math.random() * weightSum;
|
||||
|
||||
for (var i = 0; i < choices.length; i++) {
|
||||
const [weight, t] = choices[i];
|
||||
if (choice < weight) {
|
||||
return [i, t];
|
||||
}
|
||||
|
||||
choice -= weight;
|
||||
}
|
||||
|
||||
throw "unreachable";
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export function randomInteger(min: number, max: number) {
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
@ -4,7 +4,6 @@ import { Variation } from './variations'
|
||||
export interface Transform {
|
||||
coefs: Coefs,
|
||||
variations: [number, Variation][],
|
||||
enabled: boolean,
|
||||
coefsPost?: Coefs,
|
||||
color?: number
|
||||
coefsPost: Coefs,
|
||||
color: number
|
||||
}
|
Reference in New Issue
Block a user