HTML5 Captured Mode: Mouse Events Trigger Sudden Camera Jumps . Critical Bug

Godot 4.7 and 4.6 and probably other versions.

Hello, mouse input in HTML5/web exports produces large random jumps (both relative and screen_relative), both at the moment mouse capture mode is enabled, and randomly while it’s already active. This happens consistently and essentially makes it impossible to build 3D first or third person games. I’ve searched extensively online and understand that it’s harder to handle on web due to the underlying browser APIs being different. However, this issue has somehow been solved in other engines.

If anyone has knowledge on this subject or has already encountered this problem, I’d love to know what you did to work around it. Thank you.

func _unhandled_input(event):
	if event is InputEventMouseMotion and d.device == "Computer":
		if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT) or d.shiftLock:
			d.camX = clamp(d.camX - event.screen_relative.y * defaultSensivity * 1.15, -1.2, 0.85)
			d.camY -= event.screen_relative.x * defaultSensivity * 1.15

(post deleted by author)

So update : for now i use a hacky solution that work pretty well on my end. But i’m not sure about how it’d work for other mouse etc..

func set_mouse_captured():
	previous_x = number
	previous_x_difference = number
	previous_y = number
	previous_y_difference = number
	mouse_frame_protection = 16
	frame_protection_multiple = 0
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

var number = 20
var previous_x = number
var previous_x_difference = number
var previous_y = number
var previous_y_difference = number
var mouse_frame_protection = 0
var frame_protection_multiple = 0
var time_reset_protection = Time.get_unix_time_from_system()

func _unhandled_input(event):
	if event is InputEventMouseMotion and d.device == "Computer":
		if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT) or d.shiftLock:
			if mouse_frame_protection > 15:
				var difference_x = abs(previous_x - event.relative.x)
				var difference_y = abs(previous_y - event.relative.y)
			
				if difference_x > previous_x_difference * 5 or difference_y > previous_y_difference * 5:
					previous_x = number
					previous_x_difference = number
					previous_y = number
					previous_y_difference = number
					frame_protection_multiple += 1
					time_reset_protection = Time.get_unix_time_from_system()
					if frame_protection_multiple >= 3:
						mouse_frame_protection = 0
					return
					
				previous_x_difference = max(difference_x,number)
				previous_x = max(event.relative.x,number)
				previous_y_difference = max(difference_y,number)
				previous_y = max(event.relative.y,number)

			d.camX = clamp(d.camX - event.screen_relative.y * defaultSensivity * 1.15, -1.2, 0.85)
			d.camY -= event.screen_relative.x * defaultSensivity * 1.15

func _process(_delta: float) -> void:
	mouse_frame_protection += 1
	if frame_protection_multiple != 0 and Time.get_unix_time_from_system() - time_reset_protection > 1:
		frame_protection_multiple = 0```