# SVG morphing animation

**URL:** https://discourse.processing.org/t/svg-morphing-animation/10482
**Category:** Libraries
**Created:** [April 20, 2019, 11:23am UTC](https://discourse.processing.org/t/svg-morphing-animation/10482 "2019-04-20T11:23:19Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![weedboy](https://avatars.discourse-cdn.com/v4/letter/w/d6d6ee/32.png) [@weedboy](https://discourse.processing.org/u/weedboy)
#### Post date: [April 20, 2019, 11:23am UTC](https://discourse.processing.org/t/svg-morphing-animation/10482/1 "2019-04-20T11:23:19Z")

</div>

Hello Processing Forum,

I’m a beginner and this is my first post.

How i can morphing svg with p5.js or Processing? I have two svg files from illustrator, and i want create animation morphing one svg into another.

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [April 20, 2019, 5:51pm UTC](https://discourse.processing.org/t/svg-morphing-animation/10482/2 "2019-04-20T17:51:05Z")

</div>

It depends on the 2 svg

Let’s say both have a child, but one has 53 vertex/vertices, the other none (eg a circle)

Hm. Also even with 53 vertices, it’s only the circumference not every pixel therein.

You could scan the svg from a PGraphics. Then you have two point clouds

---

<div class="post-metadata">

### Author: ![kfrajer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kfrajer/32/196_2.png) [@kfrajer](https://discourse.processing.org/u/kfrajer)
#### Post date: [April 20, 2019, 5:53pm UTC](https://discourse.processing.org/t/svg-morphing-animation/10482/3 "2019-04-20T17:53:53Z")

</div>

Not familiar but I would say it is possible if you have a concept or code to start with. If you don’t have any, my first suggestion is to explore previous posts in the forum:

> [Morph / Examples / Processing.org](https://processing.org/examples/morph.html)  
> [examples | p5.js](https://p5js.org/examples/motion-morph.html)

> [How to automatically morph/transform/blend from one shape to another shape - Processing 2.x and 3.x Forum](https://forum.processing.org/two/discussion/25749/how-to-automatically-morph-transform-blend-from-one-shape-to-another-shape)

> [https://codepen.io/GreenSock/pen/bEzgLd](https://codepen.io/GreenSock/pen/bEzgLd)

> [Shape Tween for 2 x SVG Files - Processing Forum](https://forum.processing.org/one/topic/shape-tween-for-2-x-svg-files.html)

> [morph 2 images - Processing 2.x and 3.x Forum](https://forum.processing.org/two/discussion/18350/morph-2-images)

Next is not Processing related but probly relevant (?) [SVG Morphing (the easy way and the hard way) | by Ahmed Mahmoud | codeburst](https://codeburst.io/svg-morphing-the-easy-way-and-the-hard-way-c117a620b65f)

Kf

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [April 23, 2019, 1:54pm UTC](https://discourse.processing.org/t/svg-morphing-animation/10482/4 "2019-04-23T13:54:51Z")

</div>

Can you say more about what the two svgs are? Do they have the same number of points, in the same order (eg two poses of one object)?

The hardest thing is if you have two conceptually related objects drawn in different styles – eg a pine tree and a palm tree, or a truck and a car. You usually need a domain mapping for the morph to look good (branch=branch, wheel=wheel). That needs to be designed.

---

<div class="post-metadata">

### Author: ![weedboy](https://avatars.discourse-cdn.com/v4/letter/w/d6d6ee/32.png) [@weedboy](https://discourse.processing.org/u/weedboy)
#### Post date: [April 25, 2019, 8:45pm UTC](https://discourse.processing.org/t/svg-morphing-animation/10482/5 "2019-04-25T20:45:04Z")

</div>

For example, I want to make an animation based on the cover of this book. I imagine that the lines will move from center to edge like waves on water.  
 ![e9bb5ab6646dc91ce7db5e369401cdfa](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/6/6c0b8220e4b6ecdc2503aeb2bd2a8d104b0ae365.jpeg)

So, I have an svg with a hand and an svg with a circle into which the waves will eventually turn.

> **[like-1.svg](https://www.dropbox.com/s/trsr9cxp6t3p2vd/like-1.svg?dl=0)**
>
> Shared with Dropbox

Perhaps this can be done easier, but I do not know how. I will be glad to advice.

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [April 25, 2019, 9:49pm UTC](https://discourse.processing.org/t/svg-morphing-animation/10482/6 "2019-04-25T21:49:36Z")

</div>

this basic sketch shows some properties of the 2 shapes

As I said:

Let’s say both have a child, but one has 53 vertex/vertices, the other none (eg a circle has none vertex but seems to be a fixed entity)

Hm. Also even with 53 vertices, it’s only the circumference not every pixel therein.

You could scan the svg from a PGraphics. Then you have two point clouds

this basic sketch shows some properties of the 2 shapes

```auto
PShape sCircle;
PShape sLike;

void setup() {
  // runs once
  size(1800, 1600);
  //
  // The files must be in the data folder
  // of the current sketch to load successfully
  sLike = loadShape("like.svg");
  sCircle = loadShape("circle.svg");
} // func 

void draw() { 
  // runs on and on in a loop
  background(255);
  fill(0);
  stroke(0);
  textSize(22);

  drawShapes();
} // func 

// ------------------------------------------

void drawShapes() {

  shape(sLike, 110, 110);
  shape(sCircle, 710, 110);

  int count;

  int count2 = sLike.getChildCount();
  println("Like children count: "
    +count2);

  count = sLike.getChild(0).getVertexCount() ;//Returns the total number of vertices as an int
  println("Like says: "
    +count);
  translate(110, 110); 
  for (int i = 0; i < sLike.getChild(0).getVertexCount(); i++) {
    PVector v = sLike.getChild(0).getVertex(i);
    fill(255, 0, 0); 
    ellipse(v.x, v.y, 7, 7);
  }//for

  println("----------------");

  // --------------------------------------------------
  // Circle

  count2 = sCircle.getChildCount();
  println("Circle children count: "
    +count2);

  count = sCircle.getChild(0).getVertexCount() ;//Returns the total number of vertices as an int
  println("Circle says: "
    +count);

  noLoop();
}
// =====================================================================

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [April 25, 2019, 10:14pm UTC](https://discourse.processing.org/t/svg-morphing-animation/10482/7 "2019-04-25T22:14:34Z")

</div>

You could scan the svg from a PGraphics. Then you have two point clouds

```auto

// https://discourse.processing.org/t/svg-morphing-animation/10482/6

PShape sCircle;
PShape sLike;

ArrayList<PVector[]> list = new ArrayList(); 
PGraphics pg=new PGraphics();

// boolean fly=false;

float amt=0.0;

void setup() {
  // runs once
  size(1800, 1600);
  //
  // The files must be in the data folder
  // of the current sketch to load successfully
  sLike = loadShape("like.svg");
  sCircle = loadShape("circle.svg");
} // func 

void draw() { 
  // runs on and on in a loop
  background(111);
  fill(0);
  stroke(0);
  textSize(22);

  pg = createGraphics(770, 770);
  pg.noSmooth();

  makeShape1();

  // image(pg, 0, 0);

  PVector[] pv= new PVector[0]; 

  // The 3 and the other 3 = the resolution of the scan 
  for (int x=0; x < pg.width; x+=7) {
    for (int y=0; y < pg.height; y+=7) {
      if (pg.get(x, y) < color(1)) 
        //point(x, y) ;
        pv=(PVector[])append(pv, new PVector(x, y));
    }//for
  }//for
  list.add(pv);

  // showOneCloud(0, 0, 0); 

  // ---------------------------------------

  pg = createGraphics(770, 770);
  pg.noSmooth();

  makeShape2();

  // image(pg, 0, 0); 

  //reset 
  pv= new PVector[0]; 

  // The 3 and the other 3 = the resolution of the scan 
  for (int x=0; x < pg.width; x+=3) {
    for (int y=0; y < pg.height; y+=3) {
      if (pg.get(x, y) < color(1)) 
        //point(x, y) ;
        pv=(PVector[])append(pv, new PVector(x, y));
    }//for
  }//for
  list.add(pv);

  // showOneCloud(1, 0, 0); 

  // drawShapes();

  flyOneCloud(110, 110);
} // func 

// -----------------------------------------------------------

void makeShape1 () {
  // for init
  pg.beginDraw();
  pg.background(255);
  pg.fill(0);
  pg.shape(sCircle); 
  pg.endDraw();
}

void makeShape2() {
  // for init
  pg.beginDraw();
  pg.background(255);
  pg.fill(0);
  pg.translate(88, 88);
  pg.shape(sLike); 
  pg.endDraw();
}

// ------------------------------------------

void showOneCloud(int getWhat, 
  float x, float y) {

  PVector[] pvector_Array = list.get(getWhat);

  pushMatrix();
  translate(x, y);
  for (PVector pv : pvector_Array) {
    noStroke(); 
    fill(0, 255, 0);
    float sizeEllipse=1.8; 
    ellipse(pv.x, pv.y, sizeEllipse, sizeEllipse); // use
  }
  popMatrix();
}//func

void flyOneCloud( 
  float x, float y) {

  PVector[] pvector_Array1 = list.get(0);
  PVector[] pvector_Array2 = list.get(1);

  pushMatrix();
  translate(x, y);
  for (int i=0; i<min(pvector_Array1.length, pvector_Array2.length); i++) {

    PVector pv1=pvector_Array1[i];
    PVector pv2=pvector_Array2[i];
    PVector pv3=new PVector(); 

    pv3.x=lerp(pv1.x, pv2.x, amt); 
    pv3.y=lerp(pv1.y, pv2.y, amt);

    noStroke(); 
    fill(0, 255, 0);
    float sizeEllipse=3.2; 

    ellipse(pv3.x, pv3.y, 
      sizeEllipse, sizeEllipse); // use
  }
  popMatrix();

  amt+=.072;
  if (amt>1.0)
    amt=1.0;
}//func

// --------------------------------------------------------------------

void drawShapes() {

  shape(sLike, 110, 110);
  shape(sCircle, 710, 110);

  int count;

  int count2 = sLike.getChildCount();
  println("Like children count: "
    +count2);

  count = sLike.getChild(0).getVertexCount() ;//Returns the total number of vertices as an int
  println("Like says: "
    +count);
  translate(110, 110); 
  for (int i = 0; i < sLike.getChild(0).getVertexCount(); i++) {
    PVector v = sLike.getChild(0).getVertex(i);
    fill(255, 0, 0); 
    ellipse(v.x, v.y, 7, 7);
  }//for

  println("----------------");

  // --------------------------------------------------
  // Circle

  count2 = sCircle.getChildCount();
  println("Circle children count: "
    +count2);

  count = sCircle.getChild(0).getVertexCount() ;//Returns the total number of vertices as an int
  println("Circle says: "
    +count);

  noLoop();
}
// =====================================================================

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [April 25, 2019, 10:20pm UTC](https://discourse.processing.org/t/svg-morphing-animation/10482/8 "2019-04-25T22:20:47Z")

</div>

same idea but now we take only the outline of a circle to start from

would probably look better when we took only the outline of the like sign as well

```auto

// https://discourse.processing.org/t/svg-morphing-animation/10482/6

PShape sCircle;
PShape sLike;

ArrayList<PVector[]> list = new ArrayList(); 
PGraphics pg=new PGraphics();

// boolean fly=false;

float amt=0.0;

void setup() {
  // runs once
  size(1800, 1600);
  //
  // The files must be in the data folder
  // of the current sketch to load successfully
  sLike = loadShape("like.svg");
  sCircle = loadShape("circle.svg");
} // func 

void draw() { 
  // runs on and on in a loop
  background(111);
  fill(0);
  stroke(0);
  textSize(22);

  // ---------------------------------------
  // handle circle 

  pg = createGraphics(770, 770);
  pg.noSmooth();

  makeShape1();

  // image(pg, 0, 0);

  PVector[] pv= new PVector[0]; 

  // The 3 and the other 3 = the resolution of the scan 
  for (int x=0; x < pg.width; x+=2) {
    for (int y=0; y < pg.height; y+=2) {
      if (pg.get(x, y) < color(1)) 
        //point(x, y) ;
        pv=(PVector[])append(pv, new PVector(x, y));
    }//for
  }//for
  list.add(pv);

  // showOneCloud(0, 0, 0); 

  // ---------------------------------------
  // handle Like  

  pg = createGraphics(770, 770);
  pg.noSmooth();

  makeShape2();

  // image(pg, 0, 0); 

  //reset 
  pv= new PVector[0]; 

  // The 3 and the other 3 = the resolution of the scan 
  for (int x=0; x < pg.width; x+=3) {
    for (int y=0; y < pg.height; y+=3) {
      if (pg.get(x, y) < color(1)) 
        //point(x, y) ;
        pv=(PVector[])append(pv, new PVector(x, y));
    }//for
  }//for
  list.add(pv);

  // showOneCloud(1, 0, 0); 

  // drawShapes();

  flyOneCloud(110, 110);
} // func 

// -----------------------------------------------------------

void makeShape1 () {
  // for init
  pg.beginDraw();
  pg.background(255);
  pg.fill(0);
  //pg.shape(sCircle);
  pg.strokeWeight(13);
  pg.noFill();
  pg.ellipse( pg.width/2, pg.height/2, 
    760, 760 ); 
  pg.endDraw();
}

void makeShape2() {
  // for init
  pg.beginDraw();
  pg.background(255);
  pg.fill(0);
  pg.translate(88, 88);
  pg.shape(sLike); 
  pg.endDraw();
}

// ------------------------------------------

void showOneCloud(int getWhat, 
  float x, float y) {

  PVector[] pvector_Array = list.get(getWhat);

  pushMatrix();
  translate(x, y);
  for (PVector pv : pvector_Array) {
    noStroke(); 
    fill(0, 255, 0);
    float sizeEllipse=1.8; 
    ellipse(pv.x, pv.y, sizeEllipse, sizeEllipse); // use
  }
  popMatrix();
}//func

void flyOneCloud( 
  float x, float y) {

  PVector[] pvector_Array1 = list.get(0);
  PVector[] pvector_Array2 = list.get(1);

  pushMatrix();
  translate(x, y);
  for (int i=0; i<min(pvector_Array1.length, pvector_Array2.length); i++) {

    PVector pv1=pvector_Array1[i];
    PVector pv2=pvector_Array2[i];
    PVector pv3=new PVector(); 

    pv3.x=lerp(pv1.x, pv2.x, amt); 
    pv3.y=lerp(pv1.y, pv2.y, amt);

    noStroke(); 
    fill(0, 255, 0);
    float sizeEllipse=3.2; 

    ellipse(pv3.x, pv3.y, 
      sizeEllipse, sizeEllipse); // use
  }
  popMatrix();

  amt+=.072;
  if (amt>1.0)
    amt=1.0;
}//func

// --------------------------------------------------------------------

void drawShapes() {

  shape(sLike, 110, 110);
  shape(sCircle, 710, 110);

  int count;

  int count2 = sLike.getChildCount();
  println("Like children count: "
    +count2);

  count = sLike.getChild(0).getVertexCount() ;//Returns the total number of vertices as an int
  println("Like says: "
    +count);
  translate(110, 110); 
  for (int i = 0; i < sLike.getChild(0).getVertexCount(); i++) {
    PVector v = sLike.getChild(0).getVertex(i);
    fill(255, 0, 0); 
    ellipse(v.x, v.y, 7, 7);
  }//for

  println("----------------");

  // --------------------------------------------------
  // Circle

  count2 = sCircle.getChildCount();
  println("Circle children count: "
    +count2);

  count = sCircle.getChild(0).getVertexCount() ;//Returns the total number of vertices as an int
  println("Circle says: "
    +count);

  noLoop();
}
// =====================================================================

```
