Skip to content

Commit

Permalink
refactor: backmoji rendering logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Bernankez committed Apr 16, 2024
1 parent c384579 commit 8c5970f
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 36 deletions.
18 changes: 15 additions & 3 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ export * from "./utils/shared";
export * from "./utils/math";

export interface BackmojiOptions {
width?: number;
height?: number;
degree?: number;
rowGap?: number;
columnGap?: number;
Expand Down Expand Up @@ -38,7 +36,9 @@ export function backmoji(canvas: Awaitable<HTMLCanvasElement>, renderer: Awaitab
const _canvas = await canvas;
const ctx = _canvas.getContext("2d");
assert(ctx, "Current environment does not support 2d canvas rendering");
const { width = 300, height = 150, degree = 0, rowGap = 0, columnGap = 0 } = _options || {};
const { degree = 0, rowGap = 0, columnGap = 0 } = _options || {};
const width = _canvas.width;
const height = _canvas.height;
let _degree = degree % 360;
if (_degree < 0) {
_degree = 360 + _degree;
Expand Down Expand Up @@ -84,9 +84,21 @@ export function backmoji(canvas: Awaitable<HTMLCanvasElement>, renderer: Awaitab
}
}

async function setSize(width: number | undefined, height: number | undefined) {
const _canvas = await canvas;
const ratio = window.devicePixelRatio;
const w = width || _canvas.width;
const h = height || _canvas.height;
_canvas.width = w * ratio;
_canvas.height = h * ratio;
_canvas.style.width = `${w}px`;
_canvas.style.height = `${h}px`;
}

return {
render,

setOptions,
setSize,
};
}
44 changes: 24 additions & 20 deletions packages/react/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,44 @@
import { type BackmojiOptions, type CreateImageRendererOptions, type CreateTextRendererOptions, type Renderer, backmoji, createImageRenderer, createTextRenderer } from "backmoji";
import type { BackmojiOptions, CreateImageRendererOptions, CreateTextRendererOptions, Renderer } from "backmoji";
import { backmoji, createImageRenderer, createTextRenderer } from "backmoji";
import { type RefObject, useEffect, useMemo, useState } from "react";

export type BackmojiResult = ReturnType<typeof backmoji>;

export function useBackmoji(renderer: Renderer | null, canvas: RefObject<HTMLCanvasElement>, options?: Omit<BackmojiOptions, "canvas">, deps?: any[]) {
const [backmojiResult, setBackmojiResult] = useState<Partial<BackmojiResult>>({});
export function useBackmoji(canvas: RefObject<HTMLCanvasElement> | HTMLCanvasElement, renderer: Renderer | undefined, options?: BackmojiOptions, deps?: any[]) {
const [backmojiResult, setBackmojiResult] = useState<BackmojiResult>({
render: async () => {},
setOptions: () => {},
setSize: async () => {},
});

useEffect(() => {
if (!renderer || !canvas.current) {
let _canvas: HTMLCanvasElement | null;
if ("current" in canvas) {
_canvas = canvas.current;
} else {
_canvas = canvas;
}
if (!_canvas || !renderer) {
return;
}

setBackmojiResult(backmoji(renderer, { ...options, canvas: canvas.current }));
setBackmojiResult(backmoji(_canvas, renderer, options));

return () => {
if (backmojiResult?.canvas) {
backmojiResult.canvas.remove();
}
_canvas?.remove();
};
}, [renderer, canvas, ...(deps || [])]);
}, [canvas, renderer, ...(deps || [])]);

return backmojiResult;
}

export function useImageLoader(img: HTMLImageElement | string) {
const [image, setImage] = useState<HTMLImageElement | null>(null);
export function useImageLoader(img: string) {
const [image, setImage] = useState<HTMLImageElement>();

useEffect(() => {
if (typeof img === "string") {
loadImage(img).then((image) => {
setImage(image);
});
} else {
setImage(img);
}
loadImage(img).then((image) => {
setImage(image);
});
}, [img]);

function loadImage(img: string) {
Expand All @@ -49,12 +54,11 @@ export function useImageLoader(img: HTMLImageElement | string) {
return image;
}

export function useImageRenderer(img: HTMLImageElement | null, options?: CreateImageRendererOptions) {
export function useImageRenderer(img: HTMLImageElement | undefined, options?: CreateImageRendererOptions) {
const renderer = useMemo(() => {
if (img) {
return createImageRenderer(img, options);
}
return null;
}, [img]);

return renderer;
Expand Down
52 changes: 39 additions & 13 deletions packages/vue/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,51 @@
import { type BackmojiOptions, type CreateImageRendererOptions, type CreateTextRendererOptions, type Renderer, backmoji, createImageRenderer, createTextRenderer } from "backmoji";
import { type ComputedRef, type MaybeRefOrGetter, computed, onMounted, ref, toValue } from "vue";
import { type MaybeRefOrGetter, computed, onMounted, ref, toValue } from "vue";

export type BackmojiResult = ReturnType<typeof backmoji>;

export function useBackmoji(renderer: MaybeRefOrGetter<Renderer | undefined>, canvas: MaybeRefOrGetter<HTMLCanvasElement | undefined>, options?: MaybeRefOrGetter<Omit<BackmojiOptions, "canvas"> | undefined>) {
return computed(() => {
export function useBackmoji(canvas: MaybeRefOrGetter<HTMLCanvasElement | undefined>, renderer: MaybeRefOrGetter<Renderer | undefined>, options?: MaybeRefOrGetter<Omit<BackmojiOptions, "canvas"> | undefined>) {
const backmojiResult = computed(() => {
const _renderer = toValue(renderer);
const _options = toValue(options);
const _canvas = toValue(canvas);
if (!_canvas || !_renderer) {
return undefined;
}
return backmoji(_renderer, {
return backmoji(_canvas, _renderer, {
..._options,
canvas: _canvas,
});
});
}

export function useTextRenderer(text: MaybeRefOrGetter<string>, options?: MaybeRefOrGetter<CreateTextRendererOptions | undefined>) {
return computed(() => {
const _text = toValue(text);
const _options = toValue(options);
return createTextRenderer(_text, _options);
});
function render() {
if (backmojiResult.value) {
return backmojiResult.value.render();
}
return Promise.resolve();
}

function setOptions(options: BackmojiOptions, combine?: boolean) {
if (backmojiResult.value) {
backmojiResult.value.setOptions(options, combine);
}
}

function setSize(width: number | undefined, height: number | undefined) {
if (backmojiResult.value) {
return backmojiResult.value.setSize(width, height);
}
return Promise.resolve();
}

return {
render,

setOptions,
setSize,
};
}

export function useImageLoader(src: MaybeRefOrGetter<string>) {
const img = ref();
const img = ref<HTMLImageElement>();

const load = async () => {
const _src = toValue(src);
Expand All @@ -54,3 +72,11 @@ export function useImageRenderer(image: MaybeRefOrGetter<HTMLImageElement | unde
return createImageRenderer(_image, _options);
});
}

export function useTextRenderer(text: MaybeRefOrGetter<string>, options?: MaybeRefOrGetter<CreateTextRendererOptions | undefined>) {
return computed(() => {
const _text = toValue(text);
const _options = toValue(options);
return createTextRenderer(_text, _options);
});
}

0 comments on commit 8c5970f

Please sign in to comment.