Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

SwipeClouds JQuery Mobile Framework for PhoneGap & Cordova Mobile Apps

5.00/5 (9 votes)
12 Aug 2013CPOL4 min read 31.9K   488  
SwipeClouds HTML5 Canvas Framework for JQuery Mobile, PhoneGap & Cordova

SwipeClouds

Summary

To view a working demo of Swipe Clouds Click Here. Swipe Clouds for PhoneGap & Cordova.  

To view a video illustrating the features of SwipeClouds in a mobile app for drones Click Here

In an effort to create an interface that people might enjoy for my JQuery Mobile Apps I decided to try using html5 Tag Canvas. For this project I used as a starting point TagCanvas, a JQuery Plugin, by  Graham      Breach, which was the best Tag Canvas example I found. But It took some tweeking to eliminate jerky movements when swiping on mobile phones in PhoneGap builds but I finally got things working nicely.And I thought I would share it here.  The SwipeClouds Framework for JQuery Mobile in this article is designed for Jquery Mobile. I recently re-designed the entire FRamework for Angular 2 and you can find that source and updated versions of this framework at:

http://www.SwipeClouds.com

and my article for the Angular 2 SwipeClouds Framework is here on CodeProject at:

https://www.codeproject.com/Articles/1175045/Angular-Mobile-App-with-JQuery-Mobile-Cordova-or-P

Introduction

Since in a mobile app you swipe the clouds to move them around I thought Swipe Clouds was descriptive and an appropriate name. There are some basic considerations in making Swipe Clouds work correctly in mobile browsers like re-sizing the Cloud when necessary. You can immediately see that we need to do something to automatically adjust the size of this canvas dynamically. The only additional issue I ran into was that if you have a fixed footer you may want to adjust the screen size slightly in the landscape view. There are, of course, a number of ways of doing this in a JQuery Mobile App.

What I found was the best way to deal with orientation changes from portrait to landscape in a JQuery Mobile App is to use the following approach:

   $(window).bind('orientationchange', function(e){ 
      var orientation="portrait"; 
      if(window.orientation == -90 || window.orientation == 90) 
         orientation = "landscape"; 
      switch(orientation){ case 'portrait': 
         //$.mobile.fixedToolbars.setTouchToggleEnabled(true); 
         break; 
      case 'landscape': 
         //$.mobile.fixedToolbars.setTouchToggleEnabled(false); break; default: 
         break; 
      }; 
   }); 

Mobile Swipe Cloud Options Like Shape & Lock

There are are a lot of option parameters like shape and lock in these clouds which we can dynamically change at any time. The "lock" parameter prevents the cloud from being moved in the direction specified.       For example, if we set lock='x' this prevents the cloud from being moved in the x direction. To change any options you just pass all the relevant options into the "tagcanvas" function using the array method: 

   function changeshape(s) { 
      $('#wrapper').panel("close"); 
      var locks = {hcylinder: 'x', vcylinder: 'y', hring: 'x', vring: 'y', sphere: ''}; 
      lock = locks[s] || ''; 
      TagCanvas.initial = (lock == 'x' && [0,0.2]) || (lock == 'y' && [0.2,0]) || [0.2,0.2]; 
      cloudShape = s; 
      // Simply in pass the options to change!
      TagCanvas.Start('tagcanvas', cloudID, { 
         <span class="emphasis">shape: s, 
         lock: lock 
      }); </span>
   }

I created a function, namely, loadCloud, that I call to make changes to an existing Swipe Cloud. This function is shown below:

function loadCloud(zCloud, zShape, zZoom) { 
      try { 
         cloudID = zCloud; 
         cloudShape = zShape; 
         cloudZoom = zZoom; 
         TagCanvas.shape = cloudShape; 
         TagCanvas.zoom = cloudZoom; 
         TagCanvas.shape = cloudShape; 
         TagCanvas.zoom = cloudZoom; 
         TagCanvas.weightMode = 'both'; 
         TagCanvas.weightFrom = 'data-weight'; 
         var gradient = { 
            0: '#f00',    // red 
            0.33: '#ff0', // yellow 
            0.66: '#0f0', // green 
            1: '#00f'     // blue 
         }; 
         TagCanvas.weightGradient = gradient; TagCanvas.weight = false; 
         if(cloudID == 'wordCloud') { TagCanvas.weight = true; } 
         var selectedColor = '#000';
         document.getElementById('tagcanvas').style.backgroundImage = 'none'; 
         document.getElementById('tagcanvas').style.backgroundRepeat='no-repeat'; 
         document.getElementById('tagcanvas').style.backgroundColor = '#000'; 
         $('#mainPage').css('background', '#000'); 

         oopts = { 
            textFont: 'Impact,Arial Black,sans-serif', 
            textColour: '#fff', 
            textHeight: 20, 
            minBrightness: 0.2, 
            maxSpeed: 0.07, 
            decel: 0.9, 
            depth: 0.99, 
            outlineColour: '#ff0000', 
            outlineThickness: 2, 
            pulsateTo: 0.6, 
            pulsateTime: 0.5, 
            wheelZoom: true, 
            zoomMin: 0.3, 
            zoomMax: 3, 
            zoomStep: 0.05, 
            frontSelect: true, 
            lock: null, 
            tooltip: 'div', 
            tooltipDelay: 100, 
            tooltipClass: 'sc_menu_tooltip', 
            radiusX: 1, 
            radiusY: 1, 
            radiusZ: 1, 
            stretchX: 1, 
            stretchY: 1, 
            offsetX: 0, 
            offsetY: 0, 
            shuffleTags: false, 
            noSelect: false, 
            noMouse: false, 
            imageScale: 1, 
            paused: false, 
            dragControl: true, 
            dragThreshold: 4, 
            initial: [0.1,-0.1], 
            reverse: true, 
            hideTags: false, 
            shadow: '#ccf', 
            shadowBlur: 3, 
            weight: false, 
            outlineMethod: "outline" 
         }; 

         $('#tagcanvas').tagcanvas(oopts, cloudID); 
         var amt = parseFloat(cloudZoom * 100); 
         $("#zoomslider").slider().val(amt.toFixed(0)); 
         var i, et = document.getElementById(cloudID).childNodes; for(i in et) { 
            et[i].nodeName == 'A' && et[i].addEventListener('click', function(e) { 
               e.preventDefault(); 
               var targetUrl = $(this).attr("role"); 
               if(cloudID != 'pumpkinCloud') { 
                  $("#datatest").html(targetUrl); 
                  $('#inlinecontent').simpledialog2( {'hide': {effect: 'fadeOut',
                    duration: 5000} } ); 
               } else { 
                  var ximage = 'img_pumpkins/' + targetUrl + '.png'; 
                 $('#popupPumpkin img').attr('src', ximage); 
                  $('#popupPumpkin').popup("open"); 
               } 
            }); 
         } 
        screenAdjust(); 
      } catch(e) { 
         document.getElementsByTagName('canvas')[0].style.border='0'; 
      } 
   }

Sliding Panel for User Controls - How to Create iOS7 Frosted Panel Look

I wanted to give users a way access controls for manipulating properties of the Swipe Clouds and I decided on using a sliding panel to hold the user controls for changing properties of the Clouds. The panel code is shown below. To create an iOS7 Frosted Panel Look there are 3 "tricks" I used, namely: Set panel z-index to -1. Prevents controls from being blurred Set Panel's Background to transparent Blur what is under the panel In order to blur or frost what is under the sliding panel I used 2 classes, namely, backfrost_on and backfrost_off, that I add and remove to scroller_player which is the div tag that holds the screen content.   

$("#panel_controls").on("panelbeforeopen", function (event, ui) {
      $('#scroller_player').removeClass('backfrost_off');
      $('#scroller_player').addClass('backfrost_on');
   });

   $("#panel_controls").on("panelbeforeclose", function (event, ui) {
      $('#scroller_player').removeClass('backfrost_on');
      $('#scroller_player').addClass('backfrost_off');
   });

   .frosted::after {
      /* z-index:-1 Only blurs background, NOT controls on panel */
      z-index: -1 !important;
      position: absolute;
      content: "";
      right: 0;
      top: 0;
      width: 100%;
      height: 100%;
      background: rgba(255,255,255,0.5);
      -webkit-filter:blur(8px) brightness(110%);
      -moz-filter: blur(8px);
      -ms-filter: blur(8px);
      -o-filter: blur(8px);
      filter: blur(8px);
    }

    .backfrost_on {
       -webkit-filter:blur(2px) brightness(110%);
       -moz-filter: blur(2px);
       -ms-filter: blur(2px);
       -o-filter: blur(2px);
       filter: blur(2px);
    }
    .backfrost_off {
    }

I decided to make the panel slide out from the right and have the ability to slide up and down so I could add as many controls as I wanted to add for users. In order to make the controls panel slide vertically in case we have a lot of controls or we are landscape view I added added iscroll.js to ensure smooth scrolling as follows:

var myScroll; 
   function loaded() { 
      myScroll = new iScroll('scroller', { scrollbarClass: 'myScrollbar', hScrollbar: 
      false, vScrollbar: true }); 
   }
   document.addEventListener('DOMContentLoaded', loaded, false);

The functions to change the shape and size of the clouds are as follows:   

$(document).delegate('.ui-panel ul li > a', 'click', function(      
   var zid = $(this).data("id"); 
   if(zid == "close") { $('#wrapper').panel("close"); } 
      else { changeshape(zid); }
   });

   function changeshape(s) { 
      $('#wrapper').panel("close"); 
      var locks = {hcylinder: 'x', vcylinder: 'y', hring: 'x', vring: 'y', sphere: ''}; 
      lock = locks[s] || ''; 
      TagCanvas.initial = (lock == 'x' && [0,0.2]) || (lock == 'y' && [0.2,0]) || [0.2,0.2]; 
      cloudShape = s; 
      TagCanvas.Start('tagcanvas',cloudID, { shape: s, lock: lock });
   }

   $( "#zoomslider").on('slidestop', function( event ) { 
      var slider_value=$("#zoomslider").slider().val()/100; 
      loadCloud(cloudID, cloudShape, slider_value);
   });

Click Events in Swipe Clouds

Because the user is swiping the cloud it is likely that the user will accidentally click an images.  In order to handle accidental clicks on images or words in the swipe clouds I decided to popup a message asking the user if they want to go to the link. I used the following approach to handle these clicks.     

var i, et = document.getElementById(ttags).childNodes; 
   for(i in et) { 
      et[i].nodeName == 'A' && et[i].addEventListener('click', function(e) { 
         e.preventDefault(); 
         var targetUrl = $(this).attr("role"); 
         if(ttags != 'pumpkinTags') { 
            $("#datatest").html(targetUrl); 
            $('#inlinecontent').simpledialog2( {'hide': {effect: 'fadeOut', 
            duration: 5000} } ); 
         } 
         else { 
            var ximage = 'img_pumpkins/' + targetUrl + '.png'; 
            $('#popupPumpkin img').attr('src', ximage); 
            $('#popupPumpkin').popup("open"); 
         } 
      }); 
   }

   // Handles when user clicks on the "Ok" button on the popup 
   $("#dok").button().on("click", function () { 
      var path = $("#datatest").html(); 
      $('#dcancel').click(); if (path == "somevalue") { //DO SOMETHING } 
   });

   // This sets the correct dimensions & position for pumpkin image popup
   $( document ).on( "pageinit", function() { 
      $( ".photopopup" ).on({ 
         popupbeforeposition: function() { 
            var maxHeight = $( window ).height() - 60 + "px"; 
            $( ".photopopup img" ).css( "max-height", maxHeight ); 
            $('#popupPumpkin').css( "top", '60px' ); 
         } 
       }); 
    });
  

Points of Interest

To see Swipe Clouds in different mobile apps just Click Here:   www.SerGioApps.com

 

Conclusion

There are a lot of ways of customizing these Swipe Clouds and I leave it up to the read to explore their use in JQuery Mobile Apps. Enjoy!
   
   

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)