Mouse trail
A Line2D that gains a point where the pointer is and drops the oldest one once it is full. The width curve and the gradient do the fade.
The editor above is running this project. Change a line and it reloads.
Godot classes used
Line2DGradientCurve
The code
scripts/main.gd
extends Node
const MAX_POINTS: int = 110
const MIN_STEP: float = 7.0
const DRIFT_SPEED: float = 1.1
var trail: Line2D
var head: Polygon2D
var pointer: Vector2
var center: Vector2
var span: Vector2
var drifting: bool = true
var elapsed: float = 0.0
func _ready() -> void:
_add_background()
var view: Vector2 = get_viewport().get_visible_rect().size
center = view * 0.5
span = view * 0.32
pointer = center
var gradient: Gradient = Gradient.new()
gradient.set_color(0, Color('#8da5f3', 0.0))
gradient.set_color(1, Color('#8eef97'))
var taper: Curve = Curve.new()
taper.add_point(Vector2(0.0, 0.05))
taper.add_point(Vector2(1.0, 1.0))
trail = Line2D.new()
trail.width = 16.0
trail.width_curve = taper
trail.gradient = gradient
trail.joint_mode = Line2D.LINE_JOINT_ROUND
trail.begin_cap_mode = Line2D.LINE_CAP_ROUND
trail.end_cap_mode = Line2D.LINE_CAP_ROUND
add_child(trail)
head = _make_circle(10.0, Color('#f3d48d'))
head.position = pointer
add_child(head)
_add_label('one point per frame, the oldest point leaves once the line is full', Vector2(40, 40))
print('move the mouse, the line keeps the last ' + str(MAX_POINTS) + ' points')
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
pointer = event.position
drifting = false
func _process(delta: float) -> void:
elapsed += delta
if drifting:
pointer = center + Vector2(cos(elapsed * DRIFT_SPEED), sin(elapsed * DRIFT_SPEED * 1.6)) * span
head.position = pointer
if trail.get_point_count() == 0 or trail.points[-1].distance_to(pointer) > MIN_STEP:
trail.add_point(pointer)
while trail.get_point_count() > MAX_POINTS:
trail.remove_point(0)
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 _make_circle(radius: float, color: Color) -> Polygon2D:
var points: PackedVector2Array = PackedVector2Array()
for i in 24:
points.append(Vector2(cos(TAU * i / 24.0), sin(TAU * i / 24.0)) * radius)
var circle: Polygon2D = Polygon2D.new()
circle.polygon = points
circle.color = color
return circle
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)