File indexing completed on 2025-02-02 04:11:03
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include"math/bezier/solver.hpp" 0010 0011 #include <QObject> 0012 #include <QPointF> 0013 0014 0015 namespace glaxnimate::model { 0016 0017 /** 0018 * \brief Describes the easing between two keyframes 0019 */ 0020 class KeyframeTransition 0021 { 0022 Q_GADGET 0023 0024 public: 0025 enum Descriptive 0026 { 0027 Hold, 0028 Linear, 0029 Ease, 0030 Fast, 0031 Overshoot, 0032 Custom, 0033 }; 0034 0035 Q_ENUM(Descriptive) 0036 0037 KeyframeTransition() = default; 0038 KeyframeTransition(const QPointF& before_handle, const QPointF& after_handle, bool hold = false); 0039 explicit KeyframeTransition(Descriptive before, Descriptive after); 0040 explicit KeyframeTransition(Descriptive descriptive); 0041 0042 const math::bezier::CubicBezierSolver<QPointF>& bezier() const { return bezier_; } 0043 bool hold() const { return hold_; } 0044 0045 Descriptive before_descriptive() const; 0046 Descriptive after_descriptive() const; 0047 QPointF before() const { return bezier_.points()[1]; } 0048 QPointF after() const { return bezier_.points()[2]; } 0049 0050 /** 0051 * \brief Get interpolation factor 0052 * \param ratio in [0, 1]. Determines the time ratio (0 = before, 1 = after) 0053 * \return A value in [0, 1]: the corresponding interpolation factor 0054 * 0055 * If the bezier is defined as B(t) = (x,y). This gives y given x. 0056 */ 0057 double lerp_factor(double ratio) const; 0058 0059 /** 0060 * \brief Get the bezier parameter at the given time 0061 * \param ratio in [0, 1]. Determines the time ratio (0 = before, 1 = after) 0062 * \return A value in [0, 1]: the corresponding bezier parameter 0063 * 0064 * If the bezier is defined as B(t) = (x,y). This gives t given x. 0065 */ 0066 double bezier_parameter(double ratio) const; 0067 0068 void set_hold(bool hold); 0069 void set_before_descriptive(Descriptive d); 0070 void set_after_descriptive(Descriptive d); 0071 void set_handles(const QPointF& before, const QPointF& after); 0072 void set_before(const QPointF& before); 0073 void set_after(const QPointF& after); 0074 0075 /** 0076 * \brief Split the transition at \p x 0077 * \return The transitions before/after the split 0078 */ 0079 std::pair<KeyframeTransition, KeyframeTransition> split(double x) const; 0080 0081 0082 std::pair<KeyframeTransition, KeyframeTransition> split_t(double t) const; 0083 0084 private: 0085 math::bezier::CubicBezierSolver<QPointF> bezier_ { QPointF(0, 0), QPointF(0, 0), QPointF(1, 1), QPointF(1, 1) }; 0086 bool hold_ = false; 0087 }; 0088 0089 } // namespace glaxnimate::model