nocksock
nocksock

Reputation: 5527

Is there an elegant way to draw shapes around the edge of a canvas?

I want to create a seamless pattern on a canvas. I simplified the whole process down to simple rectangles. When a rectangle is drawn close to an edge of the canvas and part of it gets cut off, I want that missing part to be repeated at the other side.

I thought I'd just check whether the rectangle to be drawn is too close to the edge, and draw it again + canvas.width/height. Halfway through I realized that this might become quite a few ifs.

This is what I already have:

this is what I have

This is the part where I check for the edges.

// this._draw(); is a convenience method that draws the rectangle with
// the center as its registration point instead of top left corner.
// which is also why I add (this.size/2) to the coordinates.
if(this.x+( this.size/2 ) > canvas.width) {
  this._draw(
    this.x+canvas.width,
    this.y
  );
}

if(this.x-( this.size/2 ) <  0){
  this._draw(
    this.x+canvas.width,
    this.y
  );
}

if(this.y+( this.size/2 ) > canvas.height) {
  this._draw(
    this.x-(this.size/2),
    this.y-canvas.height-(this.size/2)
  )
}

if(this.y-(this.size/2) < 0){
  this._draw(
    this.x,
    this.y+canvas.height
  );
}

This is what I want

this is what I want

Is there some clever way to check this more efficiently? I'm certain that there's a more elegant approach than what I'm currently directed to.

The whole example is on codepen.io.

Upvotes: 1

Views: 151

Answers (1)

Cerbrus
Cerbrus

Reputation: 72857

Take a look at this code:

var canvas  = document.createElement('canvas');
var context = canvas.getContext('2d');

var LT = new Dot(0,     100,    290,            140);
var RT = new Dot(90,    75,     canvas.width,   0);
var RB = new Dot(180,   50,     canvas.width,   canvas.height);
var LB = new Dot(270,   25,     0,              canvas.height);

function Dot(color, size, x, y){
    this.size = size;
    this.x = x;
    this.y = y;
    this.color = "hsla("+color+", 100%, 50%, 1)";

    this.draw = function() {
        context.fillStyle = this.color;
        context.strokeStyle = "hsla(0,0%,0%, 0.5)";
        this._draw(x, y);
        this.drawBorders();
    };


    this._draw = function(centerX, centerY) {
        context.fillRect(
            centerX - size/2,
            centerY - size/2,
            size,
            size 
        );
    };

    this.drawBorders = function() {
        var borders = 0;

        var tx, ty;
        if(x - size/2 <= 0){
            tx = canvas.width + x;
        }else if(x + size/2 >= canvas.width){
            tx = canvas.width - x;
        }
        if(y - size/2 <= 0){
            ty = canvas.height + y;
        }else if(y + size/2 >= canvas.height){
            ty = y - canvas.height ;
        }

        if(x-size/2 <= 0 || x+size/2 >= canvas.width ){
            this._draw(tx, y);
        }
        if(y-size/2 <= 0 || y+size/2 >= canvas.height){
            this._draw(x, ty);
        }
        if(x+size/2 >= canvas.width ||
           y+size/2 >= canvas.height ||
           x-size/2 <= 0 ||
           y-size/2 <= 0){
            this._draw(tx, ty);
        }
    }
    this.draw();
}

document.body.appendChild(canvas);

This draws the squares to overlap the corners, but only if they indeed overlap.

Upvotes: 1

Related Questions