Parcourir la source

Replace conversation loading CSS animation with GIF (#264)

The animation runs a bit less smooth but is more efficient on the CPU in less optimized browsers.
Danilo Bargen il y a 8 ans
Parent
commit
36a7da3c49

BIN
public/img/spinner.gif


+ 1 - 1
src/partials/messenger.conversation.html

@@ -39,7 +39,7 @@
         <ul class="chat">
             <li in-view="$inview && !ctrl.locked && ctrl.topOfChat()" class="load-more">
                 <div ng-if="ctrl.hasMoreMessages()" class="loading">
-                    <span></span>
+                    <img ng-src="img/spinner.gif" alt="...">
                 </div>
             </li>
             <li ng-repeat="message in ctrl.messages" id="message-{{message.id}}">

+ 4 - 3
src/sass/sections/_conversation.scss

@@ -126,11 +126,12 @@
             margin-top: $main-padding;
             text-align: center;
             .loading {
-                @include loading-spinner(24px, 3px, $material-grey-dark, rgba(0, 0, 0, 0.1));
+                height: 30px;
+                width: 30px;
                 background-color: white;
                 border-radius: 50%;
-                display:inline-block;
-                padding: $main-padding;
+                display: inline-block;
+                padding: 6px;
                 @include message-bubble-shadow;
             }
         }

+ 2 - 0
tools/spinner/.gitignore

@@ -0,0 +1,2 @@
+spinner-*.png
+spinner.gif

+ 45 - 0
tools/spinner/1-export.py

@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+"""
+Export spinner as GIF.
+
+Dependencies:
+
+ - Python 3.5+
+ - Inkscape
+
+"""
+import subprocess
+import tempfile
+
+
+FRAMES = 30
+
+
+def create_png(rotation: int) -> None:
+    with tempfile.NamedTemporaryFile(mode='w', encoding='utf-8',
+                                     prefix='threema-web-spinner-', suffix='.svg') as f:
+        # Write rotated SVG to temporary file
+        f.write(svg.replace('rotate(132,15,15)', 'rotate(%d,15,15)' % rotation))
+        f.flush()
+
+        # Convert to PNG
+        filename = 'spinner-{:0>3}.png'.format(rotation)
+        print('Creating %s...' % filename)
+        result = subprocess.run([
+            'inkscape',
+            '-z',
+            '-e', filename,
+            '-w', '30',
+            '-h', '30',
+            '-b', 'white',
+            f.name,
+        ])
+        result.check_returncode()
+
+
+if __name__ == '__main__':
+    with open('spinner.svg', 'r') as f:
+        svg = f.read()
+
+    for i in range(FRAMES):
+        create_png(int(360 / FRAMES * i))

+ 12 - 0
tools/spinner/2-concat.sh

@@ -0,0 +1,12 @@
+#!/bin/bash
+# Create animated GIF.
+#
+# Dependencies:
+#
+#  - Imagemagick
+
+duration=1100
+framecount=30
+delay=$(bc -l <<< "$duration / $framecount / 10")
+
+convert -delay $delay -loop 0 -colors 24 spinner-*.png spinner.gif

+ 82 - 0
tools/spinner/spinner.svg

@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="30mm"
+   height="30mm"
+   viewBox="0 0 30 30"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.1 r"
+   sodipodi:docname="spinner.svg">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2"
+     inkscape:cx="44.855512"
+     inkscape:cy="20.443514"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1534"
+     inkscape:window-height="1063"
+     inkscape:window-x="0"
+     inkscape:window-y="15"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Tavolo 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       id="g4494"
+       transform="rotate(132,15,15)">
+      <circle
+         r="13.5"
+         cy="15"
+         cx="15"
+         id="path4485-4"
+         style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.1" />
+      <path
+         sodipodi:cx="15"
+         sodipodi:cy="15"
+         sodipodi:rx="13.5"
+         sodipodi:ry="13.5"
+         sodipodi:end="1.5707963"
+         sodipodi:start="0"
+         sodipodi:open="true"
+         sodipodi:type="arc"
+         d="M 28.5,15 A 13.5,13.5 0 0 1 15,28.5"
+         id="path4485-4-8"
+         style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.88999999" />
+    </g>
+  </g>
+</svg>