Skip to content

Commit

Permalink
Better handling for mouse down and up events (support mouse up event …
Browse files Browse the repository at this point in the history
…outside elements)
  • Loading branch information
Vexcited committed Feb 16, 2022
1 parent b38b67b commit 13e97a4
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 22 deletions.
62 changes: 53 additions & 9 deletions src/components/Launchpad.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,47 @@
import type { AvailableLayouts } from "../utils/LaunchpadLayout";
import LaunchpadLayout from "../utils/LaunchpadLayout";

export type LaunchpadProps = {
export function getPadElementId (padId: number, launchpadId = 0) {
const elementId = `launchpad-${launchpadId}-pad-${padId}`;
return elementId;
}

export type ClickEventFunctionProps = (
padId: number,
launchpadId: number,
padElement: EventTarget & HTMLDivElement
) => void;

export type ContextEventFunctionProps = (
padId: number,
launchpadId: number,
event: React.MouseEvent<HTMLDivElement, MouseEvent>
) => void;

type LaunchpadProps = {
launchpadId?: number;
layout?: AvailableLayouts;
onClick: (padId: number, launchpadId: number) => void;

/** Events that can be triggered. */
onMouseDown: ClickEventFunctionProps;
onMouseUp: ClickEventFunctionProps;

/** Optional ustom behaviour on right click. */
onContextMenu?: ContextEventFunctionProps;
}

/**
* We create a new launchpad with the given layout.
* 'launchpadId' is used when using multiples launchpad
* on the same page. We will use it in the HTML "id" to
* access the pad later.
*
* 'onClick' is a function that takes two parameters (padId, launchpadId)
* and will be triggered on pad onClick.
*/
export default function Launchpad ({
launchpadId = 0,
layout = "live",
onClick
onMouseDown,
onMouseUp,
onContextMenu
}: LaunchpadProps) {
const launchpadLayouts = new LaunchpadLayout();
const currentLayout = launchpadLayouts.layouts[layout];
Expand All @@ -35,10 +57,32 @@ export default function Launchpad ({
>
{rows.map(padId => (
<div
id={`launchpad-${launchpadId}-pad-${padId}`}
key={padId}
onContextMenu={(e) => e.preventDefault()}
onMouseDown={() => onClick(padId, launchpadId)}
id={getPadElementId(padId, launchpadId)}
onContextMenu={(event) => {
// We prevent the context menu.
event.preventDefault();

// Execute the custom behaviour if it exists.
if (!onContextMenu) return;
return onContextMenu(padId, launchpadId, event);
}}
onMouseDown={(event) => {
if (event.button === 2) return;

// We save the target pad HTML element.
const padElement = event.currentTarget;

const handleMouseUp = (up_event: MouseEvent) => {
if (up_event.button === 2) return;

onMouseUp(padId, launchpadId, padElement);
document.removeEventListener("mouseup", handleMouseUp);
};

onMouseDown(padId, launchpadId, padElement);
document.addEventListener("mouseup", handleMouseUp);
}}
className="w-full bg-gray-400 rounded-sm select-none aspect-square"
/>
))}
Expand Down
39 changes: 26 additions & 13 deletions src/pages/projects/slug/play.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,35 @@ import type {
ProjectStructure
} from "@/types/Project";

import Launchpad from "@/components/Launchpad";
import type {
ClickEventFunctionProps
} from "@/components/Launchpad";

import Launchpad, {
getPadElementId
} from "@/components/Launchpad";
import { getHexFromVelocity } from "@/utils/novationPalette";

type ProjectPlayProps = { data: ProjectStructure };
export default function ProjectPlay({ data }: ProjectPlayProps) {
console.info("[ProjectPlay] 'data' from render:", data);

const padClickHandler = (padId: number, launchpadId: number) => {
const padHtmlId = `launchpad-${launchpadId}-pad-${padId}`;
const padHtmlElement = document.getElementById(padHtmlId);

if (!padHtmlElement) return;

padHtmlElement.style.backgroundColor = getHexFromVelocity(3);
setTimeout(() => {
padHtmlElement.style.backgroundColor = "";
}, 500);
const handlePadMouseDown: ClickEventFunctionProps = (padId, launchpadId, padElement) => {
/** Debug. */ console.info(
"[handlePadMouseDown] + (down) on pad", padId, "from launchpad", launchpadId
);

padElement.style.backgroundColor = getHexFromVelocity(3);
};

const handlePadMouseUp: ClickEventFunctionProps = (padId, launchpadId, padElement) => {
/** Debug. */ console.info(
"[handlePadMouseUp] - (up) on pad", padId, "from launchpad", launchpadId
);

// Remove every styling applied to the pad.
padElement.removeAttribute("style");
}

return (
<div>
Expand All @@ -33,7 +44,8 @@ export default function ProjectPlay({ data }: ProjectPlayProps) {
>
<Launchpad
layout="programmer"
onClick={padClickHandler}
onMouseUp={handlePadMouseUp}
onMouseDown={handlePadMouseDown}
/>
</div>
<div
Expand All @@ -42,7 +54,8 @@ export default function ProjectPlay({ data }: ProjectPlayProps) {
<Launchpad
launchpadId={1}
layout="programmer"
onClick={padClickHandler}
onMouseUp={handlePadMouseUp}
onMouseDown={handlePadMouseDown}
/>
</div>
</div>
Expand Down

0 comments on commit 13e97a4

Please sign in to comment.