Skip to content

Chapter 9 - Draw from your smartphone

In the previous chapter, you were able to set environment variables to access the backend on different URLs.

In this chapter, you'll configure your frontend to access the backend that is running on your computer from your smartphone.

Warning

Please be aware both your computer and your smartphone must be on the same network for this to work.

Steps

Support TouchEvent in the Sketch component

The Sketch component is currently only supporting mouse events. You'll need to add support for touch events as well. This will allow you to draw on your smartphone.

frontend/src/components/sketch.tsx
import React from "react";
import Konva from "konva";
import { Stage, Layer, Line } from "react-konva";
import { useLines } from "@/components/line-provider";
import { useWebSocket } from "@/components/websocket-provider";

export type SketchProps = {
	strokeColor: string;
	strokeSize: number;
};

export const Sketch = ({ strokeColor, strokeSize }: SketchProps) => {
	const { state: lines, dispatch: dispatchLines } = useLines();
	const { emitFirstPointFromPlayer, emitPointFromPlayer } = useWebSocket();
	const isDrawing = React.useRef(false);

	const getPointFromMouseEvent = (
		mouseEvent: Konva.KonvaEventObject<MouseEvent | TouchEvent>
	) => {
		return mouseEvent.target.getStage()?.getPointerPosition() ?? { x: 0, y: 0 };
	};

	const handleMouseDown = (
		e: Konva.KonvaEventObject<MouseEvent | TouchEvent>
	) => {
		isDrawing.current = true;
		const point = getPointFromMouseEvent(e);
		dispatchLines({ type: "ADD_FIRST_POINT", point: point });
		emitFirstPointFromPlayer(point);
	};

	const handleMouseMove = (
		e: Konva.KonvaEventObject<MouseEvent | TouchEvent>
	) => {
		if (!isDrawing.current) {
			return;
		}
		const point = getPointFromMouseEvent(e);
		dispatchLines({ type: "ADD_POINT", point: point });
		emitPointFromPlayer(point);
	};

	const handleMouseUp = () => {
		isDrawing.current = false;
	};

	return (
		<div>
			<Stage
				width={window.innerWidth}
				height={window.innerHeight}
				onMouseDown={handleMouseDown}
				onMousemove={handleMouseMove}
				onMouseup={handleMouseUp}
				onTouchStart={handleMouseDown} // (1)!
				onTouchMove={handleMouseMove} // (2)!
				onTouchEnd={handleMouseUp} // (3)!
			>
				<Layer>
					{lines.map((line, i) => (
						<Line
							key={i}
							points={line}
							stroke={strokeColor}
							strokeWidth={strokeSize}
							tension={0.5}
							lineCap="round"
							lineJoin="round"
						/>
					))}
				</Layer>
			</Stage>
		</div>
	);
};
  1. Add the onTouchStart event handler to the Stage component.
  2. Add the onTouchMove event handler to the Stage component.
  3. Add the onTouchEnd event handler to the Stage component.

Update the CSS

On mobile, while drawing on your screen, you may notice the page is scrolling up and down and might refresh as well. This is because the default behavior of the browser is to scroll the page when you're touching the screen.

Update the global CSS to avoid these issues on mobile.

frontend/src/styles/globals.css
1
2
3
4
5
6
7
html,
body {
	overscroll-behavior: none; /* (1)! */
	height: 100%;
	margin: 0;
	overflow: hidden;
}
  1. Disable the default pull-to-refresh behavior on mobile.

Get your computer IP

An IP address is like a home address. Each device connected to a network has an IP address that designate the device.

Your computer has an IP address we'll use to access your drawing application that is running on your computer from your smartphone.

Getting your computer IP address varies from operating systems to another.

  1. Open a terminal.
  2. Type hostname -I | awk '{print $1}' and press Enter.
  3. Note the IP address that follows.

From the Apple menu, select System Preferences....

  1. In System Preferences, select Wi-Fi.
  2. In the right of the "Wi-Fi" window, click on the "Details" button of the network you're actually connected to.
  3. Under TCP/IP, note your current IP address. It should be something like 192.168.1.x, 10.x.x.x, 172.x.x.x.
  1. Open a command prompt.
  2. Type ipconfig and press Enter.
  3. Your IP address will be the IPv4 address.

Set your IP address as the backend URL

In your frontend environment variables, set the backend URL as your computer IP with the port. Replace my IP 10.11.12.13 with the one from your computer.

frontend/.env
# The URL to access the backend
BACKEND_URL=10.11.12.13:4000

Update the dev container configuration

In your dev container configuration, open the ports 3000 and 4000 to be able to access the frontend and the backend from any device of the network, for example your smartphone.

After editing the file, open the Visual Studio Code command Palette with View > Command palette... and type the Dev Containers: Rebuild and Reopen in Container command and select it. This will rebuild your devcontainer.

.devcontainer/devcontainer.json
// See https://containers.dev/implementors/json_reference/ for configuration reference
{
	"name": "Interactive drawing application",
	"build": {
		"dockerfile": "Dockerfile"
	},
	"remoteUser": "node",
	"runArgs": ["-p=3000:3000", "-p=4000:4000"],
	"postCreateCommand": "./.devcontainer/npm-global-without-sudo.sh",
	"customizations": {
		"vscode": {
			"extensions": []
		}
	}
}

Access your drawing application from your smartphone

Start both applications.

On your smartphone, open a Web browser. Access your computer IP and port. Using the previous example, that would be http://10.11.12.13:3000.

You should now be able to draw from your smartphone! Open a window on your computer using the same address and you should be able to see both players drawing at the same time!

Summary

Congrats! You can now draw collaboratively on different devices that are on the same network! The next step in to allow to use your application from anywhere.