Skip to content

Commit

Permalink
Canvas Background (#57)
Browse files Browse the repository at this point in the history
Change Background Color
  • Loading branch information
Eebro authored Jan 6, 2024
1 parent d722813 commit dd9acf7
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 12 deletions.
76 changes: 76 additions & 0 deletions client/src/components/lib/CanvasBackground.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React from 'react';
import { useAppStore } from '@/stores/AppStore';
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';

/**
* This file defines the CanvasColorToolGroup component, which allows the user to select
* a background color for the canvas. The available colors are defined in the
* `canvasColourTypes` array. The `strokeColorMap` and `mapStrokeColour` objects map these
* colors to their corresponding CSS classes and color values respectively.
* @author Eebro
*/

export const canvasColourTypes = [
'whiteCanvas',
'greenCanvas',
'blueCanvas',
'orangeCanvas',
] as const;
export type canvasColourType = (typeof canvasColourTypes)[number];

const strokeColorMap: Record<string, string> = {
whiteCanvas: 'bg-white border-gray-300',
greenCanvas: 'bg-green-200',
blueCanvas: 'bg-blue-200',
orangeCanvas: 'bg-orange-200',
};

const mapStrokeColour = {
whiteCanvas: '#FFFFFF',
greenCanvas: '#D5F5E3',
blueCanvas: '#D6EAF8',
orangeCanvas: '#FAE5D3',
};

/**
* Creates a row group of buttons corresponding
* to the provided list of tools.
* @param tools The list of tools
* @param selectedTool The currently selected tool, used
* to highlight the selected tool.
*/
const CanvasColorToolGroup = ({
colorList,
}: {
colorList: canvasColourType[];
}) => {
const { setCanvasBackground, canvasColor } = useAppStore([
'setCanvasBackground',
'canvasColor',
]);

const handleColorSelection = (color: canvasColourType) => {
setCanvasBackground(mapStrokeColour[color]);
console.log('color', color);
};

return (
<DropdownMenu.Item className="group text-[13px] indent-[10px] leading-none text-violet11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-violet9">
{colorList.map((color) => (
<button
className={
'w-5 h-5 mr-3 rounded-full hover:border-gray-900 border-2 ' +
strokeColorMap[color] +
' ' +
(canvasColor === mapStrokeColour[color]
? 'border-gray-900'
: 'border-transparent')
}
onClick={() => handleColorSelection(color)}
key={color}
></button>
))}
</DropdownMenu.Item>
);
};
export default CanvasColorToolGroup;
14 changes: 14 additions & 0 deletions client/src/components/lib/DropDownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import {
Pencil2Icon,
InfoCircledIcon,
Share1Icon,
BlendingModeIcon,
} from '@radix-ui/react-icons';
import { useAppStore } from '@/stores/AppStore';
import CanvasColorToolGroup, { canvasColourTypes } from './CanvasBackground';

/**
* Creates a DropDownMenu for Canvas
Expand Down Expand Up @@ -81,7 +83,19 @@ const DropDownMenu = ({
<Pencil2Icon /> Edit Canvas
</DropdownMenu.Item>
<DropdownMenu.Separator className="h-[1px] bg-neutral-200 m-[5px]" />

<ResetCanvasDropDownMenu />
<DropdownMenu.Separator className="h-[1px] bg-neutral-200 m-[5px]" />

<DropdownMenu.Item
className="group text-[13px] indent-[10px] leading-none text-violet11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-violet9 hover:bg-indigo-200"
disabled={true}
>
<BlendingModeIcon /> Canvas Background
</DropdownMenu.Item>

<CanvasColorToolGroup colorList={[...canvasColourTypes]} />

<DropdownMenu.Arrow className="fill-white" />
</DropdownMenu.Content>
</DropdownMenu.Portal>
Expand Down
25 changes: 13 additions & 12 deletions client/src/hooks/useDrawElements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ import { renderCanvasElements } from '@/lib/canvasElements/renderScene';
* @authors Yousef Yassin, Dana El Sherif
*/
const useDrawElements = () => {
const { appHeight, appWidth, zoom, panOffset, action } = useAppStore([
'appHeight',
'appWidth',
'zoom',
'panOffset',
'action',
]);
const { appHeight, appWidth, zoom, panOffset, action, canvasColor } =
useAppStore([
'appHeight',
'appWidth',
'zoom',
'panOffset',
'action',
'canvasColor',
]);
const {
selectedElementIds,
p1,
Expand All @@ -40,7 +42,6 @@ const useDrawElements = () => {
angles,
selectionFrame,
roughElements,
//fillColors,
opacities,
strokeColors,
strokeWidths,
Expand All @@ -61,7 +62,6 @@ const useDrawElements = () => {
'isImagePlaceds',
'angles',
'selectionFrame',
//'fillColors',
'opacities',
'strokeColors',
'strokeWidths',
Expand All @@ -73,9 +73,9 @@ const useDrawElements = () => {
if (ctx === null || canvas === null) return;

// Clear on each rerender
ctx.clearRect(0, 0, canvas.width, canvas.height);
// ctx.fillStyle = 'blue';
// ctx.fillRect(0, 0, canvas.width, canvas.height);
//ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = canvasColor || 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Retrieve the scaling offset to apply for centered zoom
// (TODO: We can change this to zoom towards mouse position)
Expand Down Expand Up @@ -152,6 +152,7 @@ const useDrawElements = () => {
opacities,
strokeColors,
strokeWidths,
canvasColor,
]);
};

Expand Down
8 changes: 8 additions & 0 deletions client/src/stores/AppStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ interface AppState {
zoom: number;
//Panning offset
panOffset: { x: number; y: number };
// Canvas Background Color
canvasColor: string;
}
interface AppActions {
// Reducer to set the canvas action
Expand All @@ -46,6 +48,7 @@ interface AppActions {
// Reducer to set zoom level
setAppZoom: (zoom: number) => void;
setPanOffset: (x: number, y: number) => void;
setCanvasBackground: (canvasColor: string) => void;
}
type AppStore = AppState & AppActions;

Expand All @@ -60,6 +63,7 @@ export const initialAppState: AppState = {
appHeight: window.innerHeight,
zoom: 1, // 100%
panOffset: { x: 0, y: 0 },
canvasColor: '#fff',
};

/** Actions / Reducers */
Expand All @@ -83,6 +87,9 @@ const setAppZoom = (set: SetState<AppStore>) => (zoom: number) =>
}));
const setPanOffset = (set: SetState<AppStore>) => (x: number, y: number) =>
set(() => ({ panOffset: { x, y } }));
const setCanvasBackground =
(set: SetState<AppStore>) => (canvasColor: string) =>
set(() => ({ canvasColor }));

/** Store Hook */
const appStore = create<AppStore>()((set) => ({
Expand All @@ -95,5 +102,6 @@ const appStore = create<AppStore>()((set) => ({
setAppDimensions: setAppDimensions(set),
setAppZoom: setAppZoom(set),
setPanOffset: setPanOffset(set),
setCanvasBackground: setCanvasBackground(set),
}));
export const useAppStore = createStoreWithSelectors(appStore);

0 comments on commit dd9acf7

Please sign in to comment.