mirror of
https://github.com/MaurycyLiebner/enve.git
synced 2024-12-18 14:42:02 +00:00
Compare commits
4 Commits
ce2e6b04da
...
88171af028
Author | SHA1 | Date | |
---|---|---|---|
|
88171af028 | ||
|
96b918b8b0 | ||
|
2d20230608 | ||
|
96eae885e6 |
@ -18,6 +18,10 @@
|
|||||||
|
|
||||||
#include "colorvaluerect.h"
|
#include "colorvaluerect.h"
|
||||||
#include "colorlabel.h"
|
#include "colorlabel.h"
|
||||||
|
#include "colorpickingwidget.h"
|
||||||
|
#include "GUI/mainwindow.h"
|
||||||
|
#include "GUI/actionbutton.h"
|
||||||
|
#include <QWindow>
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
@ -75,7 +79,15 @@ PaintColorWidget::PaintColorWidget(QWidget* const parent) :
|
|||||||
|
|
||||||
layout->addWidget(aRect);
|
layout->addWidget(aRect);
|
||||||
|
|
||||||
layout->addWidget(mColorLabel);
|
const QString pickIcon = "toolbarButtons/pickUnchecked.png";
|
||||||
|
const auto pickingButton = new ActionButton(pickIcon, "", this);
|
||||||
|
connect(pickingButton, &ActionButton::released,
|
||||||
|
this, &PaintColorWidget::startColorPicking);
|
||||||
|
|
||||||
|
const auto colorPickLay = new QHBoxLayout();
|
||||||
|
colorPickLay->addWidget(mColorLabel);
|
||||||
|
colorPickLay->addWidget(pickingButton);
|
||||||
|
layout->addLayout(colorPickLay);
|
||||||
|
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
}
|
}
|
||||||
@ -111,6 +123,16 @@ void PaintColorWidget::setDisplayedColor(const QColor& color) {
|
|||||||
mColorLabel->setAlpha(color.alphaF());
|
mColorLabel->setAlpha(color.alphaF());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PaintColorWidget::startColorPicking() {
|
||||||
|
const auto parent = MainWindow::sGetInstance();
|
||||||
|
const auto screen = parent->windowHandle()->screen();
|
||||||
|
const auto wid = new ColorPickingWidget(screen, parent);
|
||||||
|
connect(wid, &ColorPickingWidget::colorSelected,
|
||||||
|
[this](const QColor & color) {
|
||||||
|
setColor(color);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void PaintColorWidget::setColor(const QColor& color) {
|
void PaintColorWidget::setColor(const QColor& color) {
|
||||||
setDisplayedColor(color);
|
setDisplayedColor(color);
|
||||||
emit colorChanged(color);
|
emit colorChanged(color);
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void colorChanged(const QColor& color);
|
void colorChanged(const QColor& color);
|
||||||
private:
|
private:
|
||||||
|
void startColorPicking();
|
||||||
void setColor(const QColor& color);
|
void setColor(const QColor& color);
|
||||||
|
|
||||||
void updateFromRGB();
|
void updateFromRGB();
|
||||||
|
@ -186,16 +186,8 @@ void BasicTransformAnimator::moveByAbs(const QPointF &absTrans) {
|
|||||||
if(!mParentTransform) return;
|
if(!mParentTransform) return;
|
||||||
const auto savedRelPos = mPosAnimator->getSavedValue();
|
const auto savedRelPos = mPosAnimator->getSavedValue();
|
||||||
const auto savedAbsPos = mParentTransform->mapRelPosToAbs(savedRelPos);
|
const auto savedAbsPos = mParentTransform->mapRelPosToAbs(savedRelPos);
|
||||||
moveToAbs(savedAbsPos + absTrans);
|
const auto relPos = mParentTransform->mapAbsPosToRel(savedAbsPos + absTrans);
|
||||||
}
|
setRelativePos(relPos);
|
||||||
|
|
||||||
void BasicTransformAnimator::moveToAbs(const QPointF &absPos) {
|
|
||||||
setAbsolutePos(absPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BasicTransformAnimator::setAbsolutePos(const QPointF &pos) {
|
|
||||||
if(!mParentTransform) return;
|
|
||||||
setRelativePos(mParentTransform->mapAbsPosToRel(pos));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicTransformAnimator::setRelativePos(const QPointF &relPos) {
|
void BasicTransformAnimator::setRelativePos(const QPointF &relPos) {
|
||||||
|
@ -54,8 +54,6 @@ public:
|
|||||||
void startScaleTransform();
|
void startScaleTransform();
|
||||||
|
|
||||||
void setRelativePos(const QPointF &relPos);
|
void setRelativePos(const QPointF &relPos);
|
||||||
void setAbsolutePos(const QPointF &pos);
|
|
||||||
void moveToAbs(const QPointF &absPos);
|
|
||||||
void moveByAbs(const QPointF &absTrans);
|
void moveByAbs(const QPointF &absTrans);
|
||||||
|
|
||||||
void rotateRelativeToSavedValue(const qreal rotRel);
|
void rotateRelativeToSavedValue(const qreal rotRel);
|
||||||
|
@ -52,8 +52,10 @@ QList<BrushStrokeSet> BrushStrokeSet::sFromSkPath(
|
|||||||
if(segLists.isEmpty()) return result;
|
if(segLists.isEmpty()) return result;
|
||||||
for(auto& segs : segLists) {
|
for(auto& segs : segLists) {
|
||||||
if(segs.isEmpty()) continue;
|
if(segs.isEmpty()) continue;
|
||||||
|
const double totLen = segs.getTotalLength();
|
||||||
|
if(isZero4Dec(totLen)) continue;
|
||||||
const double minL = 0;
|
const double minL = 0;
|
||||||
const double maxL = segs.isClosed() ? 1 + 10/segs.getTotalLength() : 1;
|
const double maxL = segs.isClosed() ? 1 + 10/totLen : 1;
|
||||||
auto segsT = segs.getFragmentUnbound(minL, maxL);
|
auto segsT = segs.getFragmentUnbound(minL, maxL);
|
||||||
result << sFromCubicList(segsT, timeCurve,
|
result << sFromCubicList(segsT, timeCurve,
|
||||||
pressureCurve, widthCurve, spacingCurve);
|
pressureCurve, widthCurve, spacingCurve);
|
||||||
|
@ -29,6 +29,8 @@ BoundingBox* BoxTargetProperty::getTarget() const {
|
|||||||
|
|
||||||
void BoxTargetProperty::setTargetAction(BoundingBox* const box) {
|
void BoxTargetProperty::setTargetAction(BoundingBox* const box) {
|
||||||
if(box == mTarget_d) return;
|
if(box == mTarget_d) return;
|
||||||
|
const auto oldValue = mTarget_d.get();
|
||||||
|
emit setActionStarted(oldValue, box);
|
||||||
{
|
{
|
||||||
prp_pushUndoRedoName("Set Box Target");
|
prp_pushUndoRedoName("Set Box Target");
|
||||||
UndoRedo ur;
|
UndoRedo ur;
|
||||||
@ -44,6 +46,7 @@ void BoxTargetProperty::setTargetAction(BoundingBox* const box) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setTarget(box);
|
setTarget(box);
|
||||||
|
emit setActionFinished(oldValue, box);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoxTargetProperty::setTarget(BoundingBox* const box) {
|
void BoxTargetProperty::setTarget(BoundingBox* const box) {
|
||||||
|
@ -53,6 +53,8 @@ public:
|
|||||||
void setValidator(const Validator& validator)
|
void setValidator(const Validator& validator)
|
||||||
{ mValidator = validator; }
|
{ mValidator = validator; }
|
||||||
signals:
|
signals:
|
||||||
|
void setActionStarted(BoundingBox*, BoundingBox*);
|
||||||
|
void setActionFinished(BoundingBox*, BoundingBox*);
|
||||||
void targetSet(BoundingBox*);
|
void targetSet(BoundingBox*);
|
||||||
private:
|
private:
|
||||||
std::function<bool(BoundingBox*)> mValidator = nullptr;
|
std::function<bool(BoundingBox*)> mValidator = nullptr;
|
||||||
|
@ -34,10 +34,12 @@ CubicList::CubicList(const CubicList &src) {
|
|||||||
CubicList CubicList::getFragment(const qreal minLenFrac,
|
CubicList CubicList::getFragment(const qreal minLenFrac,
|
||||||
const qreal maxLenFrac) const {
|
const qreal maxLenFrac) const {
|
||||||
if(minLenFrac > maxLenFrac) return CubicList();
|
if(minLenFrac > maxLenFrac) return CubicList();
|
||||||
|
const qreal totLen = getTotalLength();
|
||||||
|
if(isZero4Dec(totLen)) return *this;
|
||||||
//Q_ASSERT(minLenFrac > 0);
|
//Q_ASSERT(minLenFrac > 0);
|
||||||
//Q_ASSERT(maxLenFrac < 1);
|
//Q_ASSERT(maxLenFrac < 1);
|
||||||
const qreal minLen = getTotalLength()*CLAMP01(minLenFrac);
|
const qreal minLen = totLen*CLAMP01(minLenFrac);
|
||||||
const qreal maxLen = getTotalLength()*CLAMP01(maxLenFrac);
|
const qreal maxLen = totLen*CLAMP01(maxLenFrac);
|
||||||
qreal minT = 0, maxT = 1;
|
qreal minT = 0, maxT = 1;
|
||||||
int minI = -1, maxI = mSegments.count() - 1;
|
int minI = -1, maxI = mSegments.count() - 1;
|
||||||
qreal currLen = 0;
|
qreal currLen = 0;
|
||||||
@ -58,6 +60,7 @@ CubicList CubicList::getFragment(const qreal minLenFrac,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(minI == -1) return CubicList();
|
||||||
|
|
||||||
QList<qCubicSegment2D> fragSegs;
|
QList<qCubicSegment2D> fragSegs;
|
||||||
if(minI == maxI) {
|
if(minI == maxI) {
|
||||||
|
@ -38,6 +38,51 @@ FollowObjectTransformEffect::FollowObjectTransformEffect() :
|
|||||||
ca_addChild(mRotInfluence);
|
ca_addChild(mRotInfluence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FollowObjectTransformEffect::setRotScaleAfterTargetChange(
|
||||||
|
BoundingBox* const oldTarget, BoundingBox* const newTarget) {
|
||||||
|
const auto parent = getFirstAncestor<BoundingBox>();
|
||||||
|
if(!parent) return;
|
||||||
|
|
||||||
|
const qreal scaleXInfl = mScaleInfluence->getEffectiveXValue();
|
||||||
|
const qreal scaleYInfl = mScaleInfluence->getEffectiveYValue();
|
||||||
|
const qreal rotInfl = mRotInfluence->getEffectiveValue();
|
||||||
|
|
||||||
|
qreal rot = 0.;
|
||||||
|
qreal scaleX = 1.;
|
||||||
|
qreal scaleY = 1.;
|
||||||
|
if(oldTarget) {
|
||||||
|
const auto trans = oldTarget->getTransformAnimator();
|
||||||
|
const auto rotAnim = trans->getRotAnimator();
|
||||||
|
const auto scaleAnim = trans->getScaleAnimator();
|
||||||
|
|
||||||
|
rot += rotAnim->getEffectiveValue()*rotInfl;
|
||||||
|
scaleX *= 1 + (scaleAnim->getEffectiveXValue() - 1)*scaleXInfl;
|
||||||
|
scaleY *= 1 + (scaleAnim->getEffectiveYValue() - 1)*scaleYInfl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newTarget) {
|
||||||
|
const auto trans = newTarget->getTransformAnimator();
|
||||||
|
const auto rotAnim = trans->getRotAnimator();
|
||||||
|
const auto scaleAnim = trans->getScaleAnimator();
|
||||||
|
|
||||||
|
rot -= rotAnim->getEffectiveValue()*rotInfl;
|
||||||
|
const qreal scaleXDiv = 1 + (scaleAnim->getEffectiveXValue() - 1)*scaleXInfl;
|
||||||
|
const qreal scaleYDiv = 1 + (scaleAnim->getEffectiveYValue() - 1)*scaleYInfl;
|
||||||
|
if(!isZero4Dec(scaleXDiv)) {
|
||||||
|
scaleX /= scaleXDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isZero4Dec(scaleYDiv)) {
|
||||||
|
scaleY /= scaleYDiv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parent->startRotTransform();
|
||||||
|
parent->rotateBy(rot);
|
||||||
|
|
||||||
|
parent->startScaleTransform();
|
||||||
|
parent->scale(scaleX, scaleY);
|
||||||
|
}
|
||||||
|
|
||||||
void FollowObjectTransformEffect::applyEffect(
|
void FollowObjectTransformEffect::applyEffect(
|
||||||
const qreal relFrame,
|
const qreal relFrame,
|
||||||
|
@ -33,6 +33,11 @@ public:
|
|||||||
qreal &shearX, qreal &shearY,
|
qreal &shearX, qreal &shearY,
|
||||||
BoundingBox* const parent) override;
|
BoundingBox* const parent) override;
|
||||||
private:
|
private:
|
||||||
|
void setRotScaleAfterTargetChange(
|
||||||
|
BoundingBox* const oldTarget,
|
||||||
|
BoundingBox* const newTarget) override;
|
||||||
|
|
||||||
|
|
||||||
qsptr<QPointFAnimator> mPosInfluence;
|
qsptr<QPointFAnimator> mPosInfluence;
|
||||||
qsptr<QPointFAnimator> mScaleInfluence;
|
qsptr<QPointFAnimator> mScaleInfluence;
|
||||||
qsptr<QrealAnimator> mRotInfluence;
|
qsptr<QrealAnimator> mRotInfluence;
|
||||||
|
@ -35,6 +35,95 @@ FollowPathTransformEffect::FollowPathTransformEffect() :
|
|||||||
ca_addChild(mInfluence);
|
ca_addChild(mInfluence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void calculateFollowRotPosChange(
|
||||||
|
const SkPath relPath,
|
||||||
|
const QMatrix transform,
|
||||||
|
const bool lengthBased,
|
||||||
|
const bool rotate,
|
||||||
|
const qreal infl,
|
||||||
|
qreal per,
|
||||||
|
qreal& rotChange,
|
||||||
|
qreal& posXChange,
|
||||||
|
qreal& posYChange) {
|
||||||
|
SkPath path;
|
||||||
|
relPath.transform(toSkMatrix(transform), &path);
|
||||||
|
const QPainterPath qpath = toQPainterPath(path);
|
||||||
|
|
||||||
|
if(lengthBased) {
|
||||||
|
const qreal length = qpath.length();
|
||||||
|
per = qpath.percentAtLength(per*length);
|
||||||
|
}
|
||||||
|
const auto p1 = qpath.pointAtPercent(per);
|
||||||
|
|
||||||
|
if(rotate) {
|
||||||
|
qreal t2 = per + 0.0001;
|
||||||
|
const bool reverse = t2 > 1;
|
||||||
|
if(reverse) t2 = 0.9999;
|
||||||
|
const auto p2 = qpath.pointAtPercent(t2);
|
||||||
|
|
||||||
|
const QLineF baseLine(QPointF(0., 0.), QPointF(100., 0.));
|
||||||
|
QLineF l;
|
||||||
|
if(reverse) l = QLineF(p2, p1);
|
||||||
|
else l = QLineF(p1, p2);
|
||||||
|
qreal trackAngle = l.angleTo(baseLine);
|
||||||
|
if(trackAngle > 180) trackAngle -= 360;
|
||||||
|
|
||||||
|
rotChange = trackAngle*infl;
|
||||||
|
} else rotChange = 0;
|
||||||
|
posXChange = p1.x();
|
||||||
|
posYChange = p1.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FollowPathTransformEffect::setRotScaleAfterTargetChange(
|
||||||
|
BoundingBox* const oldTarget, BoundingBox* const newTarget) {
|
||||||
|
const bool rotate = mRotate->getValue();
|
||||||
|
if(!rotate) return;
|
||||||
|
const auto parent = getFirstAncestor<BoundingBox>();
|
||||||
|
if(!parent) return;
|
||||||
|
const auto oldTargetP = static_cast<PathBox*>(oldTarget);
|
||||||
|
const auto newTargetP = static_cast<PathBox*>(newTarget);
|
||||||
|
|
||||||
|
const qreal infl = mInfluence->getEffectiveValue();
|
||||||
|
const qreal per = mComplete->getEffectiveValue();
|
||||||
|
const bool lengthBased = mLengthBased->getValue();
|
||||||
|
const qreal relFrame = parent->anim_getCurrentRelFrame();
|
||||||
|
const auto parentTransform = parent->getInheritedTransformAtFrame(relFrame);
|
||||||
|
|
||||||
|
qreal rot = 0.;
|
||||||
|
if(oldTargetP) {
|
||||||
|
const auto relPath = oldTargetP->getRelativePath();
|
||||||
|
const auto targetTransform = oldTargetP->getTotalTransform();
|
||||||
|
const auto transform = targetTransform*parentTransform.inverted();
|
||||||
|
|
||||||
|
qreal rotChange;
|
||||||
|
qreal posXChange;
|
||||||
|
qreal posYChange;
|
||||||
|
calculateFollowRotPosChange(relPath, transform,
|
||||||
|
lengthBased, rotate, infl, per,
|
||||||
|
rotChange, posXChange, posYChange);
|
||||||
|
|
||||||
|
rot += rotChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newTargetP) {
|
||||||
|
const auto relPath = newTargetP->getRelativePath();
|
||||||
|
const auto targetTransform = newTargetP->getTotalTransform();
|
||||||
|
const auto transform = targetTransform*parentTransform.inverted();
|
||||||
|
|
||||||
|
qreal rotChange;
|
||||||
|
qreal posXChange;
|
||||||
|
qreal posYChange;
|
||||||
|
calculateFollowRotPosChange(relPath, transform,
|
||||||
|
lengthBased, rotate, infl, per,
|
||||||
|
rotChange, posXChange, posYChange);
|
||||||
|
|
||||||
|
rot -= rotChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent->startRotTransform();
|
||||||
|
parent->rotateBy(rot);
|
||||||
|
}
|
||||||
|
|
||||||
void FollowPathTransformEffect::applyEffect(
|
void FollowPathTransformEffect::applyEffect(
|
||||||
const qreal relFrame,
|
const qreal relFrame,
|
||||||
qreal& pivotX, qreal& pivotY,
|
qreal& pivotX, qreal& pivotY,
|
||||||
@ -63,38 +152,22 @@ void FollowPathTransformEffect::applyEffect(
|
|||||||
|
|
||||||
const auto transform = targetTransform*parentTransform.inverted();
|
const auto transform = targetTransform*parentTransform.inverted();
|
||||||
|
|
||||||
SkPath path;
|
|
||||||
const auto relPath = target->getRelativePath(targetRelFrame);
|
const auto relPath = target->getRelativePath(targetRelFrame);
|
||||||
relPath.transform(toSkMatrix(transform), &path);
|
|
||||||
const QPainterPath qpath = toQPainterPath(path);
|
|
||||||
|
|
||||||
const qreal infl = mInfluence->getEffectiveValue(relFrame);
|
const qreal infl = mInfluence->getEffectiveValue(relFrame);
|
||||||
qreal per = mComplete->getEffectiveValue(relFrame);
|
qreal per = mComplete->getEffectiveValue(relFrame);
|
||||||
const bool rotate = mRotate->getValue();
|
const bool rotate = mRotate->getValue();
|
||||||
const bool lengthBased = mLengthBased->getValue();
|
const bool lengthBased = mLengthBased->getValue();
|
||||||
|
|
||||||
if(lengthBased) {
|
qreal rotChange;
|
||||||
const qreal length = qpath.length();
|
qreal posXChange;
|
||||||
per = qpath.percentAtLength(per*length);
|
qreal posYChange;
|
||||||
}
|
|
||||||
const auto p1 = qpath.pointAtPercent(per);
|
|
||||||
|
|
||||||
if(rotate) {
|
calculateFollowRotPosChange(relPath, transform,
|
||||||
qreal t2 = per + 0.0001;
|
lengthBased, rotate, infl, per,
|
||||||
const bool reverse = t2 > 1;
|
rotChange, posXChange, posYChange);
|
||||||
if(reverse) t2 = 0.9999;
|
|
||||||
const auto p2 = qpath.pointAtPercent(t2);
|
|
||||||
|
|
||||||
const QLineF baseLine(QPointF(0., 0.), QPointF(100., 0.));
|
if(rotate) rot += rotChange;
|
||||||
QLineF l;
|
|
||||||
if(reverse) l = QLineF(p2, p1);
|
|
||||||
else l = QLineF(p1, p2);
|
|
||||||
qreal trackAngle = l.angleTo(baseLine);
|
|
||||||
if(trackAngle > 180) trackAngle -= 360;
|
|
||||||
|
|
||||||
rot += trackAngle*infl;
|
posX += posXChange; //p1.x()*infl;
|
||||||
}
|
posY += posYChange; //p1.y()*infl;
|
||||||
|
|
||||||
posX += p1.x()*infl;
|
|
||||||
posY += p1.y()*infl;
|
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,10 @@ public:
|
|||||||
qreal &shearX, qreal &shearY,
|
qreal &shearX, qreal &shearY,
|
||||||
BoundingBox* const parent) override;
|
BoundingBox* const parent) override;
|
||||||
private:
|
private:
|
||||||
|
void setRotScaleAfterTargetChange(
|
||||||
|
BoundingBox* const oldTarget,
|
||||||
|
BoundingBox* const newTarget) override;
|
||||||
|
|
||||||
qsptr<BoolProperty> mRotate;
|
qsptr<BoolProperty> mRotate;
|
||||||
qsptr<BoolProperty> mLengthBased;
|
qsptr<BoolProperty> mLengthBased;
|
||||||
qsptr<QrealAnimator> mComplete;
|
qsptr<QrealAnimator> mComplete;
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#include "Boxes/boundingbox.h"
|
#include "Boxes/boundingbox.h"
|
||||||
#include "Animators/transformanimator.h"
|
#include "Animators/transformanimator.h"
|
||||||
|
#include "Animators/qrealanimator.h"
|
||||||
|
#include "Animators/qpointfanimator.h"
|
||||||
|
|
||||||
TargetTransformEffect::TargetTransformEffect(
|
TargetTransformEffect::TargetTransformEffect(
|
||||||
const QString& name,
|
const QString& name,
|
||||||
@ -50,6 +52,28 @@ TargetTransformEffect::TargetTransformEffect(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(mTarget.get(), &BoxTargetProperty::setActionStarted,
|
||||||
|
this, [this]() {
|
||||||
|
const auto parent = getFirstAncestor<BoundingBox>();
|
||||||
|
if(!parent) return;
|
||||||
|
mPosBeforeTargetChange = parent->getPivotAbsPos();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(mTarget.get(), &BoxTargetProperty::setActionFinished,
|
||||||
|
this, [this](BoundingBox* const oldTarget,
|
||||||
|
BoundingBox* const newTarget) {
|
||||||
|
const auto parent = getFirstAncestor<BoundingBox>();
|
||||||
|
if(!parent) return;
|
||||||
|
const auto posAfter = parent->getPivotAbsPos();
|
||||||
|
|
||||||
|
parent->startPosTransform();
|
||||||
|
parent->moveByAbs(mPosBeforeTargetChange - posAfter);
|
||||||
|
|
||||||
|
setRotScaleAfterTargetChange(oldTarget, newTarget);
|
||||||
|
|
||||||
|
parent->finishTransform();
|
||||||
|
});
|
||||||
|
|
||||||
ca_addChild(mTarget);
|
ca_addChild(mTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +90,12 @@ FrameRange TargetTransformEffect::prp_getIdenticalRelRange(
|
|||||||
return thisIdent*prp_absRangeToRelRange(absParentIdent);
|
return thisIdent*prp_absRangeToRelRange(absParentIdent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TargetTransformEffect::setRotScaleAfterTargetChange(
|
||||||
|
BoundingBox* const oldTarget, BoundingBox* const newTarget) {
|
||||||
|
Q_UNUSED(oldTarget)
|
||||||
|
Q_UNUSED(newTarget)
|
||||||
|
}
|
||||||
|
|
||||||
BoxTargetProperty* TargetTransformEffect::targetProperty() const {
|
BoxTargetProperty* TargetTransformEffect::targetProperty() const {
|
||||||
return mTarget.get();
|
return mTarget.get();
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,13 @@ public:
|
|||||||
|
|
||||||
FrameRange prp_getIdenticalRelRange(const int relFrame) const;
|
FrameRange prp_getIdenticalRelRange(const int relFrame) const;
|
||||||
protected:
|
protected:
|
||||||
|
virtual void setRotScaleAfterTargetChange(
|
||||||
|
BoundingBox* const oldTarget,
|
||||||
|
BoundingBox* const newTarget);
|
||||||
|
|
||||||
BoxTargetProperty* targetProperty() const;
|
BoxTargetProperty* targetProperty() const;
|
||||||
private:
|
private:
|
||||||
|
QPointF mPosBeforeTargetChange;
|
||||||
ConnContextQPtr<BoundingBox> mTargetConn;
|
ConnContextQPtr<BoundingBox> mTargetConn;
|
||||||
qsptr<BoxTargetProperty> mTarget;
|
qsptr<BoxTargetProperty> mTarget;
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,43 @@ TrackTransformEffect::TrackTransformEffect() :
|
|||||||
ca_prependChild(targetProperty(), mInfluence);
|
ca_prependChild(targetProperty(), mInfluence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qreal calculateTrackAngle(const QPointF& parentPos,
|
||||||
|
const QPointF& targetPos) {
|
||||||
|
const QLineF baseLine(parentPos, parentPos + QPointF(100., 0.));
|
||||||
|
const QLineF trackLine(parentPos, targetPos);
|
||||||
|
qreal trackAngle = trackLine.angleTo(baseLine);
|
||||||
|
if(trackAngle > 180) trackAngle -= 360;
|
||||||
|
return trackAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackTransformEffect::setRotScaleAfterTargetChange(
|
||||||
|
BoundingBox* const oldTarget, BoundingBox* const newTarget) {
|
||||||
|
const auto parent = getFirstAncestor<BoundingBox>();
|
||||||
|
if(!parent) return;
|
||||||
|
|
||||||
|
const qreal infl = mInfluence->getEffectiveValue();
|
||||||
|
|
||||||
|
qreal rot = 0.;
|
||||||
|
if(oldTarget) {
|
||||||
|
const auto targetPos = oldTarget->getPivotAbsPos();
|
||||||
|
const auto parentPos = parent->getPivotAbsPos();
|
||||||
|
|
||||||
|
const qreal trackAngle = calculateTrackAngle(parentPos, targetPos);
|
||||||
|
rot += trackAngle*infl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newTarget) {
|
||||||
|
const auto targetPos = newTarget->getPivotAbsPos();
|
||||||
|
const auto parentPos = parent->getPivotAbsPos();
|
||||||
|
|
||||||
|
const qreal trackAngle = calculateTrackAngle(parentPos, targetPos);
|
||||||
|
rot -= trackAngle*infl;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent->startRotTransform();
|
||||||
|
parent->rotateBy(rot);
|
||||||
|
}
|
||||||
|
|
||||||
void TrackTransformEffect::applyEffect(
|
void TrackTransformEffect::applyEffect(
|
||||||
const qreal relFrame,
|
const qreal relFrame,
|
||||||
qreal& pivotX, qreal& pivotY,
|
qreal& pivotX, qreal& pivotY,
|
||||||
@ -54,12 +91,7 @@ void TrackTransformEffect::applyEffect(
|
|||||||
const auto targetPos = target->getPivotAbsPos(targetRelFrame);
|
const auto targetPos = target->getPivotAbsPos(targetRelFrame);
|
||||||
const auto parentPos = parent->getPivotAbsPos(relFrame);
|
const auto parentPos = parent->getPivotAbsPos(relFrame);
|
||||||
|
|
||||||
const QLineF baseLine(parentPos, parentPos + QPointF(100., 0.));
|
|
||||||
const QLineF trackLine(parentPos, targetPos);
|
|
||||||
qreal trackAngle = trackLine.angleTo(baseLine);
|
|
||||||
if(trackAngle > 180) trackAngle -= 360;
|
|
||||||
|
|
||||||
const qreal infl = mInfluence->getEffectiveValue(relFrame);
|
const qreal infl = mInfluence->getEffectiveValue(relFrame);
|
||||||
|
const qreal trackAngle = calculateTrackAngle(parentPos, targetPos);
|
||||||
rot += trackAngle*infl;
|
rot += trackAngle*infl;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,10 @@ public:
|
|||||||
qreal &shearX, qreal &shearY,
|
qreal &shearX, qreal &shearY,
|
||||||
BoundingBox* const parent) override;
|
BoundingBox* const parent) override;
|
||||||
private:
|
private:
|
||||||
|
void setRotScaleAfterTargetChange(
|
||||||
|
BoundingBox* const oldTarget,
|
||||||
|
BoundingBox* const newTarget) override;
|
||||||
|
|
||||||
qsptr<QrealAnimator> mInfluence;
|
qsptr<QrealAnimator> mInfluence;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -305,8 +305,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
QRect getCurrentBounds() const {
|
QRect getCurrentBounds() const {
|
||||||
if(mClipToCanvasSize) return getCanvasBounds();
|
//if(mClipToCanvasSize) return getCanvasBounds();
|
||||||
else return getMaxBounds();
|
//else return getMaxBounds();
|
||||||
|
return getMaxBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getCanvasHeight() const {
|
int getCanvasHeight() const {
|
||||||
|
Loading…
Reference in New Issue
Block a user