calculation of the cube animtor matrix aligned ( still some questions
left concerning non symmetric calculations )
This commit is contained in:
parent
cb67a057d7
commit
3a0796e085
@ -67,14 +67,9 @@ namespace
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RotationTransform( Qt::Axis axis, qreal dx1, qreal dy1, qreal dx2,
|
||||
qreal dy2, qreal radians, QQuickItem* item )
|
||||
RotationTransform( Qt::Axis axis, qreal radians, QQuickItem* item )
|
||||
: QQuickTransform( item )
|
||||
, m_axis( axis )
|
||||
, m_dx1( dx1 )
|
||||
, m_dy1( dy1 )
|
||||
, m_dx2( dx2 )
|
||||
, m_dy2( dy2 )
|
||||
, m_radians( radians )
|
||||
{
|
||||
prependToItem( item );
|
||||
@ -89,34 +84,17 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
void setPreTransform( qreal dx1, qreal dy1 )
|
||||
{
|
||||
if( !qskFuzzyCompare( dx1, m_dx1 ) || !qskFuzzyCompare( dy1, m_dy1 ) )
|
||||
{
|
||||
m_dx1 = dx1;
|
||||
m_dy1 = dy1;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void setPostTransform( qreal dx2, qreal dy2 )
|
||||
{
|
||||
if( !qskFuzzyCompare( dx2, m_dx2 ) || !qskFuzzyCompare( dy2, m_dy2 ) )
|
||||
{
|
||||
m_dx2 = dx2;
|
||||
m_dy2 = dy2;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void applyTo( QMatrix4x4* matrix) const override
|
||||
{
|
||||
if ( const auto item = qobject_cast< QQuickItem* >( parent() ) )
|
||||
{
|
||||
const auto dx = 0.5 * item->width();
|
||||
const auto dy = 0.5 * item->height();
|
||||
|
||||
QTransform transform;
|
||||
transform.translate( m_dx1, m_dy1 );
|
||||
transform.translate( dx, dy );
|
||||
transform.rotateRadians( m_radians, m_axis );
|
||||
transform.translate( m_dx2, m_dy2 );
|
||||
transform.translate( -dx, -dy );
|
||||
|
||||
*matrix *= transform;
|
||||
}
|
||||
@ -124,19 +102,46 @@ namespace
|
||||
|
||||
private:
|
||||
const Qt::Axis m_axis;
|
||||
qreal m_dx1;
|
||||
qreal m_dy1;
|
||||
qreal m_dx2;
|
||||
qreal m_dy2;
|
||||
qreal m_radians;
|
||||
};
|
||||
|
||||
static RotationTransform* qskFindRotationTransform( const QQuickItem* item )
|
||||
class QuickTransform final : public QQuickTransform
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QuickTransform( QQuickItem* item )
|
||||
: QQuickTransform( item )
|
||||
{
|
||||
prependToItem( item );
|
||||
}
|
||||
|
||||
void setTransform( const QTransform& transform )
|
||||
{
|
||||
if ( transform != m_transform )
|
||||
{
|
||||
m_transform = transform;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void applyTo( QMatrix4x4* matrix ) const override
|
||||
{
|
||||
if ( const auto item = qobject_cast< QQuickItem* >( parent() ) )
|
||||
*matrix *= m_transform;
|
||||
}
|
||||
|
||||
private:
|
||||
QTransform m_transform;
|
||||
};
|
||||
|
||||
template< typename Transform >
|
||||
Transform* qskFindTransform( const QQuickItem* item )
|
||||
{
|
||||
const auto& transforms = QQuickItemPrivate::get( item )->transforms;
|
||||
for ( const auto& t : transforms )
|
||||
{
|
||||
if ( auto transform = qobject_cast< RotationTransform* >( t ) )
|
||||
if ( auto transform = qobject_cast< Transform* >( t ) )
|
||||
return transform;
|
||||
}
|
||||
|
||||
@ -402,19 +407,12 @@ void QskStackBoxAnimator2::setup()
|
||||
{
|
||||
const auto axis = ( m_orientation == Qt::Horizontal )
|
||||
? Qt::YAxis : Qt::XAxis;
|
||||
|
||||
if ( auto item = itemAt( 0 ) )
|
||||
{
|
||||
const auto dx = 0.5 * item->width();
|
||||
const auto dy = 0.5 * item->height();
|
||||
( void ) new RotationTransform( axis, dx, dy, -dx, -dy, 0.0, item );
|
||||
}
|
||||
( void ) new RotationTransform( axis, 0.0, item );
|
||||
|
||||
if ( auto item = itemAt( 1 ) )
|
||||
{
|
||||
const auto dx = 0.5 * item->width();
|
||||
const auto dy = 0.5 * item->height();
|
||||
( void ) new RotationTransform( axis, dx, dy, -dx, -dy, M_PI_2, item );
|
||||
}
|
||||
( void ) new RotationTransform( axis, M_PI_2, item );
|
||||
}
|
||||
|
||||
void QskStackBoxAnimator2::advanceIndex( qreal value )
|
||||
@ -428,7 +426,7 @@ void QskStackBoxAnimator2::advanceIndex( qreal value )
|
||||
if ( !m_inverted )
|
||||
radians = 2 * M_PI - radians;
|
||||
|
||||
auto rotation = qskFindRotationTransform( item );
|
||||
auto rotation = qskFindTransform< RotationTransform >( item );
|
||||
rotation->setRadians( radians );
|
||||
|
||||
item->setVisible( true );
|
||||
@ -452,7 +450,7 @@ void QskStackBoxAnimator2::advanceIndex( qreal value )
|
||||
if ( !m_inverted )
|
||||
radians = 2 * M_PI - radians;
|
||||
|
||||
auto rotation = qskFindRotationTransform( item );
|
||||
auto rotation = qskFindTransform< RotationTransform >( item );
|
||||
rotation->setRadians( radians );
|
||||
|
||||
item->setVisible( true );
|
||||
@ -466,7 +464,7 @@ void QskStackBoxAnimator2::done()
|
||||
{
|
||||
if ( auto item = itemAt( i ) )
|
||||
{
|
||||
delete qskFindRotationTransform( item );
|
||||
delete qskFindTransform< RotationTransform >( item );
|
||||
item->setVisible( i == 1 );
|
||||
}
|
||||
}
|
||||
@ -552,18 +550,15 @@ bool QskStackBoxAnimator4::isInverted() const
|
||||
|
||||
void QskStackBoxAnimator4::setup()
|
||||
{
|
||||
const auto axis = ( m_orientation == Qt::Horizontal )
|
||||
? Qt::YAxis : Qt::XAxis;
|
||||
|
||||
if ( auto item = itemAt( 0 ) )
|
||||
{
|
||||
( void ) new RotationTransform( axis, 0.0, 0.0, 0.0, 0.0, 0.0, item );
|
||||
( void ) new QuickTransform( item );
|
||||
item->setVisible( true );
|
||||
}
|
||||
|
||||
if ( auto item = itemAt( 1 ) )
|
||||
{
|
||||
( void ) new RotationTransform( axis, 0.0, 0.0, 0.0, 0.0, -M_PI_2, item );
|
||||
( void ) new QuickTransform( item );
|
||||
item->setVisible( true );
|
||||
}
|
||||
}
|
||||
@ -572,107 +567,76 @@ void QskStackBoxAnimator4::advanceIndex( qreal value )
|
||||
{
|
||||
if ( auto item = itemAt( 0 ) )
|
||||
{
|
||||
auto rotation = qskFindRotationTransform( item );
|
||||
const auto transform = transformation( item, false, value );
|
||||
|
||||
qreal dx1, dy1, radians, dx2, dy2;
|
||||
|
||||
if( orientation() == Qt::Horizontal )
|
||||
{
|
||||
const auto w = item->parentItem() ? item->parentItem()->width() : item->width();
|
||||
|
||||
if( isInverted() )
|
||||
{
|
||||
dx1 = ( w - item->x() ) * value;
|
||||
radians = -M_PI_2 * value;
|
||||
dx2 = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dx1 = w * ( 1 - value ) - item->x() * value;
|
||||
radians = M_PI_2 * value;
|
||||
dx2 = -w;
|
||||
}
|
||||
|
||||
dy1 = 0.5 * item->height();
|
||||
dy2 = -dy1;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto h = item->parentItem() ? item->parentItem()->height() : item->height();
|
||||
|
||||
dx1 = 0.5 * item->width();
|
||||
dx2 = -dx1;
|
||||
|
||||
if( isInverted() )
|
||||
{
|
||||
dy1 = ( h - item->y() ) * value;
|
||||
radians = -M_PI_2 * value;
|
||||
dy2 = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dy1 = h * ( 1 - value ) - item->y() * value;
|
||||
radians = M_PI_2 * value;
|
||||
dy2 = -h;
|
||||
}
|
||||
}
|
||||
|
||||
rotation->setPreTransform( dx1, dy1 );
|
||||
rotation->setRadians( radians );
|
||||
rotation->setPostTransform( dx2, dy2 );
|
||||
auto rotation = qskFindTransform< QuickTransform >( item );
|
||||
rotation->setTransform( transform );
|
||||
}
|
||||
|
||||
if ( auto item = itemAt( 1 ) )
|
||||
{
|
||||
auto rotation = qskFindRotationTransform( item );
|
||||
const auto transform = transformation( item, true, value );
|
||||
|
||||
qreal dx1, dy1, radians, dx2, dy2;
|
||||
auto rotation = qskFindTransform< QuickTransform >( item );
|
||||
rotation->setTransform( transform );
|
||||
}
|
||||
}
|
||||
|
||||
QTransform QskStackBoxAnimator4::transformation(
|
||||
const QQuickItem* item, bool increasing, qreal value ) const
|
||||
{
|
||||
const qreal v = increasing ? value : 1.0 - value;
|
||||
|
||||
qreal radians = M_PI_2 * ( 1.0 - v );
|
||||
if ( increasing != isInverted() )
|
||||
radians = -radians;
|
||||
|
||||
QTransform transform;
|
||||
|
||||
if( orientation() == Qt::Horizontal )
|
||||
{
|
||||
const auto w = item->parentItem() ? item->parentItem()->width() : item->width();
|
||||
qreal dx1, dx2;
|
||||
|
||||
if( isInverted() )
|
||||
if ( increasing == isInverted() )
|
||||
{
|
||||
dx1 = w * value - item->x() * ( 1 - value );
|
||||
radians = -M_PI_2 * ( value - 1 );
|
||||
dx2 = -w;
|
||||
dx1 = item->width() * v - item->x() * ( 1.0 - v );
|
||||
dx2 = -item->width();
|
||||
}
|
||||
else
|
||||
{
|
||||
dx1 = ( item->width() + item->x() ) * ( 1 - value );
|
||||
radians = M_PI_2 * ( value - 1 );
|
||||
dx1 = ( item->x() + item->width() ) * ( 1.0 - v );
|
||||
dx2 = 0.0;
|
||||
}
|
||||
|
||||
dy1 = 0.5 * item->height();
|
||||
dy2 = -dy1;
|
||||
const qreal h2 = 0.5 * item->height();
|
||||
|
||||
transform.translate( dx1, h2 );
|
||||
transform.rotateRadians( radians, Qt::YAxis );
|
||||
transform.translate( dx2, -h2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto h = item->parentItem() ? item->parentItem()->height() : item->height();
|
||||
qreal dy1, dy2;
|
||||
|
||||
dx1 = 0.5 * item->width();
|
||||
dx2 = -dx1;
|
||||
|
||||
if( isInverted() )
|
||||
if ( increasing == isInverted() )
|
||||
{
|
||||
dy1 = h * value - item->y() * ( 1 - value );
|
||||
radians = -M_PI_2 * ( value - 1 );
|
||||
dy2 = -h;
|
||||
dy1 = item->height() * v - item->y() * ( 1.0 - v );
|
||||
dy2 = -item->height();
|
||||
}
|
||||
else
|
||||
{
|
||||
dy1 = ( item->height() + item->y() ) * ( 1 - value );
|
||||
radians = M_PI_2 * ( value - 1 );
|
||||
dy1 = ( item->y() + item->height() ) * ( 1.0 - v );
|
||||
dy2 = 0.0;
|
||||
}
|
||||
|
||||
const qreal w2 = 0.5 * item->width();
|
||||
|
||||
transform.translate( w2, dy1 );
|
||||
transform.rotateRadians( radians, Qt::XAxis );
|
||||
transform.translate( -w2, dy2 );
|
||||
}
|
||||
|
||||
rotation->setPreTransform( dx1, dy1 );
|
||||
rotation->setRadians( radians );
|
||||
rotation->setPostTransform( dx2, dy2 );
|
||||
}
|
||||
return transform;
|
||||
}
|
||||
|
||||
void QskStackBoxAnimator4::done()
|
||||
@ -681,7 +645,7 @@ void QskStackBoxAnimator4::done()
|
||||
{
|
||||
if ( auto item = itemAt( i ) )
|
||||
{
|
||||
delete qskFindRotationTransform( item );
|
||||
delete qskFindTransform< QuickTransform >( item );
|
||||
item->setVisible( i == 1 );
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
class QskStackBox;
|
||||
class QQuickItem;
|
||||
class QTransform;
|
||||
|
||||
class QSK_EXPORT QskStackBoxAnimator : public QObject, public QskAnimator
|
||||
{
|
||||
@ -137,6 +138,8 @@ class QSK_EXPORT QskStackBoxAnimator4 : public QskStackBoxAnimator
|
||||
void done() override;
|
||||
|
||||
private:
|
||||
QTransform transformation( const QQuickItem*, bool increasing, qreal value ) const;
|
||||
|
||||
Qt::Orientation m_orientation : 2;
|
||||
bool m_inverted : 1;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user