processing.js performance on different devices

edited October 2016 in JavaScript Mode

Hi,

I am quite new to processing and I have been playing with it the last couple of weeks. I am working on a tiny project. The idea is to make a simple sequential animation. it is basically a few images, shapes, and text that appear in sequence. I have written the pde code (see below) and all works fine using the IDE. Now I want to port this on a website using processing.js (simply using processing.min.js and a canvas element).

It all works fine in the browser (chrome), but here is the problem the animation looks fine on a desktop, but on a tablet (a lenovo quad core) or Smasung Galaxy S3, the animation is all jerky (looks like the frame rate is dropping to unacceptable levels). So my question is: Is this a normal behavior, is my animation simply too complex, or may be I am doing something wrong in my code that is making the animation so heavy for non-desktop devices (although for example I don't think I have too long for loops )?

Also, does anyone has any best practice and tips when trying to set up simple sequential animation like below?

In btw, the images are each around 20-30KB. may be this is also slowing down things !!

I will appreciate any help, thank you.

Michel.

PS: I could not find a place (such as jsfiddle) to put the code along with the images somewhere for people to visualize the animation :(.


PImage main,cloud,phone,send,hand,alert;

PFont f;
String message1 = "Hello there, this";
String message2 = "is a message.";
String message3 = "See you.";
int c;

float typeSpeed = 12;
float speedDot = 3.0;

float x;
float y;

float xCloud,yCloud,xPhone,yPhone;

int fr = 24;

float angle,anglePhone,scaleCloud,scaleSend,angleSend,scaleAlert,angleAlert;

float xDot,xDot2,yDot; // Dot2 is used on the right side of the cloud

float cloudWidth = 150;

int ringingDuration,sendDuration,clickDuration,alertDuration,inBtwLoops;

int diam=50;

boolean finishedTextDisplay;

int myFrameCount;

void setup() {  
  size(1000,400);  
  frameRate(fr);  
  /* @pjs preload="data/main.png"; */
  /* @pjs preload="data/cloud.png"; */
  /* @pjs preload="data/phone.png"; */
  /* @pjs preload="data/send.png"; */
  /* @pjs preload="data/hand.png"; */
  /* @pjs preload="data/alert.png"; */

  main = loadImage("data/main.png");
  cloud = loadImage("data/cloud.png"); 
  phone = loadImage("data/phone.png");
  send = loadImage("data/send.png");
  hand = loadImage("data/hand.png");
  alert = loadImage("data/alert.png");  

  f = createFont("Arial",14,true); textFont(f);  
  resetValues();  
}

void draw() {
  myFrameCount++; // each trip thry draw is 1 frame count
  imageMode(CORNERS);image(main,0,0);  
  displayCloud(0); 
  displayPhone(0);
  if (alertDuration == 0 || alertDuration > fr) {displayAlert(0,false);} // displayAlert(scale,tinted) 

  if (finishedTextDisplay == false) {

        x = 195;
        y = 170;
        for (int i = 0; i < message1.length(); i++) { // show letters 1 sec interval 
          //println("for loop");
          if (fr*i/typeSpeed <= myFrameCount) {  
            c = 0; // show
          } 
          else {
            c = 255; // don't show
          }    
          fill(c);
          text(message1.charAt(i),x,y);    
          x += textWidth(message1.charAt(i));
          // println(textWidth(message3.charAt(i)));
        }

        x = 190;
        y = 170 + textAscent()+textDescent();        
        for (int i = 0; i < message2.length(); i++) { // show letters 1 sec interval 
          //println("for loop");
          if (fr*i/typeSpeed <= myFrameCount - ((fr/typeSpeed)*(message1.length()))) {
            c = 0; // show
          } 
          else {
            c = 255; // don't show
          }    
          fill(c);
          text(message2.charAt(i),x,y);    
          x += textWidth(message2.charAt(i)); 
        }

        x = 185;
        y = 170 + 2*(textAscent()+textDescent());

        for (int i = 0; i < message3.length(); i++) { // show letters 1 sec interval 
          // println("for loop");
          if (fr*i/typeSpeed <= myFrameCount - ((fr/typeSpeed)*(message1.length()+message2.length()))) {
            c = 0; // show
            if (i == message3.length()-1) { // last character shown --> click button
                      finishedTextDisplay = true;
            }
          } 
          else {
            c = 255; // don't show
          }    
          fill(c);
          text(message3.charAt(i),x,y);    
          x += textWidth(message3.charAt(i)); 
        } // end for loop 
    } // if finishedTextDisplay

    else // characters are all dislayed 
    {
      // display strings
      // println("NO for loop");
      fill(0);
      x = 195;y = 170; text(message1,x,y);    
      x = 190;y = 170+textAscent()+textDescent(); text(message2,x,y);
      x = 185;y = 170+2*(textAscent()+textDescent()); text(message3,x,y);

      // display hand
      if (clickDuration <= 0.5*fr) {
        // display bigger send button
        /*
        if (angle <= PI) { 
          scaleSend = map(sin(angleSend), 0, 1, 0, 0.15); 
          displaySend(scaleSend);
          angleSend += 5*PI/100;       
        }
        */
        if (clickDuration < 0.5*0.5*fr ) {scaleSend = clickDuration;}
        else {scaleSend = 0.5*fr - clickDuration;}
        // println(scaleSend);        
        scaleSend = map(scaleSend, 0, 0.5*0.5*fr, 0, 0.15); 
        displaySend(scaleSend);
        clickDuration++;

        tint(255,180);imageMode(CORNERS);image(hand,265,205);tint(255,255); 


      }
      else 
      {
                      displaySend(0);
                      // move on with simualtion
                      if (xDot < xCloud - cloudWidth/2) { // not reached cloud yet
                        displayDot();
                        // println("dot");
                      }
                      else 
                      { // dot reached the cloud --> no dot and grow cloud
                        // put the dot on the other side of the cloud
                        if (angle <= PI) { // once inflate and deflates once, cloud stops moving
                          // println(scaleCloud);
                          scaleCloud = map(sin(angle), 0, 1, 0, 0.15); 
                          displayCloud(scaleCloud);
                          angle += 5*PI/100;
                          // println("cloud");
                        }                  
                        else 
                        { // dot on the other side                    
                          if (xDot2 < xCloud + 165) { // not reached the arrow
                            displayDot2();
                            // println("dot 2");
                        }
                        else { // dot reached the phone --> no dot , phone shakes
                             if (ringingDuration < 4.5*fr) {
                               // println("ringing");
                               // displayPhone(random(-0.06,0.06)); // phone shakes
                               displayPhone(map(sin(anglePhone), -1, 1, -(PI/50), +(PI/50)));
                               anglePhone += (PI/2);

                               // rings
                               if ( (0 < ringingDuration && ringingDuration <= 0.5*fr) || (ringingDuration > 2.5*fr && ringingDuration <= 3*fr)) {                     
                                 displayRing(0);
                               }
                               if ( (0.5*fr < ringingDuration && ringingDuration <= fr) || (ringingDuration > 3*fr && ringingDuration <= 3.5*fr) ) {
                                 displayRing(0);
                                 displayRing(20);
                               }                         
                               if ( (fr < ringingDuration && ringingDuration <= 1.5*fr) || (ringingDuration > 3.5*fr && ringingDuration <= 4*fr)) {  
                                 displayRing(0);
                                 displayRing(20);
                                 displayRing(40);
                               }
                               if ( (ringingDuration > 1.5*fr && ringingDuration <= 2.0*fr) || (ringingDuration > 4*fr && ringingDuration <= 4.5*fr)) {  
                                 displayRing(0);
                                 displayRing(20);
                                 displayRing(40);
                                 // displayRing(60);
                               }
                               ringingDuration++;
                             }
                             else {
                                if (alertDuration <= fr) {
                                    // alert beeps 2 times  
                                    if (alertDuration >= 0 && alertDuration < fr/4 ) {scaleAlert = alertDuration;}
                                    if (alertDuration >= fr/4 && alertDuration < 2*fr/4) {scaleAlert = 2*fr/4 - alertDuration;}
                                    if (alertDuration >= 2*fr/4 && alertDuration < 3*fr/4) {scaleAlert = alertDuration - 2*fr/4;}
                                    if (alertDuration >= 3*fr/4 && alertDuration <= fr) {scaleAlert = fr - alertDuration;}
                                    // else {scaleAlert = 0.5*fr - alertDuration;}
                                    // println(scaleAlert);        
                                    scaleAlert = map(scaleAlert, 0, 0.5*0.5*fr, 0, 0.15); 
                                    displayAlert(scaleAlert,true);
                                    alertDuration=alertDuration+1;                                
                                }    
                                else 
                                {
                                  // alertDuration = 0;
                                  // wait for a second a so before starting the animation again
                                  if (inBtwLoops <= 2*fr) {
                                    inBtwLoops ++;
                                  }
                                  else {
                                    resetValues();
                                  }  
                                }
                             }
                          }  
                        }
                      }
      }

    }

}

void displayAlert(float scaleAlert, boolean tinted){
    pushMatrix();
    translate(222,386);
    imageMode(CENTER);
    scale(1+scaleAlert);
    if (tinted) {tint(217, 83, 79);} 
    image(alert,0,0); 
    tint(255,255);
    popMatrix();
}

void resetValues(){  
  angle=anglePhone=scaleCloud=scaleSend=angleSend=scaleAlert=angleAlert=0;  
  xCloud = width/2+85;
  yCloud = height/2-10;  
  xDot = xCloud - 170; 
  yDot = height/2;  
  xDot2 = xCloud + cloudWidth/2;  
  xPhone = xDot2 + 170 + 50;
  yPhone = height/2;  
  ringingDuration = sendDuration = clickDuration = alertDuration = inBtwLoops = 0;  
  finishedTextDisplay = false; 
  myFrameCount = 0;
}

void displayRing(int diamExtra){
  int alpha = round(map(diamExtra,0,40,255,50));
  strokeWeight(5.5);
  strokeCap(ROUND); 
  noFill();
  stroke(24, 188, 156, alpha);
  // arc(xPhone+10, yPhone - 69, diam+diamExtra, diam+diamExtra, -HALF_PI,0);
  arc(xPhone+10, yPhone - 69, diam+diamExtra, diam+diamExtra, -HALF_PI+(HALF_PI/7),0-(HALF_PI/7));
}

void displayCloud(float scaleCloud){
    pushMatrix();
    translate(xCloud,yCloud);
    imageMode(CENTER);
    scale(1+scaleCloud);
    image(cloud,0,0,150,150);
    popMatrix();
}

void displayPhone(float anglePhone){
    pushMatrix();
    translate(xPhone,yPhone);
    rotate(anglePhone);
    imageMode(CENTER);
    // scale(1+scaleCloud);
    image(phone,0,0,55,161);
    popMatrix();
}

void displayDot(){
    xDot+=speedDot;
    fill(21, 158, 130);
    stroke(21, 158, 130);
    ellipse(xDot,yDot,15,15);
}
void displayDot2(){
    xDot2+=speedDot;
    fill(21, 158, 130);
    stroke(21, 158, 130);
    ellipse(xDot2,yDot,15,15);
}

void displaySend(float scaleSend){
    pushMatrix();
    translate(275,215);
    imageMode(CENTER);
    scale(1+scaleSend);
    image(send,0,0,48,26);
    popMatrix();  
  /*
    pushMatrix();
    imageMode(CORNERS);
    tint(255,alpha);  // alpha=0: tranparent  
    image(send,250,205);
    tint(255,255); // 255: normal
    popMatrix();
  */  
} 

Answers

Sign In or Register to comment.