aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Fadel <samuelfadel@gmail.com>2015-10-05 13:02:23 -0300
committerSamuel Fadel <samuelfadel@gmail.com>2015-10-05 13:02:23 -0300
commite1e268ebbcd8f0d29b8faa187dde6981f82b027f (patch)
treee0d8d819c781e595fd9347ead8c1bdc4ddec0767
parent33bc0020b7c4f47eeedb92365c2578614d61fb97 (diff)
Initial (rudimentary) animation implementation.
Animation plays when setXY() is called on Scatterplot, providing a "smooth" transition for the new position of each point.
-rw-r--r--scatterplot.cpp37
-rw-r--r--scatterplot.h7
2 files changed, 37 insertions, 7 deletions
diff --git a/scatterplot.cpp b/scatterplot.cpp
index e22eafd..35639e6 100644
--- a/scatterplot.cpp
+++ b/scatterplot.cpp
@@ -57,16 +57,21 @@ void Scatterplot::setXY(const arma::mat &xy)
}
if (m_xy.n_elem != xy.n_elem) {
+ m_oldXY = xy;
m_selectedGlyphs.clear();
+ } else {
+ m_oldXY = m_xy;
}
m_xy = xy;
- m_sx.setDomain(m_xy.col(0).min(), m_xy.col(0).max());
- m_sy.setDomain(m_xy.col(1).min(), m_xy.col(1).max());
+ m_sx.setDomain(m_oldXY.col(0).min(), m_oldXY.col(0).max());
+ m_sy.setDomain(m_oldXY.col(1).min(), m_oldXY.col(1).max());
updateGeometry();
emit xyChanged(m_xy);
+
+ startAnimation();
}
void Scatterplot::setColorData(const arma::vec &colorData)
@@ -168,7 +173,8 @@ QSGNode *Scatterplot::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
QSGNode *node = root->firstChild()->firstChild();
for (arma::uword i = 0; i < m_xy.n_rows; i++) {
- arma::rowvec row = m_xy.row(i);
+ const arma::rowvec &oldRow = m_oldXY.row(i);
+ const arma::rowvec &row = m_xy.row(i);
bool isSelected = m_selectedGlyphs.contains(i);
QSGOpacityNode *glyphOpacityNode = static_cast<QSGOpacityNode *>(node);
@@ -178,8 +184,8 @@ QSGNode *Scatterplot::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
QSGGeometryNode *glyphNode = static_cast<QSGGeometryNode *>(node->firstChild()->nextSibling());
if (m_shouldUpdateGeometry) {
moveTranslationF = isSelected ? 1.0 : 0.0;
- x = m_sx(row[0]) + tx * moveTranslationF;
- y = m_sy(row[1]) + ty * moveTranslationF;
+ x = m_sx(m_t*row[0] + (1 - m_t)*oldRow[0]) + tx * moveTranslationF;
+ y = m_sy(m_t*row[1] + (1 - m_t)*oldRow[1]) + ty * moveTranslationF;
QSGGeometry *geometry = glyphOutlineNode->geometry();
updateCircleGeometry(geometry, GLYPH_SIZE / 2, x, y);
@@ -222,15 +228,34 @@ QSGNode *Scatterplot::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
} else {
node = root->firstChild()->nextSibling();
if (node) {
- // node->markDirty(QSGNode::DirtyGeometry);
root->removeChildNode(node);
delete node;
}
}
+ animationTick();
return root;
}
+void Scatterplot::resetAnimation()
+{
+ m_t = 0;
+}
+
+void Scatterplot::startAnimation()
+{
+ resetAnimation();
+ update();
+}
+
+void Scatterplot::animationTick()
+{
+ if (m_t < 1.f) {
+ m_t += 0.1f;
+ updateGeometry();
+ }
+}
+
void Scatterplot::mousePressEvent(QMouseEvent *event)
{
switch (m_currentInteractionState) {
diff --git a/scatterplot.h b/scatterplot.h
index 2dc031a..63a7e6e 100644
--- a/scatterplot.h
+++ b/scatterplot.h
@@ -44,7 +44,11 @@ private:
void updateGeometry();
void updateMaterials();
- arma::mat m_xy;
+ void resetAnimation();
+ void startAnimation();
+ void animationTick();
+
+ arma::mat m_oldXY, m_xy;
LinearScale m_sx, m_sy;
enum InteractionState {
@@ -63,6 +67,7 @@ private:
arma::vec m_colorData;
ColorScale *m_colorScale;
+ float m_t;
};
#endif // SCATTERPLOT_H