diff --git a/ui/paint/blob_linear.cpp b/ui/paint/blob_linear.cpp index 92a5015..c609efe 100644 --- a/ui/paint/blob_linear.cpp +++ b/ui/paint/blob_linear.cpp @@ -10,7 +10,6 @@ #include "ui/painter.h" #include -#include namespace Ui::Paint { @@ -27,34 +26,25 @@ float64 RandomAdditional() { LinearBlobBezier::LinearBlobBezier( int n, - float minScale, + Direction direction, float minSpeed, float maxSpeed) : _segmentsCount(n) , _minSpeed(minSpeed ? minSpeed : kMinSpeed) , _maxSpeed(maxSpeed ? maxSpeed : kMaxSpeed) , _pen(Qt::NoBrush, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin) +, _topDown(direction == Direction::TopDown ? 1 : -1) , _segments(n + 1) { } -void LinearBlobBezier::paint( - Painter &p, - const QBrush &brush, - const QRect &rect, - float pinnedTop, - float progressToPinned) { +void LinearBlobBezier::paint(Painter &p, const QBrush &brush, int width) { auto path = QPainterPath(); - auto m = QMatrix(); - const auto left = rect.x(); - const auto top = rect.y(); - const auto right = rect.x() + rect.width(); - const auto bottom = rect.y() + rect.height(); + const auto left = 0; + const auto right = width; - // path.moveTo(right, bottom); - // path.lineTo(left, bottom); - path.moveTo(right, top); - path.lineTo(left, top); + path.moveTo(right, 0); + path.lineTo(left, 0); const auto &n = _segmentsCount; @@ -67,17 +57,15 @@ void LinearBlobBezier::paint( const auto progress = segment.progress; const auto r1 = segment.radius * (1. - progress) + segment.radiusNext * progress; - const auto y = (bottom + r1);// * progressToPinned - // const auto y = (top - r1) * progressToPinned - // + pinnedTop * (1. - progressToPinned); + const auto y = r1 * _topDown; path.lineTo(left, y); } else { const auto &prevSegment = _segments[i - 1]; - const auto progress = prevSegment.progress; + const auto &progress = prevSegment.progress; const auto r1 = prevSegment.radius * (1. - progress) + prevSegment.radiusNext * progress; - const auto progressNext = segment.progress; + const auto &progressNext = segment.progress; const auto r2 = segment.radius * (1. - progressNext) + segment.radiusNext * progressNext; @@ -85,26 +73,18 @@ void LinearBlobBezier::paint( const auto x2 = (right - left) / n * i; const auto cx = x1 + (x2 - x1) / 2; - const auto y1 = (bottom + r1);// * progressToPinned - // const auto y1 = (top - r1) * progressToPinned - // + pinnedTop * (1. - progressToPinned); - const auto y2 = (bottom + r2);// * progressToPinned - // const auto y2 = (top - r2) * progressToPinned - // + pinnedTop * (1. - progressToPinned); + const auto y1 = r1 * _topDown; + const auto y2 = r2 * _topDown; path.cubicTo( QPointF(cx, y1), QPointF(cx, y2), QPointF(x2, y2) ); - if (i == n) { - path.lineTo(right, top); - // path.lineTo(right, bottom); - } } } + path.lineTo(right, 0); p.setBrush(Qt::NoBrush); - p.setPen(_pen); p.fillPath(path, brush); p.drawPath(path); @@ -129,7 +109,6 @@ void LinearBlobBezier::generateBlob(float &radius, int i) { } void LinearBlobBezier::update(float level, float speedScale) { - _scale = level; for (auto i = 0; i < _segmentsCount; i++) { auto &segment = _segments[i]; segment.progress += (segment.speed * _minSpeed) diff --git a/ui/paint/blob_linear.h b/ui/paint/blob_linear.h index 688fb09..31db7d7 100644 --- a/ui/paint/blob_linear.h +++ b/ui/paint/blob_linear.h @@ -12,6 +12,11 @@ namespace Ui::Paint { class LinearBlobBezier final { public: + enum class Direction { + TopDown, + BottomUp, + }; + struct Radiuses { float min = 0.; float max = 0.; @@ -26,16 +31,11 @@ public: LinearBlobBezier( int n, - float minScale, + Direction direction = Direction::TopDown, float minSpeed = 0, float maxSpeed = 0); - void paint( - Painter &p, - const QBrush &brush, - const QRect &rect, - float pinnedTop, - float progressToPinned); + void paint(Painter &p, const QBrush &brush, int width); void update(float level, float speedScale); void generateBlob(); @@ -56,10 +56,10 @@ private: const float _minSpeed; const float _maxSpeed; const QPen _pen; + const int _topDown; std::vector _segments; - float64 _scale = 0; Radiuses _radiuses; }; diff --git a/ui/paint/blobs_linear.cpp b/ui/paint/blobs_linear.cpp index fcdea81..db03988 100644 --- a/ui/paint/blobs_linear.cpp +++ b/ui/paint/blobs_linear.cpp @@ -13,12 +13,12 @@ namespace Ui::Paint { LinearBlobs::LinearBlobs( std::vector blobDatas, float levelDuration, - float levelDuration2, - float maxLevel) + float maxLevel, + LinearBlobBezier::Direction direction) : _maxLevel(maxLevel) +, _direction(direction) , _blobDatas(std::move(blobDatas)) -, _levelValue(levelDuration) -, _levelValue2(levelDuration2) { +, _levelValue(levelDuration) { init(); } @@ -26,16 +26,16 @@ void LinearBlobs::init() { for (const auto &data : _blobDatas) { auto blob = Paint::LinearBlobBezier( data.segmentsCount, - data.minScale); - blob.setRadiuses({ 0, data.minRadius }); + _direction); + blob.setRadiuses({ data.minRadius, data.idleRadius }); blob.generateBlob(); _blobs.push_back(std::move(blob)); } } float LinearBlobs::maxRadius() const { - const auto maxOfRadiuses = [](const BlobData data) { - return std::max(data.maxRadius, data.minRadius); + const auto maxOfRadiuses = [](const BlobData &d) { + return std::max(d.idleRadius, std::max(d.maxRadius, d.minRadius)); }; const auto max = *ranges::max_element( _blobDatas, @@ -67,27 +67,18 @@ LinearBlobBezier::Radiuses LinearBlobs::radiusesAt(int index) { void LinearBlobs::setLevel(float value) { const auto to = std::min(_maxLevel, value) / _maxLevel; _levelValue.start(to); - _levelValue2.start(to); } -void LinearBlobs::paint( - Painter &p, - const QBrush &brush, - const QRect &rect, - float pinnedTop, - float progressToPinned) { +void LinearBlobs::paint(Painter &p, const QBrush &brush, int width) { PainterHighQualityEnabler hq(p); const auto opacity = p.opacity(); for (auto i = 0; i < _blobs.size(); i++) { - auto r = rect; - r.setTop(r.top() - _blobDatas[i].topOffset * _levelValue2.current()); - _blobs[i].update(_levelValue.current(), _blobDatas[i].speedScale); const auto alpha = _blobDatas[i].alpha; if (alpha != 1.) { p.setOpacity(opacity * alpha); } - _blobs[i].paint(p, brush, r, pinnedTop, progressToPinned); + _blobs[i].paint(p, brush, width); if (alpha != 1.) { p.setOpacity(opacity); } @@ -97,13 +88,13 @@ void LinearBlobs::paint( void LinearBlobs::updateLevel(crl::time dt) { const auto d = (dt > 20) ? 17 : dt; _levelValue.update(d); - _levelValue2.update(d); + const auto level = (float)currentLevel(); for (auto i = 0; i < _blobs.size(); i++) { const auto &data = _blobDatas[i]; _blobs[i].setRadiuses({ - 0, - data.minRadius + data.maxRadius * (float)currentLevel() }); + data.minRadius, + data.idleRadius + (data.maxRadius - data.idleRadius) * level }); } } diff --git a/ui/paint/blobs_linear.h b/ui/paint/blobs_linear.h index a4a30e5..3187e8d 100644 --- a/ui/paint/blobs_linear.h +++ b/ui/paint/blobs_linear.h @@ -17,9 +17,9 @@ class LinearBlobs final { public: struct BlobData { int segmentsCount = 0; - float minScale = 0; float minRadius = 0; float maxRadius = 0; + float idleRadius = 0; float speedScale = 0; float alpha = 0; int topOffset = 0; @@ -28,8 +28,8 @@ public: LinearBlobs( std::vector blobDatas, float levelDuration, - float levelDuration2, - float maxLevel); + float maxLevel, + LinearBlobBezier::Direction direction); void setRadiusesAt( rpl::producer &&radiuses, @@ -37,12 +37,7 @@ public: LinearBlobBezier::Radiuses radiusesAt(int index); void setLevel(float value); - void paint( - Painter &p, - const QBrush &brush, - const QRect &rect, - float pinnedTop, - float progressToPinned); + void paint(Painter &p, const QBrush &brush, int width); void updateLevel(crl::time dt); [[nodiscard]] float maxRadius() const; @@ -55,12 +50,12 @@ private: void init(); const float _maxLevel; + const LinearBlobBezier::Direction _direction; std::vector _blobDatas; std::vector _blobs; anim::continuous_value _levelValue; - anim::continuous_value _levelValue2; rpl::lifetime _lifetime;