mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-20 17:02:53 -04:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe4e6437cf | ||
|
|
03f32d7dd8 | ||
|
|
eefbbcad51 | ||
|
|
b60b9bff6c | ||
|
|
0e439c930b | ||
|
|
24599c858b | ||
|
|
f2fdc9b72e | ||
|
|
5c9dd400c8 | ||
|
|
d511ca2256 | ||
|
|
fa4d59de25 | ||
|
|
66ed9760e7 | ||
|
|
bead8db275 |
Generated
-10
@@ -4525,8 +4525,6 @@
|
||||
},
|
||||
"node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
@@ -5267,8 +5265,6 @@
|
||||
},
|
||||
"node_modules/npm/node_modules/cross-spawn/node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "ISC",
|
||||
@@ -5317,8 +5313,6 @@
|
||||
},
|
||||
"node_modules/npm/node_modules/debug/node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT"
|
||||
@@ -7145,8 +7139,6 @@
|
||||
},
|
||||
"node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
@@ -7184,8 +7176,6 @@
|
||||
},
|
||||
"node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
|
||||
@@ -3,8 +3,10 @@ import { Container } from "konva/lib/Container";
|
||||
import { Shape } from "konva/lib/Shape";
|
||||
import { Group } from "konva/lib/Group";
|
||||
|
||||
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
|
||||
import { FileUtilities } from "../FileUtilities/FileUtilities";
|
||||
import { ImageNode, VideoNode, TextNode } from "../Nodes";
|
||||
import { MediaNode } from "../types";
|
||||
@@ -266,6 +268,7 @@ export class RealTimeDrawEngine {
|
||||
});
|
||||
return canvas;
|
||||
}
|
||||
|
||||
public isProcessing = false;
|
||||
private handleNodeDragEnd = async () => {
|
||||
// Clean up any existing state
|
||||
@@ -376,6 +379,8 @@ export class RealTimeDrawEngine {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async imageBitmapToBase64(imageBitmap: ImageBitmap): Promise<string> {
|
||||
// Create a temporary canvas
|
||||
const canvas = document.createElement("canvas");
|
||||
|
||||
@@ -23,6 +23,8 @@ import { useLayoutContext } from "./contextSignals/layout";
|
||||
import { useRenderCounter } from "~/hooks/useRenderCounter";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { SignaledMagicBox } from "./SignaledMagicBox";
|
||||
import { SignaledPromptSlider } from "./SignaledPromptSlider";
|
||||
import { SignaledPromptText } from "./SignaledPromptText";
|
||||
|
||||
export const KonvaRootComponent = ({
|
||||
className,
|
||||
@@ -54,13 +56,15 @@ export const KonvaRootComponent = ({
|
||||
<KonvaCanvasContainer
|
||||
ref={konvaContainerCallbackRef}
|
||||
className={className}
|
||||
// retreive the classNames from the parent for sizing/styling
|
||||
// retreive the classNames from the parent for sizing/styling
|
||||
/>
|
||||
<SignaledMagicBox />
|
||||
<SignaledCanvasDragDropFiles
|
||||
openAddImage={appUiContext.openAddImage}
|
||||
openAddVideo={appUiContext.openAddVideo}
|
||||
/>
|
||||
<SignaledPromptSlider />
|
||||
<SignaledPromptText />
|
||||
<SignaledToolbarMain
|
||||
layoutSignal={layoutContext.signal}
|
||||
appUiContext={appUiContext}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
import { useSignalEffect } from "@preact/signals-react";
|
||||
import { Slider } from "~/components/ui"
|
||||
import { dispatchUiEvents } from "~/signals"
|
||||
import { promptStrength } from "~/signals/uiEvents/promptSettings";
|
||||
|
||||
export const SignaledPromptSlider = () => {
|
||||
|
||||
const sliderValue = promptStrength.value
|
||||
const onSliderValueChanged = dispatchUiEvents.promptSettings.setPromptStrength
|
||||
|
||||
// This makes component re-render whenever the signal value changes
|
||||
useSignalEffect(() => {
|
||||
promptStrength.value;
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-96 left-1/2 -translate-x-1/2 h-4 w-48">
|
||||
<Slider min={0} max={100} value={sliderValue} onChange={onSliderValueChanged} step={1} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { useSignalEffect } from "@preact/signals-react";
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { ResizeType, Textarea } from "~/components/ui";
|
||||
import { dispatchUiEvents } from "~/signals";
|
||||
import { promptText } from "~/signals/uiEvents/promptSettings";
|
||||
|
||||
export const SignaledPromptText = ({
|
||||
}) => {
|
||||
const textAreaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const focusOnTextArea = useCallback(() => {
|
||||
if (textAreaRef.current === null) {
|
||||
return;
|
||||
}
|
||||
textAreaRef.current.focus();
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
focusOnTextArea();
|
||||
}, []);
|
||||
|
||||
const TextAreaStates = {
|
||||
style: {
|
||||
width: "500px",
|
||||
height: "240px",
|
||||
},
|
||||
placeholder: "...",
|
||||
label: "Prompt Text",
|
||||
resize: "none" as ResizeType,
|
||||
};
|
||||
|
||||
const textContent = promptText.value;
|
||||
const onTextChanged = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
dispatchUiEvents.promptSettings.setPrompt(event.target.value);
|
||||
};
|
||||
|
||||
// This makes component re-render whenever the signal value changes
|
||||
useSignalEffect(() => {
|
||||
promptText.value;
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-24 left-1/2 -translate-x-1/2">
|
||||
<Textarea {...TextAreaStates} ref={textAreaRef} onChange={onTextChanged} value={textContent} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -7,10 +7,16 @@ export type ResizeType =
|
||||
| "both"
|
||||
| "horizontal"
|
||||
| "vertical"
|
||||
| "block"
|
||||
| "inline"
|
||||
| undefined;
|
||||
|
||||
const resizeStyles = {
|
||||
none: "resize-none",
|
||||
both: "resize",
|
||||
horizontal: "resize-x",
|
||||
vertical: "resize-y",
|
||||
undefined: "",
|
||||
}
|
||||
|
||||
export interface TextareaInterface
|
||||
extends TextareaHTMLAttributes<HTMLTextAreaElement> {
|
||||
label?: string;
|
||||
@@ -21,6 +27,9 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaInterface>(
|
||||
{ className, label, resize = "vertical", id, ...rest }: TextareaInterface,
|
||||
ref,
|
||||
) => {
|
||||
|
||||
const resizeStyle = resizeStyles[resize];
|
||||
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
{label && <label htmlFor={id ? id : kebabCase(label)}>{label}</label>}
|
||||
@@ -31,11 +40,11 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaInterface>(
|
||||
className={twMerge(
|
||||
"border-ui-panel-border bg-ui-controls rounded-lg border px-3 py-2",
|
||||
className,
|
||||
resizeStyle,
|
||||
)}
|
||||
style={{
|
||||
outline: "2px solid transparent",
|
||||
transition: "outline-color 0.15s ease-in-out",
|
||||
resize: resize,
|
||||
}}
|
||||
onFocus={(e) => {
|
||||
// disableHotkeyInput(DomLevels.INPUT);
|
||||
|
||||
@@ -24,6 +24,10 @@ import {
|
||||
dispatchers as toolbarVideoExtractionDispatchers,
|
||||
eventsHandlers as toolbarVideoExtractionEvents,
|
||||
} from "./toolbarVideoExtraction";
|
||||
import {
|
||||
dispatchers as promptDispatchers,
|
||||
events as promptEvents,
|
||||
} from "./promptSettings";
|
||||
|
||||
export const uiEvents = {
|
||||
...addMediaEvents,
|
||||
@@ -34,6 +38,7 @@ export const uiEvents = {
|
||||
toolbarMain: toolbarMainEvents,
|
||||
toolbarNode: toolbarNodeEvents,
|
||||
toolbarVideoExtraction: toolbarVideoExtractionEvents,
|
||||
promptEvents: promptEvents,
|
||||
};
|
||||
export const dispatchUiEvents = {
|
||||
...addMediaDispatchers,
|
||||
@@ -44,4 +49,5 @@ export const dispatchUiEvents = {
|
||||
toolbarMain: toolbarMainDispatchers,
|
||||
toolbarNode: toolbarNodeDispatchers,
|
||||
toolbarVideoExtraction: toolbarVideoExtractionDispatchers,
|
||||
promptSettings: promptDispatchers,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { effect, signal } from "@preact/signals-react";
|
||||
|
||||
// Prompt settings
|
||||
// - Prompt text
|
||||
// - Prompt strength
|
||||
export const DEFAULT_PROMPT_TEXT: string = "";
|
||||
export const promptText = signal<string>(DEFAULT_PROMPT_TEXT);
|
||||
const setPrompt = (data: string) => {
|
||||
promptText.value = data;
|
||||
};
|
||||
|
||||
const onPromptTextChanged = (callback: (data: string) => void) => {
|
||||
effect(() => {
|
||||
if (promptText.value) {
|
||||
callback(promptText.value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const DEFAULT_PROMPT_STRENGTH = 100;
|
||||
export const promptStrength = signal<number>(DEFAULT_PROMPT_STRENGTH);
|
||||
const setPromptStrength = (data: number) => {
|
||||
// Round to integer, then clamp between 0 and 100
|
||||
promptStrength.value = Math.max(0, Math.min(100, Math.round(data)));
|
||||
};
|
||||
|
||||
const onPromptStrengthChanged = (callback: (data: number) => void) => {
|
||||
effect(() => {
|
||||
if (promptStrength.value) {
|
||||
callback(promptStrength.value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//EXPORTS
|
||||
export const dispatchers = {
|
||||
setPrompt,
|
||||
setPromptStrength,
|
||||
};
|
||||
|
||||
export const events = {
|
||||
onPromptTextChanged,
|
||||
onPromptStrengthChanged,
|
||||
};
|
||||
Reference in New Issue
Block a user