mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-07 13:35:09 +00:00
lottie: don't redraw path item if its properties are not changed
A path item has few animation frames, it has to be redrawn only in animated frames. If the path item became static after animation frames, it shouldn't redraw its path. It will improve performance. Change-Id: I583f2b8a889208a07530f6d06ed90469bcee726c
This commit is contained in:
1
example/resource/dynamic_path_test.json
Normal file
1
example/resource/dynamic_path_test.json
Normal file
@@ -0,0 +1 @@
|
||||
{"v":"5.1.17","fr":29.9700012207031,"ip":0,"op":150.000006109625,"w":300,"h":300,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":20,"s":[135,135],"e":[116,116]},{"t":137.000005580124}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[24,25],"e":[57,52],"to":[5.5,4.5],"ti":[-5.5,-4.5]},{"t":129.000005254278}],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[54]},{"t":149.000006068894}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100],"e":[50,50]},{"t":40.0000016292334}],"ix":2},"p":{"a":0,"k":[-26,-37],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.145327582955,0.057777773589,0.866666674614,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[26,-54],"ix":4},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":110,"s":[0],"e":[184]},{"t":149.000006068894}],"ix":5},"ir":{"a":0,"k":30,"ix":6},"is":{"a":0,"k":27,"ix":8},"or":{"a":0,"k":59,"ix":7},"os":{"a":0,"k":73,"ix":9},"ix":5,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.07993286103,0.716212213039,0.766274511814,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 3","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":150.000006109625,"st":0,"bm":0}],"markers":[]}
|
||||
@@ -669,7 +669,7 @@ void LOTPathDataItem::update(int frameNo, const VMatrix &parentMatrix,
|
||||
mCombinedAlpha = parentAlpha;
|
||||
|
||||
// 1. update the local path if needed
|
||||
if (!(mInit && mStaticPath)) {
|
||||
if (!(mInit && mStaticPath) && hasChanged(frameNo)) {
|
||||
updatePath(mLocalPath, frameNo);
|
||||
mInit = true;
|
||||
mPathChanged = true;
|
||||
@@ -731,12 +731,13 @@ void LOTRectItem::updatePath(VPath& path, int frameNo)
|
||||
{
|
||||
VPointF pos = mData->mPos.value(frameNo);
|
||||
VPointF size = mData->mSize.value(frameNo);
|
||||
float radius = mData->mRound.value(frameNo);
|
||||
float roundness = mData->mRound.value(frameNo);
|
||||
VRectF r(pos.x() - size.x() / 2, pos.y() - size.y() / 2, size.x(),
|
||||
size.y());
|
||||
|
||||
path.reset();
|
||||
path.addRoundRect(r, radius, radius, mData->direction());
|
||||
path.addRoundRect(r, roundness, roundness, mData->direction());
|
||||
updateCache(frameNo, pos, size, roundness);
|
||||
}
|
||||
|
||||
LOTEllipseItem::LOTEllipseItem(LOTEllipseData *data)
|
||||
@@ -753,6 +754,7 @@ void LOTEllipseItem::updatePath(VPath& path, int frameNo)
|
||||
|
||||
path.reset();
|
||||
path.addOval(r, mData->direction());
|
||||
updateCache(frameNo, pos, size);
|
||||
}
|
||||
|
||||
LOTShapeItem::LOTShapeItem(LOTShapeData *data)
|
||||
@@ -794,6 +796,8 @@ void LOTPolystarItem::updatePath(VPath& path, int frameNo)
|
||||
m.translate(pos.x(), pos.y()).rotate(rotation);
|
||||
m.rotate(rotation);
|
||||
path.transform(m);
|
||||
updateCache(frameNo, pos, points, innerRadius, outerRadius,
|
||||
innerRoundness, outerRoundness, rotation);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -226,6 +226,7 @@ private:
|
||||
float mCombinedAlpha;
|
||||
protected:
|
||||
virtual void updatePath(VPath& path, int frameNo) = 0;
|
||||
virtual bool hasChanged(int frameNo) = 0;
|
||||
};
|
||||
|
||||
class LOTRectItem: public LOTPathDataItem
|
||||
@@ -235,6 +236,35 @@ public:
|
||||
protected:
|
||||
void updatePath(VPath& path, int frameNo) final;
|
||||
LOTRectData *mData;
|
||||
|
||||
struct Cache {
|
||||
int mFrameNo;
|
||||
VPointF mPos;
|
||||
VPointF mSize;
|
||||
float mRoundness;
|
||||
};
|
||||
Cache mCache;
|
||||
|
||||
void updateCache(int frameNo, VPointF pos, VPointF size, float roundness) {
|
||||
mCache.mFrameNo = frameNo;
|
||||
mCache.mPos = pos;
|
||||
mCache.mSize = size;
|
||||
mCache.mRoundness = roundness;
|
||||
}
|
||||
bool hasChanged(int frameNo) final {
|
||||
if (mCache.mFrameNo == frameNo) return false;
|
||||
|
||||
VPointF pos = mData->mPos.value(frameNo);
|
||||
VPointF size = mData->mSize.value(frameNo);
|
||||
float roundness = mData->mRound.value(frameNo);
|
||||
|
||||
if (vCompare(mCache.mPos.x(), pos.x()) && vCompare(mCache.mPos.y(), pos.y()) &&
|
||||
vCompare(mCache.mSize.x(), size.x()) && vCompare(mCache.mSize.y(), size.y()) &&
|
||||
vCompare(mCache.mRoundness, roundness))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LOTEllipseItem: public LOTPathDataItem
|
||||
@@ -244,6 +274,31 @@ public:
|
||||
private:
|
||||
void updatePath(VPath& path, int frameNo) final;
|
||||
LOTEllipseData *mData;
|
||||
|
||||
struct Cache {
|
||||
int mFrameNo;
|
||||
VPointF mPos;
|
||||
VPointF mSize;
|
||||
};
|
||||
Cache mCache;
|
||||
|
||||
void updateCache(int frameNo, VPointF pos, VPointF size) {
|
||||
mCache.mFrameNo = frameNo;
|
||||
mCache.mPos = pos;
|
||||
mCache.mSize = size;
|
||||
}
|
||||
bool hasChanged(int frameNo) final {
|
||||
if (mCache.mFrameNo == frameNo) return false;
|
||||
|
||||
VPointF pos = mData->mPos.value(frameNo);
|
||||
VPointF size = mData->mSize.value(frameNo);
|
||||
|
||||
if (vCompare(mCache.mPos.x(), pos.x()) && vCompare(mCache.mPos.y(), pos.y()) &&
|
||||
vCompare(mCache.mSize.x(), size.x()) && vCompare(mCache.mSize.y(), size.y()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LOTShapeItem: public LOTPathDataItem
|
||||
@@ -253,6 +308,7 @@ public:
|
||||
private:
|
||||
void updatePath(VPath& path, int frameNo) final;
|
||||
LOTShapeData *mData;
|
||||
bool hasChanged(int frameNo) final { return true; }
|
||||
};
|
||||
|
||||
class LOTPolystarItem: public LOTPathDataItem
|
||||
@@ -262,6 +318,49 @@ public:
|
||||
private:
|
||||
void updatePath(VPath& path, int frameNo) final;
|
||||
LOTPolystarData *mData;
|
||||
|
||||
struct Cache {
|
||||
int mFrameNo;
|
||||
VPointF mPos;
|
||||
float mPoints;
|
||||
float mInnerRadius;
|
||||
float mOuterRadius;
|
||||
float mInnerRoundness;
|
||||
float mOuterRoundness;
|
||||
float mRotation;
|
||||
};
|
||||
Cache mCache;
|
||||
|
||||
void updateCache(int frameNo, VPointF pos, float points, float innerRadius, float outerRadius,
|
||||
float innerRoundness, float outerRoundness, float rotation) {
|
||||
mCache.mFrameNo = frameNo;
|
||||
mCache.mPos = pos;
|
||||
mCache.mPoints = points;
|
||||
mCache.mInnerRadius = innerRadius;
|
||||
mCache.mOuterRadius = outerRadius;
|
||||
mCache.mInnerRoundness = innerRoundness;
|
||||
mCache.mOuterRoundness = outerRoundness;
|
||||
mCache.mRotation = rotation;
|
||||
}
|
||||
bool hasChanged(int frameNo) final {
|
||||
if (mCache.mFrameNo == frameNo) return false;
|
||||
|
||||
VPointF pos = mData->mPos.value(frameNo);
|
||||
float points = mData->mPointCount.value(frameNo);
|
||||
float innerRadius = mData->mInnerRadius.value(frameNo);
|
||||
float outerRadius = mData->mOuterRadius.value(frameNo);
|
||||
float innerRoundness = mData->mInnerRoundness.value(frameNo);
|
||||
float outerRoundness = mData->mOuterRoundness.value(frameNo);
|
||||
float rotation = mData->mRotation.value(frameNo);
|
||||
|
||||
if (vCompare(mCache.mPos.x(), pos.x()) && vCompare(mCache.mPos.y(), pos.y()) &&
|
||||
vCompare(mCache.mPoints, points) && vCompare(mCache.mRotation, rotation) &&
|
||||
vCompare(mCache.mInnerRadius, innerRadius) && vCompare(mCache.mOuterRadius, outerRadius) &&
|
||||
vCompare(mCache.mInnerRoundness, innerRoundness) && vCompare(mCache.mOuterRoundness, outerRoundness))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user