[WIP] Initial implem of fade animating elements.

This commit is contained in:
barnabasmolnar
2026-06-02 19:06:32 +02:00
parent c08be69618
commit f472af04a9
9 changed files with 327 additions and 23 deletions
@@ -1,4 +1,5 @@
"use client";
import * as excalidrawLib from "@excalidraw/excalidraw";
import { Excalidraw } from "@excalidraw/excalidraw";
@@ -13,6 +14,7 @@ const ExcalidrawWrapper: React.FC = () => {
appTitle={"Excalidraw with Nextjs Example"}
useCustom={(api: any, args?: any[]) => {}}
excalidrawLib={excalidrawLib}
showFadeDemo={true}
>
<Excalidraw />
</App>
@@ -70,6 +70,7 @@ export interface AppProps {
customArgs?: any[];
children: React.ReactNode;
excalidrawLib: typeof TExcalidraw;
showFadeDemo?: boolean;
}
export default function ExampleApp({
@@ -78,6 +79,7 @@ export default function ExampleApp({
customArgs,
children,
excalidrawLib,
showFadeDemo = false,
}: AppProps) {
const {
exportToCanvas,
@@ -116,6 +118,8 @@ export default function ExampleApp({
{},
);
const [comment, setComment] = useState<Comment | null>(null);
const [hideAllForFadeDemo, setHideAllForFadeDemo] = useState(showFadeDemo);
const [fadeDemoNextIndex, setFadeDemoNextIndex] = useState(0);
const initialStatePromiseRef = useRef<{
promise: ResolvablePromise<ExcalidrawInitialDataState | null>;
@@ -178,7 +182,8 @@ export default function ExampleApp({
const newElement = cloneElement(
Excalidraw,
{
excalidrawAPI: (api: ExcalidrawImperativeAPI) => setExcalidrawAPI(api),
onExcalidrawAPI: (api: ExcalidrawImperativeAPI | null) =>
setExcalidrawAPI(api),
initialData: initialStatePromiseRef.current.promise,
onChange: (
elements: NonDeletedExcalidrawElement[],
@@ -208,6 +213,7 @@ export default function ExampleApp({
onPointerDown,
onScrollChange: rerenderCommentIcons,
validateEmbeddable: true,
resolveRenderOpacity: hideAllForFadeDemo ? () => 0 : undefined,
},
<>
{excalidrawAPI && (
@@ -664,6 +670,58 @@ export default function ExampleApp({
>
Reset Scene
</button>
{showFadeDemo && (
<>
<button
onClick={() => {
if (!excalidrawAPI) {
return;
}
const elements = excalidrawAPI.getSceneElements();
if (!elements.length) {
return;
}
setHideAllForFadeDemo(true);
const nextIndex =
fadeDemoNextIndex >= elements.length
? 0
: fadeDemoNextIndex;
if (nextIndex === 0) {
excalidrawAPI.clearElementOpacityOverrides();
}
console.info("Fading in element", {
element: elements[nextIndex],
});
excalidrawAPI.fadeElement({
id: elements[nextIndex].id,
from: 0,
to: 100,
duration: 500,
});
setFadeDemoNextIndex(nextIndex + 1);
}}
>
Fade in next element
</button>
<button
onClick={() => {
excalidrawAPI?.clearElementOpacityOverrides();
setHideAllForFadeDemo(true);
setFadeDemoNextIndex(0);
}}
>
Reset fade demo
</button>
</>
)}
<button
onClick={() => {
const libraryItems: LibraryItems = [
+35 -13
View File
@@ -2,6 +2,28 @@ import type { ExcalidrawElementSkeleton } from "@excalidraw/excalidraw/element/t
import type { FileId } from "@excalidraw/excalidraw/element/types";
const elements: ExcalidrawElementSkeleton[] = [
// {
// type: "arrow",
// x: 100,
// y: 500,
// },
// {
// type: "arrow",
// x: 250,
// y: 250,
// label: {
// text: "HELLO WORLD!!",
// },
// start: {
// type: "rectangle",
// // x: -100,
// },
// end: {
// type: "ellipse",
// // x: 300,
// },
// },
{
type: "rectangle",
x: 10,
@@ -22,14 +44,14 @@ const elements: ExcalidrawElementSkeleton[] = [
},
id: "2",
},
{
type: "arrow",
x: 100,
y: 200,
label: { text: "HELLO WORLD!!" },
start: { type: "rectangle" },
end: { type: "ellipse" },
},
// {
// type: "arrow",
// x: 100,
// y: 200,
// label: { text: "HELLO WORLD!!" },
// start: { type: "rectangle" },
// end: { type: "ellipse" },
// },
{
type: "image",
x: 606.1042326312408,
@@ -38,11 +60,11 @@ const elements: ExcalidrawElementSkeleton[] = [
height: 230,
fileId: "rocket" as FileId,
},
{
type: "frame",
children: ["1", "2"],
name: "My frame",
},
// {
// type: "frame",
// children: ["1", "2"],
// name: "My frame",
// },
];
export default {
elements,