How to change image repeat pattern in HTML5 Canvas - javascript

I am trying to create many different image repeat pattern. I used the following code for the repeat pattern. The code is working fine for regular patterns but I need many different sets of the pattern as the image is shown below.
OR Like below...
But with the below code I have this pattern only that is here ....
<div style="width: 675px;height:675px;overflow: hidden;"><canvas id="cc" width="300px" height="300px"></canvas></div>
<script>
drawPattern(img, current_size);
function drawPattern(img, size) {
var canvas = document.getElementById('cc');
var tempCanvas = document.createElement("canvas"),
tCtx = tempCanvas.getContext("2d");
tempCanvas.width = size;
tempCanvas.height = size;
tCtx.drawImage(img, 0, 0, img.width, img.height, 0, 0, size, size);
// use getContext to use the canvas for drawing
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = ctx.createPattern(tempCanvas, 'repeat');
ctx.beginPath();
ctx.rect(0,0,canvas.width,canvas.height);
ctx.fill();
}
</script>
Please help in this that how I can get that different patterns. Thanks in Advance.

I believe that there are infinite patterns you can accomplish. So it's difficult to tell you all the code that you are looking for. You should research a lot of tecniques and "steal" ideas for yourself.
From what I saw you are using JavaScript to perform this patterns, but there are other ways to accomplish this. You can simply use HTML and CSS for example. Like:
<!DOCTYPE html>
<html>
<head>
<style>
body {
background-image: url("image.png");
background-repeat: repeat-y;
}
</style>
</head>
<body>
<h1>The background-repeat Property</h1>
<p>Here, the background image is repeated only vertically.</p>
</body>
</html>
Also, the background-repeat property can have the following values:
background-repeat: repeat|repeat-x|repeat-y|no-repeat|initial|inherit;
For last there are more CSS properties you can use to perform different background patterns, like:
background-position: center; /* Center the image */
background-size: cover; /* Resize the background image to cover the entire container */
HTML and CSS documentation:
https://www.w3schools.com/cssref/pr_background-repeat.asp

Related

How to make a minimap of the whole page in Javascript

I am working on a simple JS/HTML/CSS project. I have a box that's very big (400vw, 400vh) and it acts like a map. What I want to do is a mini-map for that huge thing on the top left corner.
What I understand is that it has to be done with canvas by getting the whole page, put it in canvas and then display it in another box that's just for example 10 times smaller. If my logic is correct, then what is wrong in the code?
<html>
<head>
<script defer src="js/main.js"></script>
<link rel="stylesheet" href="css/main.css">
<style>
#minimapCanvas {
position: absolute;
top: 0;
left: 0;
}
</style>
<script>
window.onload = function() {
// Get the canvas element and its context
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
// Draw something on the main canvas
context.fillRect(0, 0, canvas.width, canvas.height);
saveCanvas();
}
function saveCanvas() {
// Get the canvas element and its context
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
// Get the image data from the canvas
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
// Create a new canvas for the minimap
var minimapCanvas = document.getElementById("minimapCanvas");
minimapCanvas.width = 100;
minimapCanvas.height = 100;
var minimapContext = minimapCanvas.getContext("2d");
// Draw the image data on the minimap canvas
minimapContext.putImageData(imageData, 0, 0, 0, 0, minimapCanvas.width, minimapCanvas.height);
}
</script>
</head>
<body>
<div class="box">
<canvas id="myCanvas" width="500" height="500"></canvas>
<canvas id="minimapCanvas" width="100" height="100"></canvas>
</div>
</body>
</html>
and after I run the application I get a big black box instead of the minimap -
I have been trying to search every possible topic about JS mini-map in stackoverflow but couldn't find my solution. I also tried Chat GPT (which usually helps me).
EDIT:
Here is a github link to my repository (NOTE: you have to run it with a live server for example in VSCode, in order for the character's image to work properly) -
https://github.com/ApooBG/minimap

Add white spaces to image Javascript

is there a way to add white spaces to an image in javascript ?
I this the image 1 and I want to edit or create a new image, to add white spaces and the result would be the image 2.
The following code achieves this task. Basically, we create a canvas and set it to the size of the desired output. We then fill it with white before drawing the original image at (0,250) This centers the image (I should have done this with code, but instead looked at your output image in an image editor. (OutputHeight-InputHeight)/2 = Y offset to draw image at.
Since you're not actually adding any detail, it's possible this isn't the best way to go about what you're trying to achieve. It's possible that you should use margin/padding to expand the room the image appears to occupy.
window.addEventListener('load', onLoaded, false);
function onLoaded(evt)
{
let img = document.querySelector('img');
let canvas = document.querySelector('#output');
let ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff';
ctx.fillRect(0,0,759,759);
ctx.drawImage(img, 0, 250);
}
body{
background-color: #ddd;
}
<img src='https://i.stack.imgur.com/bN5hp.jpg'/>
<hr>
<canvas id='output' width=760 height=760/></canvas>
You can do it using the canvas object.. if you have the image for instance
<img src="some.jpeg" id="myImg">
You can copy it to a new canvas and play with the drawImage properties
var img = document.getElementById('myImg');
var canvas = document.createElement('canvas');
canvas.width = img.width; // add here the extra width you want
canvas.height = img.height; // add here the extra height you want
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height); // play here with the position, 0, 0 are the top x,y axis
Here is the link to mozilla documentation:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage

How to bring one canvas context over the top of another?

I am using two images in a canvas, now i want to bring one image over another, ie. i want to bring the plane over the sky, how can i do that?
here is my code
var canvas = document.getElementById('canvas');
var skyContext = canvas.getContext('2d');
var planeContext = canvas.getContext('2d');
var sky = new Image();
sky.src = './images/m35.jpeg';
sky.onload = function () {
skyContext.drawImage(sky, 0, 0, 250, 250, 50, 50, 250, 250);
}
var plane = new Image();
plane.src = './images/space-ship.png';
plane.onload = function () {
planeContext.drawImage(plane, 0, 0, 70, 80, 50, 250, 70, 80);
}
In the above code, the sky is coming at the front of the plane making the plane invisible.
I also tried to use the same context like this but i am not able to bring the image at the top of another.
The most effective way to do this (especially as it looks like you're creating a game) is to use two separate canvas elements, positioned on top of each other using CSS.
For example:
var canvasMain = document.getElementById('canvasMain');
var canvasBackground = document.getElementById('canvasBackground');
var skyContext = canvasMain.getContext('2d');
var sky = new Image();
sky.src = 'https://i.stack.imgur.com/xjj19.jpg';
sky.onload = function () {
skyContext.drawImage(sky, 0, 0, 250, 250, 50, 50, 250, 250);
}
var planeContext = canvasBackground.getContext('2d');
var plane = new Image();
plane.src = 'https://i.stack.imgur.com/nHugQ.png';
plane.onload = function () {
planeContext.drawImage(plane, 0, 0, 70, 80, 50, 250, 70, 80);
}
.canvas {
position: absolute;
top: 0;
left: 0;
}
<canvas id="canvasMain" class="canvas" width="700" height="500"></canvas>
<canvas id="canvasBackground" class="canvas" width="700" height="500"></canvas>
The issue with your code is that the images are drawn once loaded and I would suspect that because the sky image is larger than the plane image it takes longer to load so the sky image is being drawn second.
Drawing things on canvas works like layers in photoshop with whatever is drawn last overwriting things drawn before it.
It is possible to use the same canvas for both the sky and the plane, you just need to wait until both images have loaded then draw them in the correct order to the sky is drawn first, then the plane on top.
You can use the same canvas context for both objects if the are on the same canvas, no need to create multiple contexts (2 just point to the same place anyway). Usually when I work with canvases I just create one context variable called ctx as its a lot quicker than typing context.etc all the time.
almcd answer is one way to do it, though to me the background and main are reversed; I would put the sky / galaxy on the background and draw the plane on the main canvas, but there is a better way...
If the sky never changes, 2 canvases is not even needed, just one canvas with a background image behind it; the sky. When it comes time to animate the plane, this method of having the background a static image means there is less to draw each frame of the game loop, so you will get better FPS.
In terms of a solution for you, I think 1 canvas with the sky as a background image positioned by CSS, and only the plane being drawn on the canvas is the best, here is the code for that...
<!doctype HTML>
<html>
<head>
<style>
#canvasContainer {
background-image: url('https://i.stack.imgur.com/xjj19.jpg');
background-repeat: no-repeat;
}
</style>
</head>
<body>
<div id="canvasContainer">
<canvas id="canvas" width="1200" height="600"></canvas>
</div>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Load the plane and draw it.
var plane = new Image();
plane.src = 'https://i.stack.imgur.com/nHugQ.png';
plane.onload = function () {
ctx.drawImage(plane, 100, 100);
}
</script>
</body>
</html>
You can move the plane by changing the 100, 100 parameters sent to draw image, as these are the left and top used to position the plane image.
Kind regards,
DouG.
Creator of Winwheel.js a feature packed JavaScript library for making spinning prize wheels on HTML canvas. See http://dougtesting.net

How to show multiple external svg graphics in a html5 canvas

I have created a html 5 canvas and added some shapes using
ctx.fillRect(X,Y,W,H); and some other javascript functions.
Now i want to add a svg graphic in multiple places of that canvas.
The reason i want to use a svg is the sharpness & quality of the image.
I tried using drawImage method in HTML5 but the image i want to draw is doesn't give a very quality output when it's added to the canvas using drawImage method.No matter how high resolution image i use it makes a very low quality image.
But i think using a svg graphic is the solution.
This is the code i used,
<canvas id="myCanvas" style="border: 2px solid #000000; width: 1280px; height: 800px;"></canvas>
<img id="location" src="location.png" alt="The Scream" width="25.5" height="41.5">
<script >
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillRect(4,4, 12,10);
ctx.fillStyle=fontBlack;
ctx.fillText("1",8,10);
ctx.fillRect(5,16, 7, 16);
ctx.fillRect(5,33, 7, 28);
ctx.fillRect(5,62, 7, 50);
ctx.fillRect(5,113, 7, 15);
ctx.fillRect(5,129, 7, 15);
//I have a list of coordinates in a javascript object list called selectedShelfList, I'm getting the necessary coordinates from that.
function drawLocations(){
for (var i=0; i<selectedShelfList.length; i++)
{
var x_coordinate = selectedShelfList[i].shelf_x;
var y_coordinate = selectedShelfList[i].shelf_y;
var img=document.getElementById("location");
ctx.drawImage(img,x_coordinate,y_coordinate,8.5,13.8);
//Instead of drawImage method i want to use a code to show a svg graphic here
}
}
</script >
As solutions i found on stackoverflow for this problem,
I tried using canvg.js as mentioned in the previous similar questions but it wasn't clear.
for example:
var ctx = document.getElementById('test').getContext('2d');
ctx.drawSvg('<svg><rect x="0" y="0" width="100" height="200" fill="red" /></svg>', 0 , 0 , 500, 500);
How shoul i give the url for external svg in this command?
Can i use the url in between the '' as the parameter for drawSvg ?
Eg: ctx.drawSvg('location.svg', 0 , 0 , 500, 500);
Is there any way i can show a svg graphic inside a canvas?
Can canvg do the trick? If so how exactly?
Please help me on this. :)
[Edited: include example of very small map pin]
Rendering a circle in a small 10 pixel boundary will always result in pixilation.
There's just too few pixels to "round" an edge.
Here's an example of a more square map pin that is far less pixelated:
You can produce this map pin in canvas code like this:
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(110,100);
ctx.lineTo(110,107);
ctx.lineTo(105,115);
ctx.lineTo(100,107);
ctx.lineTo(100,100);
ctx.closePath();
ctx.fillStyle="gold";
ctx.fill();
ctx.strokeStyle="black";
ctx.lineWidth=2;
ctx.stroke();
[Original answer]
SVG scales well since it is vector drawn.
You should be able to do this and get a high quality result:
Download this test image:
https://dl.dropboxusercontent.com/u/139992952/stackoverflow/rocket.svg
Then this code will scale the svg rocket while maintaining quality:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var size=100;
var svg1=new Image();
svg1.width=150;
svg1.onload=function(){
ctx.drawImage(svg1,0,0,size,size);
}
svg1.src="rocket.svg";
$("#bigger").click(function(){
size+=100;
ctx.drawImage(svg1,0,0,size,size);
});
}); // end $(function(){});
</script>
</head>
<body>
<button id="bigger">Bigger!</button><br>
<canvas id="canvas" width=900 height=900></canvas>
</body>
</html>
Using the canvg worked!
var ctx = document.getElementById('test').getContext('2d');
ctx.drawSvg('location.svg', 0 , 0 , 100, 100);
using above code worked. Earlier I haven't add the javascript files into the html file properly.
Adding them to local folder worked
<script type="text/javascript" src="rgbcolor.js"></script>
<script type="text/javascript" src="StackBlur.js"></script>
<script type="text/javascript" src="canvg.js"></script>
Still the image quality is not that much but it's better than using an image with drawImage method.

HTML5 Canvas moving alpha mask

I have a background, let's say it's green grass. On top of the background I have a black overlay. What I want now is to make a movable hole in the overlay so that you can see the background like in the image below.
I am pretty new to canvas so I'm not sure what I'm supposed to look for. Alpha mask?
So my question is how can I achieve the effect demonstrated in the image above?
If it were HTML I would have two images of the grass, one as the background and one above the overlay in a div with a border radius that can move and just calculate positions.
Thanks.
Are you looking for a moving "flashlight" kind of effect?
If so, you can do that by drawing a circular path and then using it as a clipping region with: context.clip();
Anything drawn after the .clip() will be viewed through the clipping path.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/pRzxt/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
var radius=50;
var x=100;
var dx=10;
var y=100;
var dy=10;
var delay=10;
var img=new Image();
img.onload=function(){
var canvas1=document.getElementById("image");
var ctxImg=canvas1.getContext("2d");
ctxImg.drawImage(img,0,0,img.width,img.height,0,0,canvas.width,canvas.height);
animate();
}
img.src="http://lh3.ggpht.com/_Z-i7eF_ACGI/TRxpFywLCxI/AAAAAAAAAD8/ACsxiuO_C1g/house%20vector.png";
function animate() {
if(--delay<0){
// update
x+=dx;
if(x-radius<0 || x+radius>=canvas.width){dx=-dx;}
y+=dy;
if(y-radius<0 || y+radius>=canvas.height){dy=-dy;}
delay=10;
// draw stuff
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.beginPath();
ctx.arc(x,y, radius, 0, 2 * Math.PI, false);
ctx.clip();
ctx.drawImage(img,0,0,img.width,img.height,0,0,canvas.width,canvas.height);
ctx.restore();
}
// request new frame
requestAnimFrame(function() {
animate();
});
}
}); // end $(function(){});
</script>
</head>
<body>
<p>Image clipped by moving circle</p>
<canvas id="canvas" width=300 height=200></canvas>
<br/><p>Unclipped image</p>
<canvas id="image" width=300 height=200></canvas>
</body>
</html>
I did something similar for a little canvas test I was working on a while back. What you can do is create a div with a canvas element on top of the bottom layer and draw a radial gradient with transparency on that top layer canvas. I have a fiddle here: http://jsfiddle.net/CnEBQ/14/
In particular look at this bit of code for the radial gradient. The context is attached to the top div canvas:
var gradient = tCTX.createRadialGradient(CANVAS_SIZE.x/2, CANVAS_SIZE.y/2, 250, CANVAS_SIZE.x/2, CANVAS_SIZE.y/2, 0);
gradient.addColorStop(0, "#000");
gradient.addColorStop(1, "transparent");
tCTX.fillStyle = gradient;
tCTX.fillRect(0, 0, CANVAS_SIZE.x, CANVAS_SIZE.y);
There may be a little bad code in there, but it should give you an idea of whether this is where you want to go. You could redraw the top layer "hole" as needed on a timer or some event to get it moving. And you can play with the gradient setting to get more or less "darkness".
I'm having quite a time trying to find a good reference to the functions I'm using here, but a decent place to look for more explanation of these functions is
the Mozilla Canvas API
where the parameters to the gradient functions are explained. Especially useful since they're not immediately obvious.

Categories