feat(docs/hold-tap): Implement hold-tap comparison Motion Canvas Project

This commit is contained in:
Kurtis Lew 2023-02-10 10:12:19 -08:00
parent 4beab96f83
commit 60744c3181
9 changed files with 298 additions and 17 deletions

View file

@ -5,6 +5,7 @@ sidebar_label: Hold-Tap
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
import '@motion-canvas/player'
## Summary ## Summary
@ -18,6 +19,11 @@ The graph below shows how the hold-tap decides between a 'tap' and a 'hold'.
![Simple behavior](../assets/hold-tap/case1_2.svg) ![Simple behavior](../assets/hold-tap/case1_2.svg)
<motion-canvas-player
src={"/animations/hold_tap_comparison.js"}
auto={true}
/>
By default, the hold-tap is configured to also select the 'hold' functionality if another key is tapped while it's active: By default, the hold-tap is configured to also select the 'hold' functionality if another key is tapped while it's active:
![Hold preferred behavior](../assets/hold-tap/case_hold_preferred.svg) ![Hold preferred behavior](../assets/hold-tap/case_hold_preferred.svg)

View file

@ -0,0 +1,80 @@
import { Rect, Text, Node } from "@motion-canvas/2d/lib/components";
import { SignalValue } from "@motion-canvas/core/lib/signals";
import { makeRef } from "@motion-canvas/core/lib/utils";
const KeySize = 200;
const KeyRadius = 10;
export const KeyBorderThickness = 10;
export const KeyTravel = 40;
export default function Key({
refs,
binding,
params,
}: {
refs: {
group: Node;
body: Node;
fill: Rect;
duration: Rect;
shadow: Rect;
binding: Text;
params: Text;
};
binding: SignalValue<string>;
params: SignalValue<string>;
}) {
return (
<Node ref={makeRef(refs, "group")} y={-KeyTravel}>
<Rect
ref={makeRef(refs, "shadow")}
width={KeySize}
height={KeySize}
y={KeyTravel}
radius={KeyRadius}
fill={"#000000"}
stroke={"#000000"}
lineWidth={KeyBorderThickness}
/>
<Node ref={makeRef(refs, "body")}>
<Rect
layout
ref={makeRef(refs, "fill")}
direction={"column-reverse"}
width={KeySize}
height={KeySize}
fill={"#FFFFFF"}
>
<Rect ref={makeRef(refs, "duration")} grow={0} fill={"#FFFFFF"} />
</Rect>
<Rect
width={KeySize}
height={KeySize}
fill={"#FFFFFF00"}
radius={KeyRadius}
stroke={"#000000"}
lineWidth={KeyBorderThickness}
/>
<Text
ref={makeRef(refs, "binding")}
text={binding}
fill={"#000000"}
width={KeySize}
padding={15}
fontWeight={600}
fontSize={32}
y={-65}
/>
<Text
ref={makeRef(refs, "params")}
text={params}
fill={"#000000"}
width={KeySize}
justifyContent={"center"}
fontWeight={600}
fontSize={60}
/>
</Node>
</Node>
);
}

View file

@ -0,0 +1,121 @@
import { Rect, Text, Node } from "@motion-canvas/2d/lib/components";
import { makeRef } from "@motion-canvas/core/lib/utils";
import { KeyBorderThickness } from "./Key";
const OutputThickness = KeyBorderThickness / 2;
const OutputFontSize = 40;
const OutputFontWeight = 600;
const ModifierRadius = 10;
const ModifierFontSize = 32;
const ModifierFontWeight = 600;
const ModifierMargin = 20;
export default function Output({
refs,
}: {
refs: {
group: Rect;
output: Text;
shift: Rect;
alt: Rect;
ctrl: Rect;
gui: Rect;
};
}) {
return (
<Rect layout ref={makeRef(refs, "group")} direction={"column"}>
<Rect
layout
direction={"row"}
alignItems={"center"}
justifyContent={"center"}
radius={ModifierRadius}
stroke={"#000000"}
lineWidth={OutputThickness}
>
<Text
ref={makeRef(refs, "output")}
text={"&#8203"}
fill={"#000000"}
justifyContent={"center"}
fontWeight={OutputFontWeight}
fontSize={OutputFontSize}
margin={ModifierMargin}
/>
</Rect>
<Rect layout direction={"row"} gap={20} marginTop={20}>
<Rect
layout
ref={makeRef(refs, "shift")}
radius={ModifierRadius}
stroke={"#000000"}
lineWidth={OutputThickness}
grow={1}
fill={"#D9D9D9"}
>
<Text
fill={"#000000"}
text={() => "SHIFT"}
fontWeight={ModifierFontWeight}
fontSize={ModifierFontSize}
margin={ModifierMargin}
/>
</Rect>
<Rect
layout
ref={makeRef(refs, "alt")}
radius={ModifierRadius}
stroke={"#000000"}
lineWidth={OutputThickness}
grow={1}
fill={"#D9D9D9"}
>
<Text
fill={"#000000"}
text={() => "ALT"}
fontWeight={ModifierFontWeight}
fontSize={ModifierFontSize}
margin={ModifierMargin}
/>
</Rect>
<Rect
layout
ref={makeRef(refs, "ctrl")}
radius={ModifierRadius}
stroke={"#000000"}
lineWidth={OutputThickness}
grow={1}
fill={"#D9D9D9"}
>
<Text
fill={"#000000"}
text={() => "CTRL"}
fontWeight={ModifierFontWeight}
fontSize={ModifierFontSize}
margin={ModifierMargin}
/>
</Rect>
<Rect
layout
ref={makeRef(refs, "gui")}
radius={ModifierRadius}
stroke={"#000000"}
lineWidth={OutputThickness}
grow={1}
fill={"#D9D9D9"}
>
<Text
fill={"#000000"}
text={() => "GUI"}
fontWeight={ModifierFontWeight}
fontSize={ModifierFontSize}
margin={ModifierMargin}
/>
</Rect>
</Rect>
</Rect>
);
}

View file

@ -0,0 +1,3 @@
{
"version": 0
}

View file

@ -0,0 +1,8 @@
import {makeProject} from '@motion-canvas/core/lib';
import hold_tap_comparison from '../scenes/hold_tap/hold_tap_comparison?scene';
export default makeProject({
scenes: [hold_tap_comparison],
background: '#FFFFFF',
});

View file

@ -1,8 +0,0 @@
import {makeProject} from '@motion-canvas/core/lib';
import example from './scenes/example?scene';
export default makeProject({
scenes: [example],
background: '#141414',
});

View file

@ -1,8 +0,0 @@
import {makeScene2D} from '@motion-canvas/2d/lib/scenes';
import {waitFor} from '@motion-canvas/core/lib/flow';
export default makeScene2D(function* (view) {
// Create your animations here
yield* waitFor(5);
});

View file

@ -0,0 +1,79 @@
import { makeScene2D } from "@motion-canvas/2d/lib/scenes";
import { Text } from "@motion-canvas/2d/lib/components";
import { createRef, makeRefs } from "@motion-canvas/core/lib/utils";
import { all, chain, delay, waitFor } from "@motion-canvas/core/lib/flow";
import Key, { KeyTravel } from "../../components/Key";
import Output from "../../components/Output";
import { linear } from "@motion-canvas/core/lib/tweening";
export default makeScene2D(function* (view) {
const tap = makeRefs<typeof Key>();
view.add(<Key refs={tap} binding={"&mt"} params={"\u21e7 F"} />);
tap.group.position.x(-400);
tap.group.position.y(-150);
tap.duration.fill("#D9D9D9");
const tap_output = makeRefs<typeof Output>();
view.add(<Output refs={tap_output} />);
tap_output.group.position(tap.group.position());
tap_output.group.position.y(tap_output.group.position.y() + 300);
const tap_label = createRef<typeof Text>();
view.add(
<Text
ref={tap_label}
position={tap.group.position().addY(-160)}
fontWeight={600}
fontSize={64}
>
tap
</Text>
);
const hold = makeRefs<typeof Key>();
view.add(<Key refs={hold} binding={"&mt"} params={"\u21e7 F"} />);
hold.group.position.x(400);
hold.group.position.y(-150);
hold.duration.fill("#D9D9D9");
const hold_output = makeRefs<typeof Output>();
view.add(<Output refs={hold_output} />);
hold_output.group.position(hold.group.position());
hold_output.group.position.y(hold_output.group.position.y() + 300);
const hold_tap = createRef<typeof Text>();
view.add(
<Text
ref={hold_tap}
position={hold.group.position().addY(-160)}
fontWeight={600}
fontSize={64}
>
hold
</Text>
);
yield* waitFor(0.5);
yield* all(
tap.body.position.y(KeyTravel, 0.15),
hold.body.position.y(KeyTravel, 0.15)
);
yield* all(
tap.duration.grow(0.5, 1, linear),
delay(1, tap.body.position.y(0, 0.15)),
hold.duration.grow(1, 2, linear)
);
yield* chain(
all(tap.group.rotation(3, 0.03), hold.group.rotation(3, 0.03)),
all(tap.group.rotation(-3, 0.06), hold.group.rotation(-3, 0.06)),
all(tap.group.rotation(0, 0.03), hold.group.rotation(0, 0.03)),
all(tap_output.output.text("f", 0), hold_output.shift.fill("#969696", 0.15))
);
yield* waitFor(0.25);
yield* hold.body.position.y(0, 0.15);
yield* delay(
0.5,
all(tap.duration.grow(0, 0.15), hold.duration.grow(0, 0.15))
);
});

View file

@ -4,7 +4,7 @@ import motionCanvas from "@motion-canvas/vite-plugin";
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
motionCanvas({ motionCanvas({
project: ["./src/project.ts"], project: ["./src/hold_tap/hold_tap_comparison.ts"],
}), }),
], ],
build: { build: {