mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-06 02:00:46 +00:00
breaking down the workflow controls page into smaller components for management, improve basicvideo so it forward the ref of the videoelement for more video operations
This commit is contained in:
1 parent
4114b6a92c
commit
fb015ee699
4 files changed
+204
-129
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, forwardRef } from "react";
|
||||
import { a, useSpring } from "@react-spring/web";
|
||||
import { useVideo } from "hooks";
|
||||
import makeClass from "resources/makeClass";
|
||||
@@ -13,12 +13,12 @@ interface Props {
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export default function BasicVideo({
|
||||
export default forwardRef(function BasicVideo({
|
||||
className,
|
||||
src,
|
||||
title,
|
||||
description
|
||||
}: Props) {
|
||||
description,
|
||||
}: Props, ref:React.ForwardedRef<HTMLVideoElement>) {
|
||||
const [tint,tintSet] = useState(true);
|
||||
const [{ playCtrl },vidProps] = useVideo({ onEnded: () => tintSet(true) });
|
||||
const style = useSpring({
|
||||
@@ -31,7 +31,7 @@ export default function BasicVideo({
|
||||
};
|
||||
|
||||
return <div {...{ ...makeClass("fy-basic-video",className) }}>
|
||||
<video {...{ playsInline: true, ...vidProps }}>
|
||||
<video {...{ playsInline: true, ...vidProps }} ref={ref}>
|
||||
<source {...{ src, type: "video/mp4" }} />
|
||||
</video>
|
||||
<a.div {...{ className: "video-overlay", onClick, style }}>
|
||||
@@ -40,4 +40,4 @@ export default function BasicVideo({
|
||||
<FontAwesomeIcon {...{ icon: faPlay }} />
|
||||
</a.div>
|
||||
</div>;
|
||||
};
|
||||
});
|
||||
+14
-123
@@ -1,4 +1,4 @@
|
||||
import React, {useState} from "react";
|
||||
import React, {useState, useRef} from "react";
|
||||
import { useParams, useHistory } from "react-router-dom";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { faChevronRight } from "@fortawesome/pro-solid-svg-icons";
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
BasicVideo,
|
||||
Checkbox,
|
||||
ErrorMessage,
|
||||
TempInput as Input,
|
||||
InputSeed,
|
||||
NumberSliderV2,
|
||||
Panel,
|
||||
@@ -23,6 +22,8 @@ import {
|
||||
TextArea
|
||||
} from "components/common";
|
||||
|
||||
import SectionControlNets, {ControlNetsInitialValues as CnIvs} from "./sectionControlNets";
|
||||
import SectionVideoSettings from "./sectionVideoSettings";
|
||||
|
||||
export default function PageFilterControls({
|
||||
t, pageState, dispatchPageState, parentPath
|
||||
@@ -34,6 +35,7 @@ export default function PageFilterControls({
|
||||
dispatchPageState: (action: Action) => void;
|
||||
}) {
|
||||
const { mediaToken } = useParams<any>();
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
useMedia({
|
||||
mediaToken: pageState.mediaFileToken || mediaToken,
|
||||
onSuccess: (res: any) => {
|
||||
@@ -43,7 +45,7 @@ export default function PageFilterControls({
|
||||
mediaFile: res,
|
||||
mediaFileToken: pageState.mediaFileToken || mediaToken
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -70,14 +72,7 @@ export default function PageFilterControls({
|
||||
nthFrames:2,
|
||||
inputFps: 24,
|
||||
interpolationMutiplier: 2,
|
||||
cnTile: 0,
|
||||
cnCanny: 0,
|
||||
cnLinearAnime: 0,
|
||||
cnLinearRealistic: 0,
|
||||
cnDepth: 0,
|
||||
cnOpenPose: 0,
|
||||
cnPipeFace: 0,
|
||||
cnSparse: 0.7,
|
||||
...CnIvs
|
||||
});
|
||||
|
||||
const handleOnChange = (key: string, newValue:any,) => {
|
||||
@@ -141,7 +136,7 @@ export default function PageFilterControls({
|
||||
<Panel>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-5">
|
||||
<BasicVideo src={mediaLink} />
|
||||
<BasicVideo src={mediaLink} ref={videoRef}/>
|
||||
</div>
|
||||
<div className="col-1 d-flex align-items-center justify-items-center">
|
||||
<FontAwesomeIcon icon={faChevronRight} className="fa-6x"/>
|
||||
@@ -335,119 +330,15 @@ export default function PageFilterControls({
|
||||
</div>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item title="Control Nets" defaultOpen>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: filterState.cnCanny,
|
||||
label: "Canny",
|
||||
thumbTip: "Canny",
|
||||
onChange: (val)=>{handleOnChange("cnCanny", val)}
|
||||
}}/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: filterState.cnLinearAnime,
|
||||
label: "Line Art Anime",
|
||||
thumbTip: "Line Art Anime",
|
||||
onChange: (val)=>{handleOnChange("cnLinearAnime", val)}
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: filterState.cnDepth,
|
||||
label: "Depth",
|
||||
thumbTip: "Depth",
|
||||
onChange: (val)=>{handleOnChange("cnDepth", val)}
|
||||
}}/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: filterState.cnOpenPose,
|
||||
label: "OpenPose",
|
||||
thumbTip: "OpenPose",
|
||||
onChange: (val)=>{handleOnChange("cnOpenPose", val)}
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: filterState.cnPipeFace,
|
||||
label: "Media Pipe Face",
|
||||
thumbTip: "Media Pipe Face",
|
||||
onChange: (val)=>{handleOnChange("cnPipeFace", val)}
|
||||
}}/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: filterState.cnSparse,
|
||||
label: "Sparse Scribble",
|
||||
thumbTip: "Sparse Scribble",
|
||||
onChange: (val)=>{handleOnChange("cnSparse", val)}
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: filterState.cnLinearRealistic,
|
||||
label: "Video CN (Linear Realistic)",
|
||||
thumbTip: "Video CN",
|
||||
onChange: (val)=>{handleOnChange("cnLinearRealistic", val)}
|
||||
}}/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: filterState.cnTile,
|
||||
label: "Tile CN",
|
||||
thumbTip: "Tile CN",
|
||||
onChange: (val)=>{handleOnChange("cnTile", val)}
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
<SectionControlNets
|
||||
onChange={(key,val)=>handleOnChange(key,val)}
|
||||
/>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item title="Video Settings">
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<Input label="Width"/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<Input label="Height" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<Input label="Frames Cap" />
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<Input label="Skip Frames" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<Input label="Every n-th Frame" />
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<Input label="Input FPS" readOnly/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<Input label="Interpolation Multiplier" />
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
</div>
|
||||
</div>
|
||||
<SectionVideoSettings
|
||||
onChange={(key,val)=>handleOnChange(key,val)}
|
||||
videoElement={videoRef?.current}
|
||||
/>
|
||||
</Accordion.Item>
|
||||
</Accordion>
|
||||
<div className="row g-3 py-3">
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import { NumberSliderV2 } from 'components/common'
|
||||
|
||||
export const ControlNetsInitialValues = {
|
||||
cnCanny: 0,
|
||||
cnDepth: 0,
|
||||
cnLinearAnime: 0,
|
||||
cnLinearRealistic: 0,
|
||||
cnOpenPose: 0,
|
||||
cnPipeFace: 0,
|
||||
cnSparse: 0.7,
|
||||
cnTile: 0,
|
||||
}
|
||||
|
||||
export default memo( function SectionControlNets(
|
||||
{onChange : handleOnChange} : {onChange: (key:string, val:number)=>void}
|
||||
){
|
||||
const iv = ControlNetsInitialValues;
|
||||
return(
|
||||
<>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: iv.cnCanny,
|
||||
label: "Canny",
|
||||
thumbTip: "Canny",
|
||||
onChange: (val)=>{handleOnChange("cnCanny", val)}
|
||||
}}/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: iv.cnLinearAnime,
|
||||
label: "Line Art Anime",
|
||||
thumbTip: "Line Art Anime",
|
||||
onChange: (val)=>{handleOnChange("cnLinearAnime", val)}
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: iv.cnDepth,
|
||||
label: "Depth",
|
||||
thumbTip: "Depth",
|
||||
onChange: (val)=>{handleOnChange("cnDepth", val)}
|
||||
}}/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: iv.cnOpenPose,
|
||||
label: "OpenPose",
|
||||
thumbTip: "OpenPose",
|
||||
onChange: (val)=>{handleOnChange("cnOpenPose", val)}
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: iv.cnPipeFace,
|
||||
label: "Media Pipe Face",
|
||||
thumbTip: "Media Pipe Face",
|
||||
onChange: (val)=>{handleOnChange("cnPipeFace", val)}
|
||||
}}/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: iv.cnSparse,
|
||||
label: "Sparse Scribble",
|
||||
thumbTip: "Sparse Scribble",
|
||||
onChange: (val)=>{handleOnChange("cnSparse", val)}
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: iv.cnLinearRealistic,
|
||||
label: "Video CN (Linear Realistic)",
|
||||
thumbTip: "Video CN",
|
||||
onChange: (val)=>{handleOnChange("cnLinearRealistic", val)}
|
||||
}}/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 0, max: 1, step: 0.1,
|
||||
initialValue: iv.cnTile,
|
||||
label: "Tile CN",
|
||||
thumbTip: "Tile CN",
|
||||
onChange: (val)=>{handleOnChange("cnTile", val)}
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
});
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
import React, { memo, useState } from 'react'
|
||||
|
||||
import { TempInput as Input } from 'components/common'
|
||||
|
||||
export const VideoSettingsInitialValues = {
|
||||
width: 544,
|
||||
height: 544,
|
||||
framesCap: 16,
|
||||
skipFrames: 0,
|
||||
everyNthFrame: 2,
|
||||
inputFps: 24,
|
||||
interpolationMultiplier: 2,
|
||||
}
|
||||
|
||||
export default memo( function SectionVideoSettings({
|
||||
onChange : handleOnChange,
|
||||
videoElement: ve
|
||||
} : {
|
||||
onChange: (key:string, val:number)=>void,
|
||||
videoElement: HTMLVideoElement | null,
|
||||
}){
|
||||
const iv = VideoSettingsInitialValues;
|
||||
const [{width, height}, setDimensions] = useState({
|
||||
width:iv.width, height:iv.height
|
||||
});
|
||||
if(ve && ve!==null){
|
||||
ve.onloadedmetadata = () =>{
|
||||
if (ve.videoWidth && ve.videoHeight) {
|
||||
const aspectRatio = ve.videoWidth/ve.videoHeight
|
||||
if (aspectRatio > 1){
|
||||
setDimensions({width: 960, height: iv.height});
|
||||
}
|
||||
else if (aspectRatio < 1) {
|
||||
setDimensions({width: iv.width, height: 960});
|
||||
}else{
|
||||
console.log(`aspectRaio: ${aspectRatio}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(
|
||||
<>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<Input label="Width" value={width} readOnly/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<Input label="Height" value={height} readOnly/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<Input label="Frames Cap" value={iv.framesCap} readOnly/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<Input label="Skip Frames" value={iv.skipFrames} readOnly/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<Input label="Every n-th Frame" value={iv.everyNthFrame} readOnly />
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<Input label="Input FPS" value={iv.inputFps} readOnly/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<Input
|
||||
label="Interpolation Multiplier"
|
||||
value={iv.interpolationMultiplier}
|
||||
readOnly
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user