Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <canvas id="canvas" width="500" height="500"> </canvas>

<!-- This is a repeating tiling example that I isolated from my game Edge Not Found, which you can play here: https://auroriax.itch.io/edge-not-found and the full source code can be found at https://github.com/Auroriax/js13k-2020 -->

<!-- This code snippet is released under MIT: https://opensource.org/licenses/MIT -->


              
            
!

CSS

              
                html, body, canvas {
    width:  100%;
    height: 100%;
    margin: 0;
    overflow: hidden;
  }
              
            
!

JS

              
                //Grabbing references
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d", { alpha: false });

//Setting canvas to be as wide as the screen
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;

//These values control how "offset" the level is. One or both of these must be 0.
//Keep the values low for the best effect (never higher than level width/height).
//If you don't get how it works, consider playing Edge Not Found for a bit. :)
const levelOffsetX = 0;
const levelOffsetY = 0;

//In number of tiles. Since we don't have the level state data like we would in the game
const gridWidth = 4;
const gridHeight = 8;

//Loading an image to use as an example level
var img = new Image();
img.onload = function () {
  DrawRepeat(img);
};
img.src = "https://assets.codepen.io/5343800/enf_examplelevel_320.png";

function DrawRepeat(img) {
  
  if (img == null) {
    return;
  }
  
  //Cleaning canvas
  ctx.fillStyle = "white";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  
  //Pixel size of the level is important for our calculations later, so we save it here
  var levelWidth = img.width;
  var levelHeight = img.height;

  //Decide where to draw the level to make it appear in the middle of the screen
  var cameraX = Math.round(canvas.width * 0.5 - levelWidth * 0.5);
  var cameraY = Math.round(canvas.height * 0.5 - levelHeight * 0.5);

  var clipOffset = 20; //Adds extra padding to make sure the screen border is filled. In pixels.

  //Determine how often we can redraw the level before hitting the screen border
  var screenWidthRatio = Math.ceil(
    ((canvas.width - levelWidth + clipOffset) / levelWidth) * 0.5
  );
  var screenHeightRatio = Math.ceil(
    ((canvas.height - levelHeight + clipOffset) / levelHeight) * 0.5
  );

  //Add a little safety padding in case the level wrapping is offset
  if (levelOffsetX != 0) {
    screenWidthRatio += 2;
  }
  if (levelOffsetY != 0) {
    screenHeightRatio += 2;
  }
  
  ctx.fillStyle = "red";
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";
  ctx.font = "40px sans-serif";

  //Fill the screen with levels, following the offset
  for (let y = -Math.abs(screenHeightRatio); y <= Math.abs(screenHeightRatio); y++) {
    for (let x = -Math.abs(screenWidthRatio); x <= Math.abs(screenWidthRatio); x++) {
      //Set alpha so levels further away from the screen center are more translucent
      ctx.globalAlpha = Math.max(0, 1 - Math.abs(y) * 0.1 - Math.abs(x * 0.1));
      if (ctx.globalAlpha > 0) { //Only draw if it will actually be visible!
        var levelX = cameraX + levelWidth * x + levelOffsetX * (levelWidth / gridWidth) * y;
        var levelY = cameraY + levelHeight * y + levelOffsetY * (levelHeight / gridHeight) * x
        ctx.drawImage(img, levelX, levelY);
        
        //Unsure how the location is decided? Uncomment the next line to display coordinates!
        //ctx.fillText(x+","+y,levelX + levelWidth * 0.5, levelY + levelHeight * 0.5);
      }
    }
  }
}

//Also redraw images when resizing window
window.onresize = function() {
	canvas.width = canvas.clientWidth;
	canvas.height = canvas.clientHeight;
  DrawRepeat(img);
};
              
            
!
999px

Console