# Alpha mask between objects

**URL:** https://discourse.processing.org/t/alpha-mask-between-objects/22403
**Category:** Coding Questions
**Created:** [July 5, 2020, 9:35pm UTC](https://discourse.processing.org/t/alpha-mask-between-objects/22403 "2020-07-05T21:35:25Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![orgcaos](https://avatars.discourse-cdn.com/v4/letter/o/8edcca/32.png) [@orgcaos](https://discourse.processing.org/u/orgcaos)
#### Post date: [July 5, 2020, 9:35pm UTC](https://discourse.processing.org/t/alpha-mask-between-objects/22403/1 "2020-07-05T21:35:25Z")

</div>

Hello guys! I hope you are safe 🙂

I’m trying to hide a part of a shape I did using alpha mask but I have no idea how to achieve it.

My current result looks like that:

![Screenshot 2020-07-06 at 12.27.48 AM](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/e/e425c6558567991251ac67a2e3d004bbcc7c54cc.jpeg)

I want the black shape to act like an alpha mask and hide the white part behind it. I tried different solutions but didn’t manage to solve it 😕

Here is my code:

```auto
// Responsive Canvas
function windowResized() {
    
    var w = windowWidth / 1.5;
    var h = w * 1.43;

    if (windowHeight < h) {
        h = windowHeight - (windowHeight / 10);
        w = h / 1.43;    
    }

    var cnv = createCanvas(w, h);
    cnv.style('display', 'block');
}

var arColors = ['magenta', '#23fafa', '#456783']; // library of colors

let amt, startColor, newColor; // variables for color fading

function setup() { 
    windowResized();
    rectMode(CENTER);
    startColor = color(random(arColors)); // set start color
    newColor = color(random(arColors)); // set new color
    amt = 0;
}
  
function draw() {
    var roundedCorner = width/30;
    var centerH = height / 2;
    var centerW = width / 2;
    var marginWidth = width / 27;

    background(0,0); // bacground transparent

    // sign fill
    fill(lerpColor(startColor, newColor, smoothstep(0.3,0.7,amt)));
    amt += 0.01;
    if(amt >= 1){
        amt = 0.0;
        startColor = newColor;
        newColor = color(random(arColors));
    }

    // sign base
    
    rect(centerW, centerH, width, height, roundedCorner); 
    noStroke();
   
    // white path
    var thickness = (height / 6.4) - marginWidth ;
    var strokePosition = marginWidth + thickness/2;

    strokeWeight(thickness);
    strokeCap(ROUND);
    strokeJoin(ROUND);
    stroke(255);
    noFill();

    beginShape();
    var n = 2.495;
    var dist = 1.495;
    vertex(width - strokePosition , strokePosition);
    vertex(strokePosition, strokePosition);
    vertex(strokePosition, strokePosition);
    vertex(strokePosition , strokePosition * n);
    vertex(strokePosition , strokePosition * n);
    vertex(width - strokePosition , strokePosition * n);
    vertex(width - strokePosition , strokePosition * n);
    var n = n + dist;
    vertex(width - strokePosition , strokePosition * n);
    vertex(width - strokePosition , strokePosition * n);
    vertex(strokePosition , strokePosition * n);
    vertex(strokePosition , strokePosition * n);
    n = n + dist;
    vertex(strokePosition , strokePosition * n);
    vertex(strokePosition , strokePosition * n);
    vertex(width - strokePosition , strokePosition * n);
    vertex(width - strokePosition , strokePosition * n);
    n = n + dist;
    vertex(width - strokePosition , strokePosition * n);
    vertex(width - strokePosition , strokePosition * n);
    vertex(strokePosition , strokePosition * n);
    vertex(strokePosition , strokePosition * n);
    n = n + dist;
    vertex(strokePosition , strokePosition * n);
    vertex(strokePosition , strokePosition * n);
    vertex(width - strokePosition , strokePosition * n);
    vertex(width - strokePosition , strokePosition * n);
    n = n + dist;
    vertex(width - strokePosition , strokePosition * n);
    vertex(width - strokePosition , strokePosition * n);
    vertex(strokePosition , strokePosition * n);
    endShape();
    noStroke();
    
  // mask
  fill(0);
  noStroke();
  beginShape(); 
  vertex(marginWidth / 2 , (height - marginWidth) / 1.155);
  vertex(marginWidth + width/12.75 , (height - marginWidth) / 1.155);
  vertex(marginWidth + width/12.75 , (height - marginWidth) / 1.155);
  vertex(marginWidth, strokePosition * n);
  vertex(marginWidth, strokePosition * n);
  vertex(marginWidth + width/12.75 , height - marginWidth);
  vertex(marginWidth + width/12.75 , height - marginWidth);
  vertex(marginWidth / 2 , height - marginWidth);
  vertex(marginWidth / 2 , height - marginWidth);
  vertex(marginWidth / 2 , (height - marginWidth) / 1.155);
  endShape();
}

function smoothstep(edge0, edge1, m) {
    m = constrain((m - edge0) / (edge1 - edge0), 0.0, 1.0); 
    return m * m * (3 - 2 * m);
}

```

---

<div class="post-metadata">

### Author: ![slow\_izzm](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/slow_izzm/32/5637_2.png) [@slow\_izzm](https://discourse.processing.org/u/slow_izzm)
#### Post date: [July 6, 2020, 3:10am UTC](https://discourse.processing.org/t/alpha-mask-between-objects/22403/2 "2020-07-06T03:10:14Z")

</div>

You can use a custom shape as a mask.

[https://p5js.org/reference/#/p5/beginShape](https://p5js.org/reference/#/p5/beginShape)  
[https://p5js.org/reference/#/p5/createGraphics](https://p5js.org/reference/#/p5/createGraphics)  
[https://p5js.org/reference/#/p5.Image/mask](https://p5js.org/reference/#/p5.Image/mask)

Here is a quick example … after I threw this together I realized I did the opposite of what you are going for in terms of what you want masked out, but you can easily tweak it to your liking.

```auto
let msk,
  mskClone,
  mskGraphic;

function setup() {
  createCanvas(400, 200);
  
  msk = createGraphics(width, height);
  mskGraphic = createGraphics(width, height);
}

function draw() {
  background(13, 17, 21);
  mskGraphic.clear();
  msk.beginShape();
  msk.vertex(30, 10);
  msk.vertex(130, 10);
  msk.vertex(50,100);
  msk.vertex(130, height-10);
  msk.vertex(30, height-10);
  msk.endShape(CLOSE);
  
  //same shape as mask - used to draw the stroke for visual aid
  noFill();
  stroke('#fffafa');
  strokeWeight(2);
  beginShape();
  vertex(30, 10);
  vertex(130, 10);
  vertex(50,100);
  vertex(130, height-10);
  vertex(30, height-10);
  endShape(CLOSE);

  //graphic visual when not masked
  mskGraphic.ellipse(mouseX, mouseY, 25, 25);

  //mask
  (mskClone = msk.get()).mask(mskGraphic.get());
  image(mskClone, 0, 0);
}

```

---

<div class="post-metadata">

### Author: ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)
#### Post date: [July 6, 2020, 3:30am UTC](https://discourse.processing.org/t/alpha-mask-between-objects/22403/3 "2020-07-06T03:30:05Z")

</div>

Remember mask vertices must be called in the opposite direction to other vertices.

---

<div class="post-metadata">

### Author: ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)
#### Post date: [July 6, 2020, 6:28pm UTC](https://discourse.processing.org/t/alpha-mask-between-objects/22403/5 "2020-07-06T18:28:30Z")

</div>

see previous post

> **[Processing 2.x and 3.x Forum](https://forum.processing.org/two/discussion/23886/masking-a-shape-with-another-shape)**
>
> Processing is an electronic sketchbook, a language and a worldwide community. This is its forum.

---

<div class="post-metadata">

### Author: ![orgcaos](https://avatars.discourse-cdn.com/v4/letter/o/8edcca/32.png) [@orgcaos](https://discourse.processing.org/u/orgcaos)
#### Post date: [July 6, 2020, 8:08pm UTC](https://discourse.processing.org/t/alpha-mask-between-objects/22403/6 "2020-07-06T20:08:41Z")

</div>

Thank you guys for answering! You are the best 🙂

---

<div class="post-metadata">

### Author: ![orgcaos](https://avatars.discourse-cdn.com/v4/letter/o/8edcca/32.png) [@orgcaos](https://discourse.processing.org/u/orgcaos)
#### Post date: [July 6, 2020, 9:34pm UTC](https://discourse.processing.org/t/alpha-mask-between-objects/22403/7 "2020-07-06T21:34:30Z")

</div>

ok guys I tried it but unfortunately it didn’t work ☹ actually I think that something’s going wrong with the

```auto
(mskClone = msk.get()).mask(mskGraphic.get());
  image(mskClone, 0, 0);

```

Here’s my code:

```auto
// Responsive Canvas
function windowResized() {
  let w = windowWidth / 1.5;
  let h = w * 1.43;
  if (windowHeight < h) {
    h = windowHeight - (windowHeight / 10);
    w = h / 1.43;    
  }
  let cnv = createCanvas(w, h);
  cnv.style('display', 'block');
}

//variables

let arColors = ['magenta', '#23fafa', '#456783']; // library of colors
let amt, startColor, newColor; // variables for color fading

let msk,
  mskClone,
  mskGraphic;

function setup() { 
  windowResized();
  rectMode(CENTER);

  startColor = color(random(arColors)); // set start color
  newColor = color(random(arColors)); // set new color
  amt = 0;
  
  msk = createGraphics(width, height);
  mskGraphic = createGraphics(width, height);
}
  
function draw() {
  let roundedCorner = width/30;
  let centerH = height / 2;
  let centerW = width / 2;
  let marginWidth = width / 27;

  background(0,0); // background transparent

  // sign fill
  fill(lerpColor(startColor, newColor, smoothstep(0.3,0.7,amt)));
  amt += 0.01;
  if(amt >= 1){
    amt = 0.0;
    startColor = newColor;
    newColor = color(random(arColors));
  }

  // sign base
  rect(centerW, centerH, width, height, roundedCorner); 
  noStroke();

    
  let thickness = (height / 6.4) - marginWidth ;
  let strokePosition = marginWidth + thickness/2;
  
  // mask
  fill(0);
  strokeWeight(7);

  mskGraphic.clear();
  msk.beginShape();        
  msk.vertex(marginWidth / 2 , (height - marginWidth) / 1.155);
  msk.vertex(marginWidth + width/12.75 , (height - marginWidth) / 1.155);
  msk.vertex(marginWidth + width/12.75 , (height - marginWidth) / 1.155);
  msk.vertex(marginWidth, strokePosition * n);
  msk.vertex(marginWidth, strokePosition * n);
  msk.vertex(marginWidth + width/12.75 , height - marginWidth);
  msk.vertex(marginWidth + width/12.75 , height - marginWidth);
  msk.vertex(width - marginWidth , height - marginWidth);
  msk.vertex(width - marginWidth , marginWidth);
  msk.vertex(marginWidth , marginWidth);
  msk.endShape(CLOSE);

  //white path
  noFill();
  strokeWeight(thickness);
  strokeCap(ROUND);
  strokeJoin(ROUND);
  stroke(255);

  var n = 2.495, 
      dist = 1.495;
  
  mskGraphic.beginShape();
  mskGraphic.vertex(width - strokePosition , strokePosition);
  mskGraphic.vertex(strokePosition, strokePosition);
  mskGraphic.vertex(strokePosition, strokePosition);
  mskGraphic.vertex(strokePosition, strokePosition * n);
  mskGraphic.vertex(strokePosition, strokePosition * n);
  mskGraphic.vertex(width - strokePosition, strokePosition * n);
  mskGraphic.vertex(width - strokePosition, strokePosition * n);
  mskGraphic.vertex(width - strokePosition, strokePosition * (n = n + dist));
  mskGraphic.vertex(width - strokePosition, strokePosition * n);
  mskGraphic.vertex(strokePosition, strokePosition * n);
  mskGraphic.vertex(strokePosition, strokePosition * n);
  mskGraphic.vertex(strokePosition, strokePosition * (n = n + dist));
  mskGraphic.vertex(strokePosition, strokePosition * n);
  mskGraphic.vertex(width - strokePosition, strokePosition * n);
  mskGraphic.vertex(width - strokePosition, strokePosition * n);
  mskGraphic.vertex(width - strokePosition, strokePosition * (n = n + dist));
  mskGraphic.vertex(width - strokePosition, strokePosition * n);
  mskGraphic.vertex(strokePosition, strokePosition * n);
  mskGraphic.vertex(strokePosition, strokePosition * n);
  mskGraphic.vertex(strokePosition, strokePosition * (n = n + dist));
  mskGraphic.vertex(strokePosition, strokePosition * n);
  mskGraphic.vertex(width - strokePosition, strokePosition * n);
  mskGraphic.vertex(width - strokePosition, strokePosition * n);
  mskGraphic.vertex(width - strokePosition , strokePosition * (n = n + dist));
  mskGraphic.vertex(width - strokePosition , strokePosition * n);
  mskGraphic.vertex(strokePosition , strokePosition * n);
  mskGraphic.endShape();
  stroke(0);
  strokeWeight(7);
  ellipse(20,20,20,20);
  noStroke();
  
  (mskClone = msk.get()).mask(mskGraphic.get());
  image(mskClone, 0, 0);

}

function smoothstep(edge0, edge1, m) {
  m = constrain((m - edge0) / (edge1 - edge0), 0.0, 1.0); 
  return m * m * (3 - 2 * m);
}

```

---

<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: [July 27, 2020, 6:25pm UTC](https://discourse.processing.org/t/alpha-mask-between-objects/22403/8 "2020-07-27T18:25:49Z")

</div>

> [@paulgoux](#):
>
> mask vertices must be called in the opposite direction to other vertices

I think this is actually not true for masks. It is true for PShape inner contours created with beginContour

> **[beginContour() / Reference](https://processing.org/reference/beginContour_.html)**
>
> Use the beginContour() and endContour() function to create negative shapes within shapes such as the center of the letter "O". beginContour() begins recording vertices for the sha…

> First draw vertices for the exterior shape in clockwise order, then for internal shapes, draw vertices counterclockwise.

PGraphics masks are rendered to pixel data, so the vertex order can be the same as any other drawing.

**…oops! Sorry, I gave a Processing(Java) answer to a p5.js question. My mistake.**
