Draw with the mouse

Hold the left button to draw. Each stroke is a new Line2D, and the right button clears the canvas.

The editor above is running this project. Change a line and it reloads.

Godot classes used

Line2DInputEventMouseButtonInputEventMouseMotion

The code

scripts/main.gd
extends Node

const COLORS: Array = ['#8da5f3', '#8eef97', '#fc7f7f', '#f3d48d']
const MIN_STEP: float = 5.0
const WIDTH: float = 7.0

var stroke: Line2D = null
var next_color: int = 0


func _ready() -> void:
	_add_background()
	_add_sample()
	_add_label('hold the left button to draw, right button clears the canvas', Vector2(40, 40))

	print('drag with the left button to draw, right click to clear')


func _input(event: InputEvent) -> void:
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
		if event.pressed:
			stroke = _new_stroke()
			stroke.add_point(event.position)
		else:
			stroke = null
	elif event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT and event.pressed:
		_clear()
	elif event is InputEventMouseMotion and stroke != null:
		if stroke.points[-1].distance_to(event.position) > MIN_STEP:
			stroke.add_point(event.position)


func _new_stroke() -> Line2D:
	var line: Line2D = Line2D.new()
	line.width = WIDTH
	line.default_color = Color(COLORS[next_color])
	line.joint_mode = Line2D.LINE_JOINT_ROUND
	line.begin_cap_mode = Line2D.LINE_CAP_ROUND
	line.end_cap_mode = Line2D.LINE_CAP_ROUND
	line.antialiased = true
	add_child(line)

	next_color = (next_color + 1) % COLORS.size()

	return line


func _clear() -> void:
	stroke = null

	for child in get_children():
		if child is Line2D:
			child.queue_free()


func _add_sample() -> void:
	var view: Vector2 = get_viewport().get_visible_rect().size
	var sample: Line2D = _new_stroke()

	for i in 90:
		var t: float = float(i) / 89.0
		sample.add_point(Vector2(view.x * (0.14 + t * 0.72), view.y * (0.58 + sin(t * TAU * 1.5) * 0.22)))


func _add_label(text: String, at: Vector2) -> void:
	var label: Label = Label.new()
	label.text = text
	label.position = at
	label.add_theme_color_override('font_color', Color('#999999'))
	label.add_theme_font_size_override('font_size', 20)
	add_child(label)


func _add_background() -> void:
	var background: ColorRect = ColorRect.new()
	background.color = Color('#12141a')
	add_child(background)
	background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)

More Motion examples