The Canvas UI now shows a grid while the user is painting. (#75604)

A grid is shown while the user is holding a painting tool on an editable
canvas. This is achieved by drawing empty rectangles after the filled
ones are placed whenever the canvas is updated and if requirements are
met.

It's by no mean perfect, especially since the strokeStyle is a mere
"#888888" hexcolor, the contrast may get low around colors of similar
lightness. But I don't think I've much the strength to seek out a
fancier solution to a peeve that's hardly a botherance anyway while the
canvas is still mostly white.

I've also had a maintainer suggest me to make a toggle to
disable/enable. I talked a bit how that'd be a bit more complex to
integrate but not much so frankly, although switching hands or putting
away the tool already works for that. That said, I'm willing to do it if
player feedback suggests such toggle should be integrated.
This commit is contained in:
Ghom
2023-05-26 10:15:10 +00:00
committed by GitHub
parent 9d37e24f07
commit 4f87839cf3
2 changed files with 63 additions and 30 deletions
+8 -2
View File
@@ -50,6 +50,8 @@
/// Is it clean canvas or was there something painted on it at some point, used to decide when to show wip splotch overlay
var/used = FALSE
var/finalized = FALSE //Blocks edits
/// Whether a grid should be shown in the UI if the canvas is editable and the viewer is holding a painting tool.
var/show_grid = TRUE
var/icon_generated = FALSE
var/icon/generated_icon
///boolean that blocks persistence from saving it. enabled from printing copies, because we do not want to save copies.
@@ -128,12 +130,13 @@
.["finalized"] = finalized
.["editable"] = !finalized //Ideally you should be able to draw moustaches on existing paintings in the gallery but that's not implemented yet
.["show_plaque"] = istype(loc,/obj/structure/sign/painting)
.["show_grid"] = show_grid
.["paint_tool_palette"] = null
var/obj/item/painting_implement = user.get_active_held_item()
if(!painting_implement)
.["paint_tool_color"] = null
return
.["paint_tool_color"] = get_paint_tool_color(painting_implement)
// Clearing additional data so that it doesn't linger around if the painting tool is dropped.
.["paint_tool_palette"] = null
SEND_SIGNAL(painting_implement, COMSIG_PAINTING_TOOL_GET_ADDITIONAL_DATA, .)
/obj/item/canvas/examine(mob/user)
@@ -190,6 +193,9 @@
return FALSE
SEND_SIGNAL(painting_implement, COMSIG_PAINTING_TOOL_PALETTE_COLOR_CHANGED, chosen_color, params["color_index"])
. = TRUE
if("toggle_grid")
. = TRUE
show_grid = !show_grid
if("finalize")
. = TRUE
finalize(user)
+55 -28
View File
@@ -18,6 +18,7 @@ type PaintCanvasProps = Partial<{
editable: boolean;
drawing_color: string | null;
has_palette: boolean;
show_grid: boolean;
}>;
type PointData = {
@@ -37,6 +38,7 @@ const toMassPaintFormat = (data: PointData[]) => {
class PaintCanvas extends Component<PaintCanvasProps> {
canvasRef: RefObject<HTMLCanvasElement>;
baseImageData: Color[][];
is_grid_shown: boolean;
modifiedElements: PointData[];
onCanvasModified: (data: PointData[]) => void;
onCanvasDropper: (x: number, y: number) => void;
@@ -47,6 +49,7 @@ class PaintCanvas extends Component<PaintCanvasProps> {
super(props);
this.canvasRef = createRef<HTMLCanvasElement>();
this.modifiedElements = [];
this.is_grid_shown = false;
this.drawing = false;
this.onCanvasModified = props.onCanvasModifiedHandler;
this.onCanvasDropper = props.onCanvasDropperHandler;
@@ -65,9 +68,10 @@ class PaintCanvas extends Component<PaintCanvasProps> {
componentDidUpdate() {
// eslint-disable-next-line max-len
if (
this.props.value !== undefined &&
JSON.stringify(this.baseImageData) !==
JSON.stringify(fromDM(this.props.value))
(this.props.value !== undefined &&
JSON.stringify(this.baseImageData) !==
JSON.stringify(fromDM(this.props.value))) ||
this.is_grid_shown !== this.props.show_grid
) {
this.syncCanvas();
}
@@ -91,6 +95,7 @@ class PaintCanvas extends Component<PaintCanvasProps> {
return;
}
this.baseImageData = fromDM(this.props.value);
this.is_grid_shown = !!this.props.show_grid;
this.modifiedElements = [];
const canvas = this.canvasRef.current!;
@@ -101,6 +106,11 @@ class PaintCanvas extends Component<PaintCanvasProps> {
const color = element[y];
ctx.fillStyle = color.toString();
ctx.fillRect(x, y, 1, 1);
if (this.is_grid_shown) {
ctx.strokeStyle = '#888888';
ctx.lineWidth = 0.05;
ctx.strokeRect(x, y, 1, 1);
}
}
}
}
@@ -141,6 +151,11 @@ class PaintCanvas extends Component<PaintCanvasProps> {
const ctx = canvas.getContext('2d')!;
ctx.fillStyle = color;
ctx.fillRect(x, y, 1, 1);
if (this.is_grid_shown) {
ctx.strokeStyle = '#888888';
ctx.lineWidth = 0.05;
ctx.strokeRect(x, y, 1, 1);
}
}
handleDrawing(event: MouseEvent) {
@@ -222,6 +237,7 @@ type CanvasData = {
patron: string | null;
date: string | null;
show_plaque: boolean;
show_grid: boolean;
};
export const Canvas = (props, context) => {
@@ -231,6 +247,7 @@ export const Canvas = (props, context) => {
const scaled_height = height * data.px_per_unit;
const average_plaque_height = 90;
const palette_height = 44;
const griddy = !!data.show_grid && !!data.editable && !!data.paint_tool_color;
return (
<Window
width={scaled_width + 72}
@@ -241,31 +258,40 @@ export const Canvas = (props, context) => {
(data.editable && data.paint_tool_palette ? palette_height : 0)
}>
<Window.Content>
{!!data.paint_tool_palette && (
<Tooltip
content={
multiline`
You can Right-Click the canvas to change the color of
the painting tool to that of the clicked pixel.
` +
(data.editable
? multiline`
\n You can also select a color from the
palette at the bottom of the UI,
or input a new one with Right-Click.
`
: '')
}>
<Icon
name="question-circle"
position="relative"
color="blue"
size={1.5}
m={0.5}
/>
<br />
</Tooltip>
)}
<Flex align="start" direction="row">
{!!data.paint_tool_palette && (
<Flex.Item>
<Tooltip
content={
multiline`
You can Right-Click the canvas to change the color of
the painting tool to that of the clicked pixel.
` +
(data.editable
? multiline`
\n You can also select a color from the
palette at the bottom of the UI,
or input a new one with Right-Click.
`
: '')
}>
<Icon name="question-circle" color="blue" size={1.5} m={0.5} />
</Tooltip>
</Flex.Item>
)}
{!!data.editable && !!data.paint_tool_color && (
<Flex.Item>
<Button
title="Grid Toggle"
icon="th-large"
backgroundColor={data.show_grid ? 'green' : 'red'}
onClick={() => act('toggle_grid')}
size={1.5}
m={0.5}
/>
</Flex.Item>
)}
</Flex>
<Box textAlign="center">
<PaintCanvas
value={data.grid}
@@ -274,6 +300,7 @@ export const Canvas = (props, context) => {
width={scaled_width}
height={scaled_height}
drawing_color={data.paint_tool_color}
show_grid={griddy}
onCanvasModifiedHandler={(changed) =>
act('paint', { data: toMassPaintFormat(changed) })
}