Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring in scroll damper #49

Merged
merged 12 commits into from
Apr 7, 2024
507 changes: 300 additions & 207 deletions addons/SmoothScroll/SmoothScrollContainer.gd

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion addons/SmoothScroll/plugin.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ name="SmoothScroll"
description="""This plugin adds a new scroll container class
with additional smooth scroll options."""
author="Fabian Keßler (SpyrexDE)"
version="1.2"
version="1.3"
script="plugin.gd"
33 changes: 33 additions & 0 deletions addons/SmoothScroll/scroll_damper/cubic_scroll_damper.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
extends ScrollDamper
class_name CubicScrollDamper


## Friction, not physical.
## The higher the value, the more obvious the deceleration.
@export_range(0.001, 10000.0, 0.001, "or_greater", "hide_slider")
var friction := 4.0:
set(val):
friction = max(val, 0.001)
_factor = pow(10.0, friction) - 1.0

## Factor to use in formula
var _factor := 10000.0:
set(val): _factor = max(val, 0.000000000001)


func _calculate_velocity_by_time(time: float) -> float:
if time <= 0.0: return 0.0
return time*time*time * _factor


func _calculate_time_by_velocity(velocity: float) -> float:
return pow(abs(velocity) / _factor, 1.0/3.0)


func _calculate_offset_by_time(time: float) -> float:
time = max(time, 0.0)
return 1.0/4.0 * _factor * time*time*time*time


func _calculate_time_by_offset(offset: float) -> float:
return pow(abs(offset) * 4.0 / _factor, 1.0/4.0)
47 changes: 47 additions & 0 deletions addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
extends ScrollDamper
class_name ExpoScrollDamper


## Friction, not physical.
## The higher the value, the more obvious the deceleration.
@export_range(0.001, 10000.0, 0.001, "or_greater", "hide_slider")
var friction := 4.0:
set(val):
friction = max(val, 0.001)
_factor = pow(10.0, friction)

## Factor to use in formula
var _factor := 10000.0:
set(val): _factor = max(val, 1.000000000001)

## Minumun velocity.
@export_range(0.001, 100000.0, 0.001, "or_greater", "hide_slider")
var minimum_velocity := 0.4:
set(val): minimum_velocity = max(val, 0.001)


func _calculate_velocity_by_time(time: float) -> float:
var minimum_time = _calculate_time_by_velocity(minimum_velocity)
if time <= minimum_time: return 0.0
return pow(_factor, time)


func _calculate_time_by_velocity(velocity: float) -> float:
return log(abs(velocity)) / log(_factor)


func _calculate_offset_by_time(time: float) -> float:
return pow(_factor, time) / log(_factor)


func _calculate_time_by_offset(offset: float) -> float:
return log(offset * log(_factor)) / log(_factor)


func _calculate_velocity_to_dest(from: float, to: float) -> float:
var dist = to - from
var min_time = _calculate_time_by_velocity(minimum_velocity)
var min_offset = _calculate_offset_by_time(min_time)
var time = _calculate_time_by_offset(abs(dist) + min_offset)
var vel = _calculate_velocity_by_time(time) * sign(dist)
return vel
Binary file not shown.
29 changes: 29 additions & 0 deletions addons/SmoothScroll/scroll_damper/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions addons/SmoothScroll/scroll_damper/icon.svg.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[remap]

importer="texture"
type="CompressedTexture2D"
uid="uid://4ok12qtgl7xq"
path="res://.godot/imported/icon.svg-ab15342a73e61a79c8b3960fca89a8c3.ctex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://addons/SmoothScroll/scroll_damper/icon.svg"
dest_files=["res://.godot/imported/icon.svg-ab15342a73e61a79c8b3960fca89a8c3.ctex"]

[params]

compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
33 changes: 33 additions & 0 deletions addons/SmoothScroll/scroll_damper/linear_scroll_damper.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
extends ScrollDamper
class_name LinearScrollDamper


## Friction, not physical.
## The higher the value, the more obvious the deceleration.
@export_range(0.001, 10000.0, 0.001, "or_greater", "hide_slider")
var friction := 4.0:
set(val):
friction = max(val, 0.001)
_factor = pow(10.0, friction) - 1.0

## Factor to use in formula
var _factor := 10000.0:
set(val): _factor = max(val, 0.000000000001)


func _calculate_velocity_by_time(time: float) -> float:
if time <= 0.0: return 0.0
return time * _factor


func _calculate_time_by_velocity(velocity: float) -> float:
return abs(velocity) / _factor


func _calculate_offset_by_time(time: float) -> float:
time = max(time, 0.0)
return 1.0/2.0 * _factor * time*time


func _calculate_time_by_offset(offset: float) -> float:
return sqrt(abs(offset) * 2.0 / _factor)
33 changes: 33 additions & 0 deletions addons/SmoothScroll/scroll_damper/quad_scroll_damper.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
extends ScrollDamper
class_name QuadScrollDamper


## Friction, not physical.
## The higher the value, the more obvious the deceleration.
@export_range(0.001, 10000.0, 0.001, "or_greater", "hide_slider")
var friction := 4.0:
set(val):
friction = max(val, 0.001)
_factor = pow(10.0, friction) - 1.0

## Factor to use in formula
var _factor := 10000.0:
set(val): _factor = max(val, 0.000000000001)


func _calculate_velocity_by_time(time: float) -> float:
if time <= 0.0: return 0.0
return time*time * _factor


func _calculate_time_by_velocity(velocity: float) -> float:
return sqrt(abs(velocity) / _factor)


func _calculate_offset_by_time(time: float) -> float:
time = max(time, 0.0)
return 1.0/3.0 * _factor * time*time*time


func _calculate_time_by_offset(offset: float) -> float:
return pow(abs(offset) * 3.0 / _factor, 1.0/3.0)
74 changes: 74 additions & 0 deletions addons/SmoothScroll/scroll_damper/scroll_damper.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
@icon("icon.svg")
extends Resource
class_name ScrollDamper

## Abstract class

## Rebound strength. The higher the value, the faster it attracts.
@export_range(0.0, 1.0, 0.001, "or_greater", "hide_slider")
var rebound_strength := 7.0:
set(val):
rebound_strength= max(val, 0.0)
_attract_factor = rebound_strength * rebound_strength * rebound_strength

## Factor for attracting.
var _attract_factor := 400.0:
set(val):
_attract_factor = max(val, 0.0)


# Abstract method
func _calculate_velocity_by_time(time: float) -> float:
return 0.0

# Abstract method
func _calculate_time_by_velocity(velocity: float) -> float:
return 0.0

# Abstract method
func _calculate_offset_by_time(time: float) -> float:
return 0.0

# Abstract method
func _calculate_time_by_offset(offset: float) -> float:
return 0.0


func _calculate_velocity_to_dest(from: float, to: float) -> float:
var dist = to - from
var time = _calculate_time_by_offset(abs(dist))
var vel = _calculate_velocity_by_time(time) * sign(dist)
return vel


func _calculate_next_velocity(present_time: float, delta_time: float) -> float:
return _calculate_velocity_by_time(present_time - delta_time)


func _calculate_next_offset(present_time: float, delta_time: float) -> float:
return _calculate_offset_by_time(present_time) \
- _calculate_offset_by_time(present_time - delta_time)


## Return the result of next velocity and position according to delta time
func slide(velocity: float, delta_time: float) -> Array:
var present_time = _calculate_time_by_velocity(velocity)
return [
_calculate_next_velocity(present_time, delta_time) * sign(velocity),
_calculate_next_offset(present_time, delta_time) * sign(velocity)
]


## Emulate force that attracts something to destination.
## Return the result of next velocity according to delta time
func attract(from: float, to: float, velocity: float, delta_time: float) -> float:
var dist = to - from
var target_vel = _calculate_velocity_to_dest(from, to)
velocity += _attract_factor * dist * delta_time \
+ _calculate_velocity_by_time(delta_time) * sign(dist)
if (
(dist > 0 and velocity >= target_vel) \
or (dist < 0 and velocity <= target_vel) \
):
velocity = target_vel
return velocity
17 changes: 16 additions & 1 deletion example.tscn
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[gd_scene load_steps=4 format=3 uid="uid://xqy4fhlaf2q3"]
[gd_scene load_steps=7 format=3 uid="uid://xqy4fhlaf2q3"]

[ext_resource type="Script" path="res://addons/SmoothScroll/SmoothScrollContainer.gd" id="1_su8ig"]
[ext_resource type="Script" path="res://addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd" id="2_ibjlc"]

[sub_resource type="GDScript" id="GDScript_xo176"]
script/source = "extends Control
Expand All @@ -15,6 +16,18 @@ func _on_h_slider_value_changed(value):
$Label.text = \"FPS: \" + str($HSlider.value)
"

[sub_resource type="Resource" id="Resource_lssh0"]
script = ExtResource("2_ibjlc")
friction = 4.0
minimum_velocity = 0.4
rebound_strength = 7.0

[sub_resource type="Resource" id="Resource_nvbjt"]
script = ExtResource("2_ibjlc")
friction = 4.0
minimum_velocity = 0.4
rebound_strength = 7.0

[sub_resource type="GDScript" id="GDScript_xu50n"]
script/source = "extends RichTextLabel

Expand Down Expand Up @@ -63,6 +76,8 @@ offset_top = 147.0
offset_right = 649.0
offset_bottom = 393.0
script = ExtResource("1_su8ig")
wheel_scroll_damper = SubResource("Resource_lssh0")
dragging_scroll_damper = SubResource("Resource_nvbjt")
debug_mode = true

[node name="Control" type="Control" parent="SmoothScrollContainer"]
Expand Down