fix cache
add font propertie to rust text paint layout improvements
This commit is contained in:
parent
b671f9ee47
commit
1baa3ae736
Binary file not shown.
@ -30,6 +30,7 @@ pub struct Paint {
|
|||||||
pub struct TextPaint {
|
pub struct TextPaint {
|
||||||
pub style: PaintStyle,
|
pub style: PaintStyle,
|
||||||
pub align: TextAlign,
|
pub align: TextAlign,
|
||||||
|
pub fontName: String,
|
||||||
pub size: f32,
|
pub size: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +154,7 @@ pub fn test_timeline_entities_at_frame(
|
|||||||
color: Color::new(0, 0, 0, 1.0),
|
color: Color::new(0, 0, 0, 1.0),
|
||||||
width: 10.0,
|
width: 10.0,
|
||||||
}),
|
}),
|
||||||
|
fontName: "Arial".to_string(),
|
||||||
align: TextAlign::Center,
|
align: TextAlign::Center,
|
||||||
size: 20.0,
|
size: 20.0,
|
||||||
};
|
};
|
||||||
@ -162,6 +163,7 @@ pub fn test_timeline_entities_at_frame(
|
|||||||
style: PaintStyle::Fill(FillStyle {
|
style: PaintStyle::Fill(FillStyle {
|
||||||
color: Color::new(0, 0, 0, 1.0),
|
color: Color::new(0, 0, 0, 1.0),
|
||||||
}),
|
}),
|
||||||
|
fontName: "Arial".to_string(),
|
||||||
align: TextAlign::Center,
|
align: TextAlign::Center,
|
||||||
size: 10.0,
|
size: 10.0,
|
||||||
};
|
};
|
||||||
|
@ -20,12 +20,12 @@ export default function App() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-950 h-full w-full flex flex-col">
|
<div className="bg-gray-950 overflow-y-hidden h-full w-full flex flex-col">
|
||||||
<MenuBar />
|
<MenuBar />
|
||||||
<div className="flex flex-row w-full h-full">
|
<div className="flex flex-row w-full h-full">
|
||||||
<ToolBar />
|
<ToolBar />
|
||||||
<div className="flex flex-col ml-4 w-full h-full">
|
<div className="flex flex-col ml-4 mr-4 mt-4 w-full h-full overflow-x-hidden">
|
||||||
<div className="flex gap-4 flex-row mb-4 justify-center items-center">
|
<div className="flex gap-4 flex-col lg:flex-row mb-4 justify-center items-center">
|
||||||
<Canvas />
|
<Canvas />
|
||||||
<PropertiesContainer>
|
<PropertiesContainer>
|
||||||
<Properties />
|
<Properties />
|
||||||
|
@ -11,6 +11,7 @@ import { FC } from "react";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { AnimatedVec2Properties, ColorProperties } from "./Values";
|
import { AnimatedVec2Properties, ColorProperties } from "./Values";
|
||||||
import { PropertiesProps } from "./common";
|
import { PropertiesProps } from "./common";
|
||||||
|
import { useFontsStore } from "stores/fonts.store";
|
||||||
|
|
||||||
type TextPropertiesProps = PropertiesProps<z.input<typeof AnimatedTextEntity>>;
|
type TextPropertiesProps = PropertiesProps<z.input<typeof AnimatedTextEntity>>;
|
||||||
type StaggeredTextPropertiesProps = PropertiesProps<
|
type StaggeredTextPropertiesProps = PropertiesProps<
|
||||||
@ -66,6 +67,8 @@ export const TextProperties: FC<TextPropertiesProps> = ({
|
|||||||
entity,
|
entity,
|
||||||
onUpdate,
|
onUpdate,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { fonts } = useFontsStore();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.div
|
<motion.div
|
||||||
variants={{ enter: { opacity: 1, y: 0 }, from: { opacity: 0, y: 50 } }}
|
variants={{ enter: { opacity: 1, y: 0 }, from: { opacity: 0, y: 50 } }}
|
||||||
@ -92,6 +95,38 @@ export const TextProperties: FC<TextPropertiesProps> = ({
|
|||||||
}
|
}
|
||||||
></input>
|
></input>
|
||||||
</label>
|
</label>
|
||||||
|
<label className="flex flex-col items-start">
|
||||||
|
<span className="label">Font</span>
|
||||||
|
<select
|
||||||
|
onChange={(e) =>
|
||||||
|
onUpdate({
|
||||||
|
...entity,
|
||||||
|
cache: { valid: false },
|
||||||
|
paint: { ...entity.paint, fontName: e.target.value },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
value={entity.paint.fontName}
|
||||||
|
>
|
||||||
|
{fonts.map((font) => (
|
||||||
|
<option value={font} key={font}>
|
||||||
|
{font}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<span className="label">Size</span>
|
||||||
|
<input
|
||||||
|
value={entity.paint.size}
|
||||||
|
onChange={(e) =>
|
||||||
|
onUpdate({
|
||||||
|
...entity,
|
||||||
|
cache: { valid: false },
|
||||||
|
paint: { ...entity.paint, size: Number(e.target.value) },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
></input>
|
||||||
|
</label>
|
||||||
<AnimatedVec2Properties
|
<AnimatedVec2Properties
|
||||||
onUpdate={(updatedEntity) =>
|
onUpdate={(updatedEntity) =>
|
||||||
onUpdate({ ...entity, origin: updatedEntity })
|
onUpdate({ ...entity, origin: updatedEntity })
|
||||||
@ -107,6 +142,8 @@ export const StaggeredTextProperties: FC<StaggeredTextPropertiesProps> = ({
|
|||||||
entity,
|
entity,
|
||||||
onUpdate,
|
onUpdate,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { fonts } = useFontsStore();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.div
|
<motion.div
|
||||||
variants={{ enter: { opacity: 1, y: 0 }, from: { opacity: 0, y: 50 } }}
|
variants={{ enter: { opacity: 1, y: 0 }, from: { opacity: 0, y: 50 } }}
|
||||||
@ -127,6 +164,28 @@ export const StaggeredTextProperties: FC<StaggeredTextPropertiesProps> = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
<label className="flex flex-col items-start">
|
||||||
|
<span className="label">Font</span>
|
||||||
|
<select
|
||||||
|
onChange={(e) => {
|
||||||
|
onUpdate({
|
||||||
|
...entity,
|
||||||
|
cache: { valid: false },
|
||||||
|
letter: {
|
||||||
|
...entity.letter,
|
||||||
|
paint: { ...entity.letter.paint, fontName: e.target.value },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
value={entity.letter.paint.fontName}
|
||||||
|
>
|
||||||
|
{fonts.map((font) => (
|
||||||
|
<option value={font} key={font}>
|
||||||
|
{font}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
<label className="flex flex-col items-start">
|
<label className="flex flex-col items-start">
|
||||||
<span className="label">Size</span>
|
<span className="label">Size</span>
|
||||||
<input
|
<input
|
||||||
@ -134,6 +193,7 @@ export const StaggeredTextProperties: FC<StaggeredTextPropertiesProps> = ({
|
|||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
onUpdate({
|
onUpdate({
|
||||||
...entity,
|
...entity,
|
||||||
|
cache: { valid: false },
|
||||||
letter: {
|
letter: {
|
||||||
...entity.letter,
|
...entity.letter,
|
||||||
paint: {
|
paint: {
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
|
|
||||||
const PropertiesContainer: FC<{ children: ReactNode }> = ({ children }) => {
|
const PropertiesContainer: FC<{ children: ReactNode }> = ({ children }) => {
|
||||||
return (
|
return (
|
||||||
<div className="w-full rounded-md h-[500px] overflow-auto border transition-colors focus-within:border-gray-400 border-gray-600 flex flex-col items-start p-4">
|
<div className="w-full rounded-md lg:h-[500px] overflow-auto border transition-colors focus-within:border-gray-400 border-gray-600 flex flex-col items-start p-4">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -72,12 +72,12 @@ const Track: FC<TrackProps> = ({
|
|||||||
value={entity}
|
value={entity}
|
||||||
dragListener={false}
|
dragListener={false}
|
||||||
dragControls={controls}
|
dragControls={controls}
|
||||||
className="h-8 w-full flex flex-row gap-1 select-none"
|
className="h-8 w-96 flex flex-1 flex-row gap-1 select-none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
onMouseDown={(e) => e.preventDefault()}
|
onMouseDown={(e) => e.preventDefault()}
|
||||||
onPointerDown={(e) => controls.start(e)}
|
onPointerDown={(e) => controls.start(e)}
|
||||||
className={`h-full transition-all rounded-sm flex-shrink-0 w-96 p-1 px-2 flex flex-row ${
|
className={`h-full transition-all rounded-sm min-w-[200px] p-1 px-2 flex flex-row ${
|
||||||
selectedEntity === index ? "bg-gray-800" : "bg-gray-900"
|
selectedEntity === index ? "bg-gray-800" : "bg-gray-900"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@ -87,7 +87,7 @@ const Track: FC<TrackProps> = ({
|
|||||||
? deselectEntity()
|
? deselectEntity()
|
||||||
: selectEntity(index)
|
: selectEntity(index)
|
||||||
}
|
}
|
||||||
className="text-white-800 select-none pointer-events-none"
|
className="text-white-800 select-none cursor-pointer"
|
||||||
>
|
>
|
||||||
{name}
|
{name}
|
||||||
</h3>
|
</h3>
|
||||||
@ -230,11 +230,11 @@ const Timeline: FC<TimelineProps> = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="gap-1 flex flex-col overflow-y-hidden">
|
<div className="gap-1 flex flex-col overflow-y-hidden">
|
||||||
<div className="z-20 flex flex-row gap-2">
|
<div className="z-20 flex flex-row gap-2">
|
||||||
<div className="flex-shrink-0 w-96" />
|
<div className="flex-shrink-0 min-w-[200px]" />
|
||||||
<TimePicker />
|
<TimePicker />
|
||||||
</div>
|
</div>
|
||||||
<Reorder.Group
|
<Reorder.Group
|
||||||
className="gap-1 flex flex-col"
|
className="gap-1 flex-1 flex flex-col overflow-scroll"
|
||||||
values={entities}
|
values={entities}
|
||||||
onReorder={setEntities}
|
onReorder={setEntities}
|
||||||
>
|
>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { C } from "@tauri-apps/api/event-30ea0228";
|
||||||
import { BaseEntity } from "primitives/Entities";
|
import { BaseEntity } from "primitives/Entities";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@ -20,7 +21,12 @@ export function handleEntityCache<
|
|||||||
if (cached) {
|
if (cached) {
|
||||||
cache.cleanup(cached);
|
cache.cleanup(cached);
|
||||||
}
|
}
|
||||||
return cache.build();
|
|
||||||
|
const nextCache = cache.build();
|
||||||
|
|
||||||
|
cache.set(entity.id, nextCache);
|
||||||
|
|
||||||
|
return nextCache;
|
||||||
} else {
|
} else {
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
const nextCache = cache.build();
|
const nextCache = cache.build();
|
||||||
|
@ -124,7 +124,7 @@ export class Drawer {
|
|||||||
animatedEntities: z.input<typeof AnimatedEntities>,
|
animatedEntities: z.input<typeof AnimatedEntities>,
|
||||||
prepareDependencies: boolean
|
prepareDependencies: boolean
|
||||||
) {
|
) {
|
||||||
console.time("calculate");
|
// console.time("calculate");
|
||||||
|
|
||||||
if (this.didLoad) {
|
if (this.didLoad) {
|
||||||
const renderState = useRenderStateStore.getState().renderState;
|
const renderState = useRenderStateStore.getState().renderState;
|
||||||
@ -145,20 +145,20 @@ export class Drawer {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.timeEnd("calculate");
|
// console.timeEnd("calculate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
requestRedraw(rebuild: boolean) {
|
requestRedraw(rebuild: boolean) {
|
||||||
if (this.didLoad && this.surface) {
|
if (this.didLoad && this.surface && !this.isLocked) {
|
||||||
if (rebuild && this.raf !== undefined) {
|
if (rebuild && this.raf !== undefined) {
|
||||||
cancelAnimationFrame(this.raf);
|
cancelAnimationFrame(this.raf);
|
||||||
this.surface.flush();
|
// this.surface.flush();
|
||||||
this.raf = this.surface.requestAnimationFrame((canvas) =>
|
this.raf = this.surface.requestAnimationFrame((canvas) =>
|
||||||
this.draw(canvas)
|
this.draw(canvas)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.surface.flush();
|
// this.surface.flush();
|
||||||
this.raf = this.surface.requestAnimationFrame((canvas) =>
|
this.raf = this.surface.requestAnimationFrame((canvas) =>
|
||||||
this.draw(canvas)
|
this.draw(canvas)
|
||||||
);
|
);
|
||||||
@ -169,7 +169,7 @@ export class Drawer {
|
|||||||
draw(canvas: Canvas) {
|
draw(canvas: Canvas) {
|
||||||
if (this.CanvasKit && this.entities && !this.isLocked) {
|
if (this.CanvasKit && this.entities && !this.isLocked) {
|
||||||
this.isLocked = true;
|
this.isLocked = true;
|
||||||
console.time("draw");
|
//console.time("draw");
|
||||||
const CanvasKit = this.CanvasKit;
|
const CanvasKit = this.CanvasKit;
|
||||||
|
|
||||||
canvas.clear(CanvasKit.WHITE);
|
canvas.clear(CanvasKit.WHITE);
|
||||||
@ -191,12 +191,19 @@ export class Drawer {
|
|||||||
TextCache,
|
TextCache,
|
||||||
TextEntityCache
|
TextEntityCache
|
||||||
>(entity, {
|
>(entity, {
|
||||||
build: () =>
|
build: () => {
|
||||||
buildTextCache(
|
const cache = buildTextCache(
|
||||||
CanvasKit,
|
CanvasKit,
|
||||||
entity,
|
entity,
|
||||||
this.dependenciesService.dependencies
|
this.dependenciesService.dependencies
|
||||||
),
|
);
|
||||||
|
|
||||||
|
useEntitiesStore
|
||||||
|
.getState()
|
||||||
|
.updateEntityById(entity.id, { cache: { valid: true } });
|
||||||
|
|
||||||
|
return cache;
|
||||||
|
},
|
||||||
get: () => this.cache.text.get(entity.id),
|
get: () => this.cache.text.get(entity.id),
|
||||||
set: (id, cache) => this.cache.text.set(id, cache),
|
set: (id, cache) => this.cache.text.set(id, cache),
|
||||||
cleanup: (cache) => {
|
cleanup: (cache) => {
|
||||||
@ -245,7 +252,7 @@ export class Drawer {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.isLocked = false;
|
this.isLocked = false;
|
||||||
console.timeEnd("draw");
|
//console.timeEnd("draw");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,82 +203,86 @@ export default function drawStaggeredText(
|
|||||||
|
|
||||||
buildPaintStyle(CanvasKit, paint, entity.letter.paint);
|
buildPaintStyle(CanvasKit, paint, entity.letter.paint);
|
||||||
|
|
||||||
// Draw all those runs.
|
if (glyphs) {
|
||||||
for (let i = 0; i < measuredLetters.length; i++) {
|
// Draw all those runs.
|
||||||
const measuredLetter = measuredLetters[i];
|
for (let i = 0; i < measuredLetters.length; i++) {
|
||||||
|
const measuredLetter = measuredLetters[i];
|
||||||
|
|
||||||
const glyph = glyphs.subarray(i, i + 1);
|
const glyph = glyphs.subarray(i, i + 1);
|
||||||
|
|
||||||
const blob = CanvasKit.TextBlob.MakeFromGlyphs(
|
const blob = CanvasKit.TextBlob.MakeFromGlyphs(
|
||||||
glyph as unknown as Array<number>,
|
glyph as unknown as Array<number>,
|
||||||
font
|
font
|
||||||
);
|
);
|
||||||
if (blob) {
|
if (blob) {
|
||||||
canvas.save();
|
canvas.save();
|
||||||
|
|
||||||
const width = measuredLetters
|
const width = measuredLetters
|
||||||
.filter((letter) => letter.line === 0)
|
.filter((letter) => letter.line === 0)
|
||||||
.reduce((prev, curr) => curr.bounds.x_advance + prev, 0);
|
.reduce((prev, curr) => curr.bounds.x_advance + prev, 0);
|
||||||
|
|
||||||
const lineOffset = (entity.letter.paint.size / 2) * measuredLetter.line;
|
const lineOffset = (entity.letter.paint.size / 2) * measuredLetter.line;
|
||||||
|
|
||||||
const entityOrigin = [
|
const entityOrigin = [
|
||||||
entity.origin[0] - width / 2,
|
entity.origin[0] - width / 2,
|
||||||
entity.origin[1] + lineOffset,
|
entity.origin[1] + lineOffset,
|
||||||
];
|
];
|
||||||
|
|
||||||
const lineCount = measuredLetters
|
const lineCount = measuredLetters
|
||||||
.map((e) => e.line)
|
.map((e) => e.line)
|
||||||
.sort((a, b) => a - b)[measuredLetters.length - 1];
|
.sort((a, b) => a - b)[measuredLetters.length - 1];
|
||||||
|
|
||||||
if (entity.letter.transform && entity.letter.transform[i]) {
|
if (entity.letter.transform && entity.letter.transform[i]) {
|
||||||
const letterTransform = entity.letter.transform[i];
|
const letterTransform = entity.letter.transform[i];
|
||||||
const letterOrigin = [0, 0];
|
const letterOrigin = [0, 0];
|
||||||
|
|
||||||
let origin = letterOrigin.map(
|
let origin = letterOrigin.map(
|
||||||
(val, index) => val + entityOrigin[index]
|
(val, index) => val + entityOrigin[index]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Calculate the spacing
|
// Calculate the spacing
|
||||||
|
|
||||||
const spacing =
|
const spacing =
|
||||||
measuredLetter.bounds.x_advance - measuredLetter.bounds.width;
|
measuredLetter.bounds.x_advance - measuredLetter.bounds.width;
|
||||||
|
|
||||||
//console.log(spacing);
|
//console.log(spacing);
|
||||||
|
|
||||||
// Center the origin
|
// Center the origin
|
||||||
|
|
||||||
origin[0] =
|
origin[0] =
|
||||||
origin[0] + measuredLetter.bounds.width / 2 + measuredLetter.offset.x;
|
origin[0] +
|
||||||
origin[1] = origin[1] - metrics.descent + lineOffset;
|
measuredLetter.bounds.width / 2 +
|
||||||
|
measuredLetter.offset.x;
|
||||||
|
origin[1] = origin[1] - metrics.descent + lineOffset;
|
||||||
|
|
||||||
//console.log(measuredLetter.bounds);
|
//console.log(measuredLetter.bounds);
|
||||||
|
|
||||||
canvas.translate(origin[0], origin[1]);
|
canvas.translate(origin[0], origin[1]);
|
||||||
|
|
||||||
canvas.scale(letterTransform.scale[0], letterTransform.scale[1]);
|
canvas.scale(letterTransform.scale[0], letterTransform.scale[1]);
|
||||||
|
|
||||||
canvas.translate(
|
canvas.translate(
|
||||||
-origin[0] + measuredLetter.offset.x,
|
-origin[0] + measuredLetter.offset.x,
|
||||||
-origin[1] + lineOffset
|
-origin[1] + lineOffset
|
||||||
);
|
);
|
||||||
|
|
||||||
/* canvas.translate(
|
/* canvas.translate(
|
||||||
measuredLetter.offset.x + measuredLetter.bounds.width / 2,
|
measuredLetter.offset.x + measuredLetter.bounds.width / 2,
|
||||||
0
|
0
|
||||||
); */
|
); */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* canvas.translate(
|
/* canvas.translate(
|
||||||
width * -0.5,
|
width * -0.5,
|
||||||
lineCount * (-entity.letter.paint.size / 2)
|
lineCount * (-entity.letter.paint.size / 2)
|
||||||
); */
|
); */
|
||||||
|
|
||||||
canvas.drawTextBlob(blob, entityOrigin[0], entityOrigin[1], paint);
|
canvas.drawTextBlob(blob, entityOrigin[0], entityOrigin[1], paint);
|
||||||
|
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
|
|
||||||
blob.delete();
|
blob.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,6 +138,7 @@ function buildText(
|
|||||||
type: "Fill",
|
type: "Fill",
|
||||||
color,
|
color,
|
||||||
},
|
},
|
||||||
|
fontName: "Arial",
|
||||||
size,
|
size,
|
||||||
align: "Center",
|
align: "Center",
|
||||||
},
|
},
|
||||||
@ -202,6 +203,7 @@ function buildStaggeredText(
|
|||||||
stagger: 0.05,
|
stagger: 0.05,
|
||||||
letter: {
|
letter: {
|
||||||
paint: {
|
paint: {
|
||||||
|
fontName: "Arial",
|
||||||
style: {
|
style: {
|
||||||
type: "Fill",
|
type: "Fill",
|
||||||
color,
|
color,
|
||||||
|
@ -35,7 +35,7 @@ export const Paint = z.object({
|
|||||||
export const TextPaint = z.object({
|
export const TextPaint = z.object({
|
||||||
style: PaintStyle,
|
style: PaintStyle,
|
||||||
align: TextAlign,
|
align: TextAlign,
|
||||||
fontName: z.string().default("Helvetica-Bold"),
|
fontName: z.string(),
|
||||||
size: z.number().min(0),
|
size: z.number().min(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -28,10 +28,9 @@ export class DependenciesService {
|
|||||||
) {
|
) {
|
||||||
const fontNames = new Set<string>();
|
const fontNames = new Set<string>();
|
||||||
|
|
||||||
entities.forEach((entity) => {
|
console.log(entities);
|
||||||
if (entity.type === EntityType.Enum.Text) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
entities.forEach((entity) => {
|
||||||
switch (entity.type) {
|
switch (entity.type) {
|
||||||
case EntityType.Enum.Text:
|
case EntityType.Enum.Text:
|
||||||
fontNames.add(entity.paint.fontName);
|
fontNames.add(entity.paint.fontName);
|
||||||
@ -62,22 +61,26 @@ export class DependenciesService {
|
|||||||
async loadFonts(fontNames: Set<string>) {
|
async loadFonts(fontNames: Set<string>) {
|
||||||
const resolveFonts: Array<Promise<void>> = [];
|
const resolveFonts: Array<Promise<void>> = [];
|
||||||
|
|
||||||
|
const loadFont = async (fontName: string) => {
|
||||||
|
return invoke("get_system_font", { fontName }).then((data) => {
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
const u8 = new Uint8Array(data as any);
|
||||||
|
const buffer = typedArrayToBuffer(u8);
|
||||||
|
this.dependencies.fonts.set(fontName, buffer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
fontNames.forEach((fontName) => {
|
fontNames.forEach((fontName) => {
|
||||||
if (!this.dependencies.fonts.has(fontName)) {
|
if (!this.dependencies.fonts.has(fontName)) {
|
||||||
resolveFonts.push(
|
resolveFonts.push(loadFont(fontName));
|
||||||
invoke("get_system_font", { fontName }).then((data) => {
|
|
||||||
if (Array.isArray(data)) {
|
|
||||||
const u8 = new Uint8Array(data as any);
|
|
||||||
const buffer = typedArrayToBuffer(u8);
|
|
||||||
this.dependencies.fonts.set(fontName, buffer);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all(resolveFonts);
|
await Promise.all(resolveFonts);
|
||||||
|
|
||||||
console.log(this.dependencies);
|
console.log(fontNames);
|
||||||
|
|
||||||
|
// console.log(this.dependencies);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,12 @@ export class PlaybackService {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEntitiesStore.subscribe((state) => {
|
||||||
|
if (!this.playing) {
|
||||||
|
this.seek();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.seek();
|
this.seek();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ interface FontsStore {
|
|||||||
|
|
||||||
const useFontsStore = create<FontsStore>((set) => ({
|
const useFontsStore = create<FontsStore>((set) => ({
|
||||||
fonts: [],
|
fonts: [],
|
||||||
setFonts: (fonts) => ({ fonts }),
|
setFonts: (fonts) => set({ fonts }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export { useFontsStore };
|
export { useFontsStore };
|
||||||
|
@ -7,7 +7,7 @@ interface TimelineStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const useTimelineStore = create<TimelineStore>((set) => ({
|
const useTimelineStore = create<TimelineStore>((set) => ({
|
||||||
fps: 120,
|
fps: 30,
|
||||||
size: [1280, 720],
|
size: [1280, 720],
|
||||||
duration: 10.0,
|
duration: 10.0,
|
||||||
}));
|
}));
|
||||||
|
@ -72,6 +72,7 @@ body,
|
|||||||
#root {
|
#root {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.SliderRoot {
|
.SliderRoot {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user