fix: preview + aspect ratio
This commit is contained in:
@@ -23,6 +23,7 @@ export function AvatarEditor() {
|
||||
id: 'avatech-editor-iframe',
|
||||
title: 'avatech-editor-iframe',
|
||||
name: 'avatech-editor-iframe',
|
||||
crossorigin: "anonymous",
|
||||
class: () =>
|
||||
'w-full h-full pointer-events-auto ' + (showEditor.val ? '' : 'hidden'),
|
||||
src: iframeSrc,
|
||||
|
||||
+14
-10
@@ -1,18 +1,22 @@
|
||||
import { van } from './van.js'
|
||||
const { button, iframe, div, img } = van.tags
|
||||
import { van } from "./van.js";
|
||||
const { button, iframe, div, img } = van.tags;
|
||||
|
||||
export function AvatarViewer() {
|
||||
return div(
|
||||
{
|
||||
class: 'w-[310px] h-[310px] absolute right-0 top-0 z-[100] pointer-events-auto mt-4 mr-4',
|
||||
class:
|
||||
"w-[310px] h-[310px] absolute right-0 top-0 z-[100] pointer-events-auto mt-4 mr-4",
|
||||
},
|
||||
iframe({
|
||||
id: 'avatech-viewer-iframe',
|
||||
title: 'avatech-viewer-iframe',
|
||||
name: 'avatech-viewer-iframe',
|
||||
class: () => 'w-full h-full flex pointer-events-auto rounded-2xl border-none',
|
||||
src: 'https://labs.avatech.ai/viewer/default',
|
||||
// src: 'http://localhost:3000/viewer/default',
|
||||
id: "avatech-viewer-iframe",
|
||||
title: "avatech-viewer-iframe",
|
||||
name: "avatech-viewer-iframe",
|
||||
allow: "cross-origin-isolated",
|
||||
sandbox: "true",
|
||||
class: () =>
|
||||
"w-full h-full flex pointer-events-auto rounded-2xl border-none",
|
||||
// src: "https://labs.avatech.ai/viewer/default",
|
||||
src: 'http://localhost:3000/viewer/default',
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
+43
-19
@@ -15,7 +15,9 @@ import {
|
||||
import { van } from "./van.js";
|
||||
const { button, div, img, canvas } = van.tags;
|
||||
|
||||
function updateImagePrompts() {
|
||||
let throttle = false;
|
||||
|
||||
export function updateImagePrompts() {
|
||||
if (selectedLayer.val !== "" && selectedLayer.val !== undefined) {
|
||||
imagePromptsMulti.val = {
|
||||
...imagePromptsMulti.val,
|
||||
@@ -36,10 +38,11 @@ function handleClick(e) {
|
||||
const x = e.clientX - rect.left;
|
||||
const y = e.clientY - rect.top;
|
||||
const relativeX = Math.trunc(
|
||||
(x / e.target.offsetWidth) * imageSize.val.width
|
||||
((x / e.target.offsetWidth) * imageSize.val.width) / imageSize.val.samScale
|
||||
);
|
||||
const relativeY = Math.trunc(
|
||||
(y / e.target.offsetHeight) * imageSize.val.height
|
||||
((y / e.target.offsetHeight) * imageSize.val.height) /
|
||||
imageSize.val.samScale
|
||||
);
|
||||
|
||||
imagePrompts.val = [
|
||||
@@ -67,12 +70,13 @@ function handleImageSize(image) {
|
||||
return { height: h, width: w, samScale };
|
||||
}
|
||||
|
||||
initModel();
|
||||
|
||||
export function ImageEditor() {
|
||||
initModel();
|
||||
return div(
|
||||
{
|
||||
class: () =>
|
||||
"absolute flex bg-gray-900 bg-opacity-50 top-0 w-full h-full pointer-events-auto" +
|
||||
"absolute flex bg-gray-900 bg-opacity-50 top-0 w-full h-full pointer-events-auto " +
|
||||
(showImageEditor.val ? "" : "hidden"),
|
||||
},
|
||||
button(
|
||||
@@ -112,6 +116,7 @@ export function ImageEditor() {
|
||||
div(
|
||||
{
|
||||
class: "flex items-center justify-center w-full h-full",
|
||||
id: "image-container",
|
||||
},
|
||||
img({
|
||||
class:
|
||||
@@ -120,6 +125,9 @@ export function ImageEditor() {
|
||||
onload: (e) => {
|
||||
imageSize.val = handleImageSize(e.target);
|
||||
|
||||
document.getElementById("image-container").style.scale =
|
||||
imageSize.val.samScale;
|
||||
|
||||
imageContainerSize.val = {
|
||||
width: e.target.offsetWidth,
|
||||
height: e.target.offsetHeight,
|
||||
@@ -138,24 +146,40 @@ export function ImageEditor() {
|
||||
handleClick(e);
|
||||
},
|
||||
onmousemove: (e) => {
|
||||
// console.log('Yo', e);
|
||||
if (!throttle) {
|
||||
throttle = true;
|
||||
setTimeout(() => {
|
||||
throttle = false;
|
||||
|
||||
if (embeddings.val) {
|
||||
const rect = e.target.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
const y = e.clientY - rect.top;
|
||||
const relativeX = Math.trunc(
|
||||
((x / e.target.offsetWidth) * imageSize.val.width) /
|
||||
imageSize.val.samScale
|
||||
);
|
||||
const relativeY = Math.trunc(
|
||||
((y / e.target.offsetHeight) * imageSize.val.height) /
|
||||
imageSize.val.samScale
|
||||
);
|
||||
|
||||
const clicks = [{ x: relativeX, y: relativeY, clickType: 1 }];
|
||||
runONNX(clicks, embeddings.val).then((mask) => {
|
||||
const canvas = document.getElementById("mask-canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.drawImage(mask, 0, 0);
|
||||
});
|
||||
}
|
||||
}, 10);
|
||||
}
|
||||
},
|
||||
}),
|
||||
canvas({
|
||||
class:
|
||||
"fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2",
|
||||
"pointer-events-none fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 opacity-80",
|
||||
id: "mask-canvas",
|
||||
onclick: (e) => {
|
||||
if (embeddings.val) {
|
||||
const clicks = [{ x: e.clientX, y: e.clientY, clickType: 1 }];
|
||||
runONNX(clicks, embeddings.val).then((mask) => {
|
||||
const canvas = document.getElementById("mask-canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.drawImage(mask, 0, 0);
|
||||
});
|
||||
}
|
||||
},
|
||||
}),
|
||||
() => {
|
||||
return div(
|
||||
@@ -164,7 +188,7 @@ export function ImageEditor() {
|
||||
style: () =>
|
||||
`width: ${imageContainerSize.val.width}px; height: ${imageContainerSize.val.height}px;`,
|
||||
},
|
||||
...imagePrompts.val.map((point) => {
|
||||
...imagePrompts.val?.map((point) => {
|
||||
return button({
|
||||
style: () =>
|
||||
`left: ${
|
||||
|
||||
+28
-5
@@ -1,4 +1,10 @@
|
||||
import { imagePrompts, selectedLayer, imagePromptsMulti, targetNode } from "./state.js";
|
||||
import { updateImagePrompts } from "./ImageEditor.js";
|
||||
import {
|
||||
imagePrompts,
|
||||
selectedLayer,
|
||||
imagePromptsMulti,
|
||||
targetNode,
|
||||
} from "./state.js";
|
||||
import { van } from "./van.js";
|
||||
const {
|
||||
button,
|
||||
@@ -20,7 +26,7 @@ export function SideBar() {
|
||||
return div(
|
||||
{
|
||||
class:
|
||||
"z-100 w-fit flex-col flex justify-center absolute top-0 left-0 bottom-0 items-start gap-2",
|
||||
"ml-2 z-100 w-fit flex-col flex justify-center absolute top-0 left-0 bottom-0 items-start gap-2",
|
||||
},
|
||||
|
||||
() => {
|
||||
@@ -72,6 +78,7 @@ export function SideBar() {
|
||||
{ class: "modal-box text-base-content" },
|
||||
form(
|
||||
{
|
||||
class: "gap-2 flex flex-col",
|
||||
method: "dialog",
|
||||
onsubmit: (e) => {
|
||||
e.preventDefault();
|
||||
@@ -83,7 +90,16 @@ export function SideBar() {
|
||||
console.log(inputText, imagePromptsMulti.val);
|
||||
my_modal_3.close();
|
||||
e.target.elements[1].value = "";
|
||||
targetNode.val.addInput(inputText, "SAM_PROMPT")
|
||||
targetNode.val.addOutput(inputText, "SAM_PROMPT");
|
||||
targetNode.val.graph.change();
|
||||
if (
|
||||
selectedLayer.val === null ||
|
||||
selectedLayer.val === undefined ||
|
||||
selectedLayer.val === ""
|
||||
) {
|
||||
selectedLayer.val = inputText;
|
||||
}
|
||||
updateImagePrompts();
|
||||
},
|
||||
},
|
||||
button(
|
||||
@@ -104,9 +120,16 @@ export function SideBar() {
|
||||
input({
|
||||
type: "text",
|
||||
placeholder: "Type here",
|
||||
class: "input input-bordered w-full max-w-xs",
|
||||
class: "input input-bordered w-full",
|
||||
autofocus: true,
|
||||
})
|
||||
}),
|
||||
button(
|
||||
{
|
||||
type: "submit",
|
||||
class: "btn btn-sm btn-ghost place-self-end",
|
||||
},
|
||||
"Confirm"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ export const loadNpyTensor = async (tensorFile, dType = "float32") => {
|
||||
};
|
||||
|
||||
export const runONNX = async (clicks, tensor) => {
|
||||
console.log('tensor', tensor);
|
||||
// console.log('tensor', tensor);
|
||||
try {
|
||||
if (
|
||||
model === null ||
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+8
-2
@@ -33,9 +33,15 @@ class SAM_Prompt_Image:
|
||||
|
||||
image_prompts = json.loads(image_prompts_json)
|
||||
|
||||
print(image_prompts)
|
||||
result = (image_prompts, )
|
||||
|
||||
return (image_prompts, )
|
||||
if isinstance(image_prompts, list):
|
||||
pass
|
||||
elif all(isinstance(item, list) for item in image_prompts.values()):
|
||||
for item in image_prompts.values():
|
||||
result.extend(item)
|
||||
|
||||
return result
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"SAM_Prompt_Image": SAM_Prompt_Image
|
||||
|
||||
Reference in New Issue
Block a user