Skip to content

Commit

Permalink
feat(docs): autoplay visible fiddles (#1001)
Browse files Browse the repository at this point in the history
  • Loading branch information
aarthificial committed Mar 20, 2024
1 parent aa871a1 commit 109d84e
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 18 deletions.
90 changes: 78 additions & 12 deletions packages/docs/src/components/Fiddle/SharedPlayer.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
import {parser as javascript} from '@lezer/javascript';
import {parser as rust} from '@lezer/rust';
import type {View2D} from '@motion-canvas/2d';
Expand All @@ -9,16 +10,75 @@ import type {
ThreadGeneratorFactory,
} from '@motion-canvas/core';

type Setter = (value: PlayerType) => void;

interface Config {
setter: Setter;
parent: HTMLDivElement;
ratio: number;
onError?: (message: string) => void;
onBorrow: Setter;
}

const VisiblePlayers = new Map<HTMLDivElement, number>();
const ConfigMap = new Map<Setter, Config>();

const Observer = ExecutionEnvironment.canUseDOM
? new IntersectionObserver(
entries => {
for (const entry of entries) {
const target = entry.target as HTMLDivElement;
if (entry.isIntersecting) {
VisiblePlayers.set(target, entry.intersectionRatio);
} else {
VisiblePlayers.delete(target);
}
}

const current = VisiblePlayers.get(CurrentParent);
if (current !== undefined && current > 0.75) return;

let bestRatio = 0;
let bestConfig: Config = null;
for (const config of ConfigMap.values()) {
const visible = VisiblePlayers.get(config.parent);
if (visible !== undefined && visible > bestRatio) {
bestRatio = visible;
bestConfig = config;
}
}

if (bestConfig && (current === undefined || bestRatio > current)) {
borrowPlayer(
bestConfig.setter,
bestConfig.parent,
bestConfig.ratio,
bestConfig.onError,
).then(bestConfig.onBorrow);
}
},
{
threshold: [0, 0.25, 0.5, 0.75, 1],
},
)
: null;

let ProjectInstance: Project = null;
let Description: FullSceneDescription<ThreadGeneratorFactory<View2D>> = null;
let PlayerInstance: PlayerType = null;
let StageInstance: StageType = null;
let CurrentSetter: (value: PlayerType) => void = null;
let CurrentParent: HTMLElement = null;
let CurrentSetter: Setter = null;
let CurrentParent: HTMLDivElement = null;
let CurrentRatio = 1;
let ErrorHandler: (message: string) => void = null;

export function disposePlayer(setter: (value: PlayerType) => void) {
export function disposePlayer(setter: Setter) {
const config = ConfigMap.get(setter);
if (config) {
Observer?.unobserve(config.parent);
ConfigMap.delete(setter);
}

if (CurrentSetter !== setter || !ProjectInstance) return;
PlayerInstance.deactivate();
CurrentSetter = null;
Expand All @@ -33,7 +93,7 @@ export function updatePlayer(description: typeof Description) {
}

export async function borrowPlayer(
setter: (value: PlayerType) => void,
setter: Setter,
parent: HTMLDivElement,
ratio: number,
onError?: (message: string) => void,
Expand Down Expand Up @@ -125,15 +185,21 @@ export async function borrowPlayer(
return PlayerInstance;
}

export async function tryBorrowPlayer(
setter: (value: PlayerType) => void,
export function tryBorrowPlayer(
setter: Setter,
parent: HTMLDivElement,
ratio: number,
onError?: (error: string) => void,
): Promise<PlayerType | null> {
if (!CurrentSetter) {
return borrowPlayer(setter, parent, ratio, onError);
onError: (error: string) => void,
onBorrow: Setter,
) {
if (!ConfigMap.has(setter)) {
Observer?.observe(parent);
ConfigMap.set(setter, {
setter,
parent,
ratio,
onError,
onBorrow,
});
}

return null;
}
14 changes: 8 additions & 6 deletions packages/docs/src/components/Fiddle/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,15 @@ export default function Fiddle({
});
foldImports(editorView.current);

tryBorrowPlayer(setPlayer, previewRef.current, parsedRatio, setError).then(
tryBorrowPlayer(
setPlayer,
previewRef.current,
parsedRatio,
setError,
async borrowed => {
if (borrowed) {
const success = await update(snippets[snippetId].state.doc, false);
if (success && mode !== 'code') {
borrowed.togglePlayback(true);
}
const success = await update(snippets[snippetId].state.doc, false);
if (success && mode !== 'code') {
borrowed.togglePlayback(true);
}
},
);
Expand Down

0 comments on commit 109d84e

Please sign in to comment.