fix: Scroll with snapping max scroll target (#11419) ce274af56c

Co-authored-by: Philip Chung <philterdesign@gmail.com>
This commit is contained in:
philter
2026-01-09 20:28:38 +00:00
parent f26de28d16
commit f213badda4
8 changed files with 38 additions and 13 deletions

View File

@@ -1 +1 @@
4b0ea7e6317c81f93d766c0ffd7ff60074851ed8
ce274af56c78a1dd554a13823adbfbf52304b595

View File

@@ -15,7 +15,8 @@ public:
Vec2D rangeMax,
Vec2D value,
std::vector<Vec2D> snappingPoints,
float contentSize) override;
float contentSize,
float viewportSize) override;
Vec2D clamp(Vec2D rangeMin, Vec2D rangeMax, Vec2D value) override;
};
} // namespace rive

View File

@@ -36,7 +36,8 @@ public:
float rangeMax,
float value,
std::vector<float> snappingPoints,
float contentSize);
float contentSize,
float viewportSize);
float advance(float elapsedSeconds);
};
@@ -63,7 +64,8 @@ public:
Vec2D rangeMax,
Vec2D value,
std::vector<Vec2D> snappingPoints,
float contentSize) override;
float contentSize,
float viewportSize) override;
void prepare(DraggableConstraintDirection dir) override;
void reset() override;
};

View File

@@ -54,7 +54,8 @@ public:
Vec2D rangeMax,
Vec2D value,
std::vector<Vec2D> snappingPoints,
float contentSize)
float contentSize,
float viewportSize)
{
m_isRunning = true;
}

View File

@@ -13,9 +13,15 @@ void ClampedScrollPhysics::run(Vec2D rangeMin,
Vec2D rangeMax,
Vec2D value,
std::vector<Vec2D> snappingPoints,
float contentSize)
float contentSize,
float viewportSize)
{
ScrollPhysics::run(rangeMin, rangeMax, value, snappingPoints, contentSize);
ScrollPhysics::run(rangeMin,
rangeMax,
value,
snappingPoints,
contentSize,
viewportSize);
m_value = clamp(rangeMin, rangeMax, value);
}

View File

@@ -39,9 +39,15 @@ void ElasticScrollPhysics::run(Vec2D rangeMin,
Vec2D rangeMax,
Vec2D value,
std::vector<Vec2D> snappingPoints,
float contentSize)
float contentSize,
float viewportSize)
{
Super::run(rangeMin, rangeMax, value, snappingPoints, contentSize);
Super::run(rangeMin,
rangeMax,
value,
snappingPoints,
contentSize,
viewportSize);
std::vector<float> xPoints;
std::vector<float> yPoints;
for (auto pt : snappingPoints)
@@ -56,7 +62,8 @@ void ElasticScrollPhysics::run(Vec2D rangeMin,
rangeMax.x,
value.x,
xPoints,
contentSize);
contentSize,
viewportSize);
}
if (m_physicsY != nullptr)
{
@@ -65,7 +72,8 @@ void ElasticScrollPhysics::run(Vec2D rangeMin,
rangeMax.y,
value.y,
yPoints,
contentSize);
contentSize,
viewportSize);
}
}
@@ -163,7 +171,8 @@ void ElasticScrollPhysicsHelper::run(float acceleration,
float rangeMax,
float value,
std::vector<float> snappingPoints,
float contentSize)
float contentSize,
float viewportSize)
{
m_isRunning = true;
m_runRangeMin = rangeMin;
@@ -194,12 +203,16 @@ void ElasticScrollPhysicsHelper::run(float acceleration,
{
float endTarget = -(m_current + m_speed / m_friction);
float sectionSize = contentSize != 0 ? contentSize : 1;
float viewportSectionSize = viewportSize != 0 ? viewportSize : 1;
int multiple = rangeMax == std::numeric_limits<float>::infinity()
? std::floor(endTarget / sectionSize)
: 0;
float modEndTarget = rangeMax == std::numeric_limits<float>::infinity()
? std::fmod(endTarget, sectionSize)
: endTarget;
float maxTarget = rangeMax == std::numeric_limits<float>::infinity()
? std::numeric_limits<float>::infinity()
: sectionSize - viewportSectionSize;
float closest = std::numeric_limits<float>::max();
float snapTarget = 0;
for (auto snap : snappingPoints)
@@ -211,6 +224,7 @@ void ElasticScrollPhysicsHelper::run(float acceleration,
snapTarget = snap + (multiple * sectionSize);
}
}
snapTarget = std::min(snapTarget, maxTarget);
m_speed = -(snapTarget + m_current) * m_friction;
m_snapTarget = -snapTarget;
}

View File

@@ -280,7 +280,8 @@ void ScrollConstraint::runPhysics()
Vec2D(minOffsetX(), minOffsetY()),
Vec2D(offsetX(), offsetY()),
snap() ? snappingPoints : std::vector<Vec2D>(),
mainAxisIsColumn() ? contentHeight() : contentWidth());
mainAxisIsColumn() ? contentHeight() : contentWidth(),
mainAxisIsColumn() ? viewportHeight() : viewportWidth());
}
}

Binary file not shown.