Is it possible to make canvas with background with lines or canvas that isn't a rectangle?

You need linear algebra stuff, basically noticing how vertical line starting/ending Y coordinate changes in relation to line's X coordinate. And of course a lot of experimenting until you get something usable. Something like :

var w = 600
    h = 600
    sp = 15

var slides = [fcircle, fsquare, ftriangle, ftrapezoid, fparallelogram];

var active = 0;

var ms;

function blines(){
  stroke(0);
  for (var i=0; i < h; i+=sp) {
    line(0,i,w,i);
  }
}

function vertlines(calcline) {
   for (var x=w/2-w/4+sp; x < w/2+w/4; x+=sp) {
       var pnts = calcline(x);
       line(pnts[0],pnts[1],pnts[2],pnts[3]);
   }
}

function fcircle() {
   // cut background
   noStroke();
   circle(w/2, h/2, w/2);
   stroke('red');
   // draw figure lines
   let calc = function (x){
      var sx = x-w/2;
      var sy = h/2;
      var ey = h/2;
      sy += 137*sin(2.5+x/135);
      ey -= 137*sin(2.5+x/135);
      return [x,sy,x,ey];
   }
   vertlines(calc);
}

function fsquare() {
   // cut background
   noStroke();
   quad(w/2-w/4, h/2-h/4, w/2+w/4, h/2-h/4,
        w/2+w/4, h/2+h/4, w/2-w/4, h/2+h/4);  
   stroke('red');
   // draw figure lines
   let calc = function (x){
      return [x,h/2-h/4,x,h/2+h/4];
   }
   vertlines(calc);
}

function ftriangle() {
   // cut background
   noStroke();
   quad(w/2, h/2-h/4, w/2+w/4, h/2+h/4,
        w/2-w/4, h/2+h/4, w/2, h/2-h/4);  
  stroke('red');
   // draw figure lines
   let calc = function (x){
      var inpx = x > w/2 ? w-x : x;
      var ys = h/2+h/4;
      ys += -(0.3*inpx*log(inpx)-220);
      return [x,ys,x,h/2+h/4];
   }
   vertlines(calc);
}

function ftrapezoid() {
   // cut background
   noStroke();
   quad(w/2-w/10, h/2-h/4, w/2+w/10, h/2-h/4,
        w/2+w/4, h/2+h/4, w/2-w/4, h/2+h/4);  
   stroke('red');
   // draw figure lines
   let calc = function (x){
      var inpx = x > w/2 ? w-x : x;
      var ys = h/2+h/4;
      ys += -(0.55*inpx*log(inpx)-420);
      if (x >= w/2-w/10 && x <= w/2+w/10) {
         ys=h/2-h/4;
      }
      return [x,ys,x,h/2+h/4];
   }
   vertlines(calc);
}

function fparallelogram() {
   // cut background
   noStroke();
   quad(w/2-w/10, h/2-h/4, w/2+w/7, h/2-h/4,
        w/2, h/2+h/4, w/2-w/4, h/2+h/4);  
   stroke('red');
   // draw figure lines
   let calc = function (x){
      // guard condition
      if (x > w/2+w/7)
         return [0,0,0,0];
      var inpx = x > w/2 ? w-x : x;
      var ys = h/2+h/4;
      ys += -(0.55*inpx*log(inpx)-420);
      var ye=h/2+h/4
      if (x >= w/2-w/10) {
         ys=h/2-h/4;
      }
      if (x > w/2) {
         ye = h/2+h/4;
         ye += 0.50*inpx*log(inpx)-870;
      }
      return [x,ys,x,ye];
   }
   vertlines(calc);
}

function setup() {
  ms = millis();
  createCanvas(w, h);
}

function draw() {
   if (millis() - ms > 2000) {
      ms = millis();
      active++;
      if (active > slides.length-1)
         active = 0;
   }
   background('#D6EAF8');
   fill('#D6EAF8');
   blines();
   slides[active]();
}

Slideshow DEMO


If you don't need actual line coordinates (for plotting for example), I'd just make most out of createGraphics() to easily render shapes and lines into (taking advantage of the fact that get() returns a p5.Image) and p5.Image's mask() function.

Here's a basic example:

function setup() {
  createCanvas(600, 300);
  
  let w = 300;
  let h = 150;
  let spacing = 12;
  let strokeWidth = 1;
  
  const BLUE   = color('#005398');
  const YELLOW = color('#f9db44');
  const RED    = color('#dc1215');
  
  bg = getLinesRect(w, h, RED, BLUE, spacing, strokeWidth, true);
  fg = getLinesRect(w, h, RED, YELLOW, spacing, strokeWidth, false);
  mask = getCircleMask(w, h, w * 0.5, h * 0.5, 100, 0);
  
  image(bg, 0, 0);
  image(fg, w, 0);
  // render opaque mask (for visualisation only), mask() requires alpha channel
  image(getCircleMask(w, h, w * 0.5, h * 0.5, 100, 255),0, h);
  
  // apply mask
  fg.mask(mask);
  // render bg + masked fg
  image(bg, w, h);
  image(fg, w, h);
  
  // text labels
  noStroke();
  fill(255);
  text("bg layer", 9, 12);
  text("fg layer", w + 9, 12);
  text("mask", 9, h + 12);
  text("bg + masked fg", w + 9, h + 12);
}

function getLinesRect(w, h, bg, fg, spacing, strokeWidth, isHorizontal){
  let rect = createGraphics(w, h);
  rect.background(bg);
  rect.stroke(fg);
  rect.strokeWeight(strokeWidth);
  
  if(isHorizontal){
    for(let y = 0 ; y < h; y += spacing){
      rect.line(0, y + strokeWidth, w, y + strokeWidth);
    } 
  }else{
    for(let x = 0 ; x < w; x += spacing){
      rect.line(x + strokeWidth, 0, x + strokeWidth, h);
    }
  }
  // convert from p5.Graphics to p5.Image
  return rect.get();
}

function getCircleMask(w, h, cx, cy, cs, opacity){
  let mask = createGraphics(w, h);
  // make background transparent (alpha is used for masking)
  mask.background(0, opacity);
  mask.noStroke();
  mask.fill(255);
  mask.circle(cx, cy, cs);
  // convert p5.Graphics to p5.Image
  return mask.get();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js"></script>

3 coloured composition with horizontal lined background and vertical lined foreground, applying a circular mask to the foreground

You can apply the same logic for the rest of the shapes:

function setup() {
  createCanvas(1620, 590);
  
  let compWidth  = 500;
  let compHeight = 250;
  let compSpacing= 30;
  
  let lineWeight = 1.5;
  let lineSpacing = 12;
  
  const BLUE   = color('#005398');
  const YELLOW = color('#f9db44');
  const RED    = color('#dc1215');
  
  // yellow square
  circleMask   = getCircleMask(compWidth, compHeight, compWidth * 0.5, compHeight * 0.5, 210);
  redCircle    = getComposition(compWidth, compHeight, RED, 
                                                    BLUE,
                                                    YELLOW,
                                                    lineSpacing, lineWeight, circleMask);
  
  
  // red box
  boxMask      = getRectMask(compWidth, compHeight, (compWidth - 100) * 0.5, 20, 100, 210);
  redBox       = getComposition(compWidth, compHeight, RED, 
                                                    YELLOW,
                                                    BLUE,
                                                    lineSpacing, lineWeight, boxMask);
  
  
  // yellow square
  squareMask   = getRectMask(compWidth, compHeight, 144, 20, 210, 210);
  yellowSquare = getComposition(compWidth, compHeight, YELLOW, 
                                                    RED,
                                                    BLUE,
                                                    lineSpacing, lineWeight, squareMask);
                                                    
  // yellow trapeze
  trapezeMask   = getQuadMask(compWidth, compHeight, 200, 25, 200 + 115, 25,
                                                     150 + 220, 220, 150, 220);
  yellowTrapeze = getComposition(compWidth, compHeight, YELLOW, 
                                                    BLUE,
                                                    RED,
                                                    lineSpacing, lineWeight, trapezeMask);
                                                    
  // blue triangle
  triangleMask   = getTriangleMask(compWidth, compHeight, compWidth * 0.5, 25,
                                                     150 + 220, 220, 150, 220);
  blueTriangle   = getComposition(compWidth, compHeight, BLUE, 
                                                    YELLOW,
                                                    RED,
                                                    lineSpacing, lineWeight, triangleMask);
                                                    
  // blue parallelogram
  parallelogramMask = getQuadMask(compWidth, compHeight, 200, 25, 200 + 145, 25,
                                                         150 + 145, 220, 150, 220);
  blueParallelogram = getComposition(compWidth, compHeight, BLUE, 
                                                    RED,
                                                    YELLOW,
                                                    lineSpacing, lineWeight, parallelogramMask);
  
  // render compositions
  image(redCircle, compSpacing, compSpacing);
  image(redBox, compSpacing, compSpacing + (compHeight + compSpacing));
  
  
  image(yellowSquare, compSpacing + (compWidth + compSpacing), compSpacing);
  image(yellowTrapeze, compSpacing + (compWidth + compSpacing), compSpacing + (compHeight + compSpacing));
  
  image(blueTriangle, compSpacing + (compWidth + compSpacing) * 2, compSpacing);
  image(blueParallelogram, compSpacing + (compWidth + compSpacing) * 2, compSpacing + (compHeight + compSpacing));
  
}

function getComposition(w, h, bgFill, bgStroke, fgStroke, spacing, strokeWidth, mask){
  let comp = createGraphics(w, h);
  
  bg = getLinesRect(w, h, bgFill, bgStroke, spacing, strokeWidth, true);
  fg = getLinesRect(w, h, bgFill, fgStroke, spacing, strokeWidth, false);
  // apply mask
  fg.mask(mask);
  // render to final output
  comp.image(bg, 0, 0);
  comp.image(fg, 0, 0);
  
  return comp;
}

function getRectMask(w, h, rx, ry, rw, rh){
  let mask = createGraphics(w, h);
  // make background transparent (alpha is used for masking)
  mask.background(0,0);
  mask.noStroke();
  mask.fill(255);
  mask.rect(rx, ry, rw, rh);
  // convert p5.Graphics to p5.Image
  return mask.get();
}

function getCircleMask(w, h, cx, cy, cs){
  let mask = createGraphics(w, h);
  // make background transparent (alpha is used for masking)
  mask.background(0,0);
  mask.noStroke();
  mask.fill(255);
  mask.circle(cx, cy, cs);
  // convert p5.Graphics to p5.Image
  return mask.get();
}

function getQuadMask(w, h, x1, y1, x2, y2, x3, y3, x4, y4){
  let mask = createGraphics(w, h);
  // make background transparent (alpha is used for masking)
  mask.background(0,0);
  mask.noStroke();
  mask.fill(255);
  mask.quad(x1, y1, x2, y2, x3, y3, x4, y4);
  // convert p5.Graphics to p5.Image
  return mask.get();
}

function getTriangleMask(w, h, x1, y1, x2, y2, x3, y3){
  let mask = createGraphics(w, h);
  // make background transparent (alpha is used for masking)
  mask.background(0,0);
  mask.noStroke();
  mask.fill(255);
  mask.triangle(x1, y1, x2, y2, x3, y3);
  // convert p5.Graphics to p5.Image
  return mask.get();
}

function getLinesRect(w, h, bg, fg, spacing, strokeWidth, isHorizontal){
  let rect = createGraphics(w, h);
  rect.background(bg);
  rect.stroke(fg);
  rect.strokeWeight(strokeWidth);
  
  if(isHorizontal){
    for(let y = 0 ; y < h; y += spacing){
      rect.line(0, y + strokeWidth, w, y + strokeWidth);
    } 
  }else{
    for(let x = 0 ; x < w; x += spacing){
      rect.line(x + strokeWidth, 0, x + strokeWidth, h);
    }
  }
  // convert from p5.Graphics to p5.Image
  return rect.get();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js"></script>

rough reproduction of Soll Lewitt's Wall Drawing 340

Probably both rectangles and the triangle could've been drawn using getQuadMask() making good use of coordinates.

Note that I've just eye balled the shapes a bit so they're not going to be perfect, but it should be easy to tweak. Bare in mind the placement of the mask will have an effect of on how the vertical lines will align.

There are probably other ways to get the same visual effect. For example, using texture() and textureWrap(REPEAT) with beginShape()/endShape(), using pixels for each line and checking intersections before changing direction and colours, etc.

In terms of generating lines for plotting I would start with horizontal lines, doing line to convex polygon intersection to determine where to stop the horizontal lines and start vertical lines. @AgniusVasiliauskas's answer(+1) is good for that approach.

Freya Holmér has a pretty nice visual explanation for the test.