From 35270dbbb408cae8070059029176ef80d634c65d Mon Sep 17 00:00:00 2001 From: lilia Date: Sun, 30 Oct 2016 16:53:17 +0900 Subject: [PATCH] Use timeout-based animation for hourglasses CSS animations are convenient but costly if you have hundreds of them. Fixes #945 --- js/views/message_view.js | 17 +++++++++++++---- stylesheets/_hourglass.scss | 5 ----- stylesheets/manifest.css | 22 ++++------------------ 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/js/views/message_view.js b/js/views/message_view.js index 03a1e84c..c342e741 100644 --- a/js/views/message_view.js +++ b/js/views/message_view.js @@ -29,14 +29,20 @@ templateName: 'hourglass', className: 'timer', initialize: function() { + this.update(); + }, + update: function() { + if (this.timeout) { + clearTimeout(this.timeout); + this.timeout = null; + } if (this.model.isExpiring()) { this.render(); var totalTime = this.model.get('expireTimer') * 1000; var remainingTime = this.model.msTilExpire(); var elapsed = (totalTime - remainingTime) / totalTime; - this.$('.sand') - .css('animation-duration', remainingTime*0.001 + 's') - .css('transform', 'translateY(' + elapsed*100 + '%)'); + this.$('.sand').css('transform', 'translateY(' + elapsed*100 + '%)'); + this.timeout = setTimeout(this.update.bind(this), totalTime / 100); this.$el.css('display', 'inline-block'); } return this; @@ -201,7 +207,10 @@ } }, renderExpiring: function() { - new TimerView({ model: this.model, el: this.$('.timer') }); + if (!this.timerView) { + this.timerView = new TimerView({ model: this.model, el: this.$('.timer') }); + } + this.timerView.update(); }, render: function() { var contact = this.model.isIncoming() ? this.model.getContact() : null; diff --git a/stylesheets/_hourglass.scss b/stylesheets/_hourglass.scss index e8bff4d6..cd859bfd 100644 --- a/stylesheets/_hourglass.scss +++ b/stylesheets/_hourglass.scss @@ -17,13 +17,8 @@ } .sand { background: $color; - animation: moveDown steps(100); - animation-fill-mode: forwards; } &:after { @include color-svg('/images/hourglass_empty.svg', $color); } - @keyframes moveDown { - to { transform: translateY(100%); } - } } diff --git a/stylesheets/manifest.css b/stylesheets/manifest.css index b562f5ce..0a55c0b8 100644 --- a/stylesheets/manifest.css +++ b/stylesheets/manifest.css @@ -1538,16 +1538,12 @@ li.entry .error-icon-container { top: 0; left: 0; } .ios .hourglass .sand { - background: #999; - animation: moveDown steps(100); - animation-fill-mode: forwards; } + background: #999; } .ios .hourglass:after { -webkit-mask: url("/images/hourglass_empty.svg") no-repeat center; -webkit-mask-size: 100%; background-color: #999; } -@keyframes moveDown { - to { - transform: translateY(100%); } } + .android #header { background-color: #2090ea; color: white; @@ -1618,16 +1614,11 @@ li.entry .error-icon-container { top: 0; left: 0; } .android .outgoing .hourglass .sand { - background: #999; - animation: moveDown steps(100); - animation-fill-mode: forwards; } + background: #999; } .android .outgoing .hourglass:after { -webkit-mask: url("/images/hourglass_empty.svg") no-repeat center; -webkit-mask-size: 100%; background-color: #999; } -@keyframes moveDown { - to { - transform: translateY(100%); } } .android .incoming .hourglass { display: inline-block; position: relative; @@ -1645,16 +1636,11 @@ li.entry .error-icon-container { top: 0; left: 0; } .android .incoming .hourglass .sand { - background: #fff; - animation: moveDown steps(100); - animation-fill-mode: forwards; } + background: #fff; } .android .incoming .hourglass:after { -webkit-mask: url("/images/hourglass_empty.svg") no-repeat center; -webkit-mask-size: 100%; background-color: #fff; } -@keyframes moveDown { - to { - transform: translateY(100%); } } .android .incoming .bubble .sender, .android .incoming .bubble .content, .android .incoming .bubble .body, .android .incoming .bubble .meta, .android .incoming .bubble a { color: white; } .android .incoming .bubble .sender::selection, .android .incoming .bubble .content::selection, .android .incoming .bubble .body::selection, .android .incoming .bubble .meta::selection, .android .incoming .bubble a::selection {