Skip to content

Instantly share code, notes, and snippets.

@namse
Created September 4, 2021 18:34
Show Gist options
  • Save namse/4054327706d3bff2d2a7f86c074aea38 to your computer and use it in GitHub Desktop.
Save namse/4054327706d3bff2d2a7f86c074aea38 to your computer and use it in GitHub Desktop.
namui rebuilding v0.4
import {
CanvasKit,
CanvasKitInit,
ClipOp,
Image,
InputRect,
InputRRect,
Paint,
Paragraph,
ParagraphStyle,
Path,
Rect,
} from "canvaskit-wasm";
export {};
// 주제 : canvasKit을 적극 활용한 버전
// update -> render -> event handling -> 반복
// ----Engine Type-----
type RenderingData = {
clip?: {
path: Path | InputRect | InputRRect;
clipOp: ClipOp;
};
command: ([Path, Paint] | [Paragraph, Paint] | [Image, Paint?])[];
onClick?: () => void;
}[];
type ParagraphMaker = (
style: ParagraphStyle,
font: string,
text: string
) => Paragraph;
type RenderingFunction = (
canvasKit: CanvasKit,
makeParagraph: ParagraphMaker
) => RenderingData;
type RenderingTree = (RenderingFunction | RenderingTree)[];
// ------------------------------------------------------------
type State = {
counters: {
count: number;
}[];
};
function index(state: State): RenderingTree {
return [
state.counters.map((counterState) =>
Counter({
state: counterState,
onRemove: () => {
// case 1. remove by index
// problem - what if remove 2 counters, index 3 and 5? it will remove original 3, 6 counter.
// case 2. remove by reference
state.counters.remove(counterState);
},
})
),
Button({
x: 20,
y: 0,
width: 20,
height: 20,
text: "add counter",
onClick: () => {
state.counters.push({ count: 0 });
},
}),
];
}
function Counter({
state,
onRemove,
}: {
state: { count: number };
onRemove: () => void;
}): RenderingTree {
return [
TextComponent(state.count),
Button({
x: 20,
y: 0,
width: 20,
height: 20,
text: "+",
onClick: () => {
state.count += 1;
},
}),
Button({
x: 40,
y: 0,
width: 20,
height: 20,
text: "remove",
onClick: () => {
onRemove();
},
}),
];
}
function TextComponent(value: string | number): RenderingFunction {
return (canvasKit, makeParagraph) => {
const paragraph = makeParagraph(
{
maxLines: 1,
},
"default",
value.toString()
);
const textPaint = new canvasKit.Paint();
textPaint.setColor(canvasKit.Color4f(0.9, 0, 0, 1.0));
textPaint.setStyle(canvasKit.PaintStyle.Fill);
textPaint.setAntiAlias(true);
return [
{
command: [[paragraph, textPaint]],
},
];
};
}
function Button({
x,
y,
width,
height,
text,
onClick,
}: {
x: number;
y: number;
width: number;
height: number;
text: string;
onClick: () => void;
}): RenderingTree {
return [
Rect({
x,
y,
width,
height,
onClick,
}),
TextComponent(text),
];
}
function Rect({
x,
y,
width,
height,
onClick,
}: {
x: number;
y: number;
width: number;
height: number;
onClick?: () => void;
}): RenderingFunction {
return (canvasKit) => {
const borderRectPath = new canvasKit.Path().addRect(
canvasKit.XYWHRect(x, y, width, height)
);
const borderPaint = new canvasKit.Paint();
borderPaint.setColor(canvasKit.Color4f(0.9, 0, 0, 1.0));
borderPaint.setStyle(canvasKit.PaintStyle.Stroke);
borderPaint.setAntiAlias(true);
return [
{
command: [[borderRectPath, borderPaint]],
onClick,
},
];
};
}
declare global {
interface Array<T> {
remove(o: T): void;
}
}
Array.prototype.remove = function (element) {
const index = this.indexOf(element);
if (index > -1) {
this.splice(index, 1);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment