← Back to team overview

openlp-dev team mailing list archive

[Merge] lp:~ic90/openlp/animated-alerts into lp:~openlp-dev/openlp/webengine-migrate

 

Nico Opiyo has proposed merging lp:~ic90/openlp/animated-alerts into lp:~openlp-dev/openlp/webengine-migrate.

Commit message:
Added animations to the alerts

Requested reviews:
  OpenLP Development (openlp-dev)

For more details, see:
https://code.launchpad.net/~ic90/openlp/animated-alerts/+merge/362178

This branch adds a scrolling animation to the alert text and adds entrance and exit transition effects to the alert background.
-- 
Your team OpenLP Development is requested to review the proposed merge of lp:~ic90/openlp/animated-alerts into lp:~openlp-dev/openlp/webengine-migrate.
=== modified file '.bzrignore'
--- .bzrignore	2018-09-07 06:43:01 +0000
+++ .bzrignore	2019-01-24 09:02:30 +0000
@@ -53,3 +53,4 @@
 .cache
 test
 tests.kdev4
+venv

=== modified file 'openlp/core/display/html/display.html'
--- openlp/core/display/html/display.html	2018-10-12 19:51:51 +0000
+++ openlp/core/display/html/display.html	2019-01-24 09:02:30 +0000
@@ -24,14 +24,91 @@
       visibility: visible;
       z-index: -1;
     }
+
+    /* Animation key frames for horizontal scrolling of alert */
+    @keyframes alert-scrolling-text {
+        from { margin-left: 100%; }
+        to {  margin-left: -300% }
+    }
+    /* Middle fade-in alert animation */
+    @keyframes middle-fade-in {
+        from { opacity: 0;}
+        to { opacity: 1;}
+    }
+
+    /* Middle fade-out alert animation */
+    @keyframes middle-fade-out {
+        from { opacity: 1;}
+        to { opacity: 0;}
+    }
+
+    /* Fade in when alert location is in the middle */
+    .middle-entrance-animation {
+        animation-duration: 2s;
+        animation-timing-function: linear;
+        animation-name: middle-fade-in;
+    }
+
+    /* Fade out when alert location is in the middle */
+    .middle-exit-animation {
+        animation-duration: 2s;
+        animation-timing-function: linear;
+        animation-name: middle-fade-out;
+    }
+
+    .horizontal-scroll-animation {
+        animation-duration: 10s;
+        animation-iteration-count: 1;
+        animation-timing-function: linear;
+        animation-name: alert-scrolling-text;
+    }
+
+    /* ALERT STYLING */
+    #alert-background {
+        position: absolute;
+        margin: 0;
+        padding: 0;
+        left: 0px;
+        right: 0px;
+        z-index: 10;
+        width: 100%;
+        height: 25%;
+        vertical-align: middle;
+        color: #ffffff;
+        background-color: #660000;
+        overflow: hidden;
+        visibility:hidden;
+    }
+
+    #alert {
+        position: relative;
+        top: 50%
+        transform: translateY(-50%);
+        margin-top: 0%;
+        margin-right: 0%;
+        margin-left: 100%;
+        margin-bottom: 0%;
+        z-index: 11;
+        overflow: visible;
+        white-space: nowrap;
+        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+        font-size: 100pt;
+        color: #ffffff;
+        visibility: hidden;
+    }
+
+
+
     </style>
     <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
     <script type="text/javascript" src="reveal.js"></script>
     <script type="text/javascript" src="display.js"></script>
   </head>
+
   <body>
     <div class="reveal">
       <div id="global-background" class="slide-background present" data-loaded="true"></div>
+      <div id="alert-background"><p id="alert">Testing alerts</p></div>
       <div class="slides"></div>
       <div class="footer"></div>
     </div>

=== modified file 'openlp/core/display/html/display.js'
--- openlp/core/display/html/display.js	2018-12-06 20:26:35 +0000
+++ openlp/core/display/html/display.js	2019-01-24 09:02:30 +0000
@@ -52,6 +52,31 @@
   Stopped: "stopped"
 };
 
+/** 
+ * Transition state enumeration 
+ */
+
+var TransitionState = {
+   EntranceTransition: "entranceTransition",
+   NoTransition: "noTransition",
+   ExitTransition: "exitTransition"
+};
+
+/**
+ * Animation state enumeration
+ */
+var AnimationState = {
+  NoAnimation: "noAnimation",
+  ScrollingAnimation: "scrollingAnimation",
+  FadeInAnimation: "fadeInAnimation",
+  FadeOutAnimation: "fadeOutAnimation"
+};
+
+/**
+ * 
+ * @param {Location} selector 
+ */
+
 /**
  * Return an array of elements based on the selector query
  * @param {string} selector - The selector to find elements
@@ -132,6 +157,10 @@
 }
 
 /**
+ * 
+ */
+
+/**
  * An audio player with a play list
  */
 var AudioPlayer = function (audioElement) {
@@ -249,6 +278,8 @@
  */
 var Display = {
   _slides: {},
+  _transitionState: TransitionState.NoTransition,
+  _animationState: AnimationState.NoAnimation,
   _revealConfig: {
     margin: 0.0,
     minScale: 1.0,
@@ -372,14 +403,124 @@
    * @param {string} text - The alert text
    * @param {int} location - The location of the text (top, middle or bottom)
   */
- alert: function (text, location) {
-  console.debug(" alert text: " + text, ", location: " + location);
+  alert: function (text, location) {
+    console.debug(" alert text: " + text + ", location: " + location);
+
+    if(text == ""){
+      return null;
+    }
+
+    var alertBackground = $("#alert-background")[0];
+    var alertText = $("#alert")[0];
+
+    alertText.innerHTML = text;
+
+    /* Bring in the transition background */
+    Display._transitionState = Display.alertEntranceTransition(location);
+
+    alertBackground.addEventListener('transitionend', function(e){
+      e.stopPropagation();
+      console.debug("Transition end event captured");
+      if(Display._transitionState == TransitionState.EntranceTransition){
+        console.debug("Entrance Transition Condition");
+        alertText.style.visibility = "visible";
+        alertText.classList.add("horizontal-scroll-animation");
+      }else if(Display._transitionState == TransitionState.ExitTransition){
+        console.debug("Exit Transition Condition");
+        Display._transitionState = TransitionState.NoTransition;
+        alertBackground.style.visibility = "hidden";
+        alertBackground.classList.remove("middle-exit-animation");
+      }
+    });
+
+    alertBackground.addEventListener('animationend',function(){
+      
+      console.debug("Noticed an animation has ended. The animation state is: ", Display._animationState);
+      if(Display._animationState == AnimationState.FadeInAnimation){
+        console.debug("Entrance Animation Condition");
+        alertText.style.visibility = "visible";
+        alertText.classList.add("horizontal-scroll-animation");
+        alertText.classList.remove("middle-entrance-animation");
+        Display._animationState = AnimationState.ScrollingAnimation;
+      }else if(Display._animationState == AnimationState.FadeOutAnimation){
+        console.debug("Exit Animation Condition");
+        alertBackground.style.visibility = "hidden";
+        alertBackground.classList.remove("middle-exit-animation");
+        Display._animationState = AnimationState.NoAnimation;
+      }else if(alertText.classList.contains("horizontal-scroll-animation")){
+        console.debug("Scrolling Animation Ended");
+        alertText.classList.remove("horizontal-scroll-animation");
+        Display._animationState = AnimationState.NoAnimation;
+        Display._transitionState = Display.alertExitTransition(location);        
+      }
+
+    });
+
   /*
    * The implementation should show an alert.
    * It should be able to handle receiving a new alert before a previous one is "finished", basically queueing it.
    */
-  return;
-},
+  //return;
+  },
+
+  /**
+   * Start background entrance transition for display of alert
+   * @param {string} location - String showing the location of the alert on screen
+   */
+  alertEntranceTransition: function (location){
+    console.debug("Alert Entrance Transition Method. The value of animation state is: " + Display._animationState);
+    var alertBackground = $("#alert-background")[0];
+
+    switch(location){
+      case "0":
+        console.debug("Top Location Entrance Transition");
+        alertBackground.style.top = '0';
+        alertBackground.style.transition = "2s linear";
+        alertBackground.style.height = "25%";
+        break;
+      case "1":
+        console.debug("Middle Location Entrance Animation");
+        console.debug("The value of animation state is: " + Display._animationState);
+        alertBackground.style.top = ((window.innerHeight - alertBackground.clientHeight) / 2)
+            + 'px';
+        alertBackground.classList.add("middle-entrance-animation");
+        Display._animationState = AnimationState.FadeInAnimation;
+        break;
+      case "2":
+      default:
+        console.debug("Bottom Location Entrance Transition");
+        alertBackground.style.bottom = '0';
+        alertBackground.style.transition= "2s linear";
+        alertBackground.style.height = "25%";
+        break;
+    }
+    alertBackground.style.visibility = "visible";
+    return TransitionState.EntranceTransition;
+
+  },
+
+  /**
+   * Start background exit transition once alert has been displayed
+   * @param {string} location - Integer showing the location of the alert on screen 
+   */
+  alertExitTransition: function(location){
+
+    console.debug("Alert Exit Transition");
+    var alertBackground = $("#alert-background")[0];
+    
+    if(location == "0" || location == "2"){
+      console.debug("Exit Transition for top or bottom");
+      alertBackground.style.height = "0%";
+      alertBackground.style.transition = '2s linear';
+    }else if(location == "1"){
+      // alertBackground.style.opacity = 0;
+      console.debug("Fade out Animation");
+      alertBackground.classList.add("middle-exit-animation");
+      Display._animationState = AnimationState.FadeOutAnimation;
+    }
+
+    return TransitionState.ExitTransition;
+  },
 
   /**
    * Add a slides. If the slide exists but the HTML is different, update the slide.

=== modified file 'openlp/core/display/window.py'
--- openlp/core/display/window.py	2018-12-06 20:26:35 +0000
+++ openlp/core/display/window.py	2019-01-24 09:02:30 +0000
@@ -401,4 +401,4 @@
         """
         Set an alert
         """
-        self.run_javascript('Display.alert({text}, {location});'.format(text=text, location=location))
+        self.run_javascript('Display.alert("{text}", "{location}");'.format(text=text, location=location))

=== modified file 'package.json'
--- package.json	2019-01-16 06:15:21 +0000
+++ package.json	2019-01-24 09:02:30 +0000
@@ -20,6 +20,7 @@
   "author": "OpenLP Developers",
   "license": "GPL-2.0",
   "devDependencies": {
+    "karma": "^3.1.4",
     "karma-log-reporter": "0.0.4"
   }
 }

=== modified file 'tests/js/test_display.js'
--- tests/js/test_display.js	2019-01-16 06:15:21 +0000
+++ tests/js/test_display.js	2019-01-24 09:02:30 +0000
@@ -18,6 +18,14 @@
   it("AudioState should exist", function () {
     expect(AudioState).toBeDefined();
   });
+
+  it("TransitionState should exist", function(){
+    expect(TransitionState).toBeDefined();
+  });
+
+  it("AnimationState should exist", function(){
+    expect(AnimationState).toBeDefined();
+  });
 });
 
 describe("The function", function () {
@@ -138,7 +146,46 @@
     Display.goToSlide("v1");
     expect(Reveal.slide).toHaveBeenCalledWith(0);
   });
-});
+
+  it("should have an alert() method", function () {
+    expect(Display.alert).toBeDefined();
+  });
+
+  it("should have a correctly functioning alert() method", function (){
+    spyOn(Display,"alert");
+    Display.alert("OPEN-LP-3.0 Alert Test", "2");
+    expect(Display.alert).toHaveBeenCalledWith("OPEN-LP-3.0 Alert Test", "2");
+  });
+
+});
+
+describe("Display.alert",function(){
+    beforeEach(function(){
+      var alertBackground = document.getElementById("alert-background");
+      var alertText = document.getElementById("alert");
+    });
+
+   it("should return if called without any text", function(){
+    spyOn(Display, "alert");
+    Display.alert("", "2");
+    expect(Display.alert).toHaveBeenCalled();
+   });
+
+   it("should call alertEntranceTransition", function(){
+    spyOn(Display,"alertEntranceTransition");
+    Display.alertEntranceTransition("2");
+    expect(Display.alertEntranceTransition).toHaveBeenCalledWith("2");
+   });
+
+   it("should call alertExitTransition", function(){
+    spyOn(Display,"alertExitTransition");
+    Display.alertExitTransition("2");
+    expect(Display.alertExitTransition).toHaveBeenCalledWith("2");
+   });
+});
+
+
+
 
 describe("Display.addTextSlide", function () {
   beforeEach(function() {