How to make a minimap of the whole page in Javascript - 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

Related

Pixel modification on a Video frame in HTML5 canvas

I am in the process of building an app for my research and I am new to canvas. I am trying to make a video out of a set of images and I need to be able to dynamically change a particular frame. I was successful in making the video but unable to modify a particular frame when I reach it. Below is the code for the same.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Images with intervals</title>
</head>
<body>
<canvas id="myCanvas1" width="400" height="200" style="position:absolute;right:0; margin-right:auto; background-color:#bbb"></canvas>
<canvas id="myCanvas2" width="400" height="200" style="position:absolute;left:0; margin-left:auto; background-color:#666"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('myCanvas2');
var context = canvas.getContext('2d');
var i = 0;
var im1 = 'images/img1.png';
function drawScreen() {
context.drawImage(im1, 0, 0,50,50);
}
setInterval(function() {
var im = ['images/img1.png', 'images/img2.png', 'images/img3.png', 'images/img4.png', 'images/img5.png'];
// Create the image object
var img = new Image();
//alert(window["i"]);
// If the image is loaded draw it on canvas
img.addEventListener('load', function() {
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0);
});
//alert(window["i"]);
// pass in the image source
img.src = im[i++];
alert(window["i"]);
// if the image is last, change it back to the first
i = i > im.length - 1 ? 0 : i;
//alert(window["i"]);
if(i==3)
{ drawScreen();
//alert(window["i"]);
}
}, 1000);
</script>
</body>
</html>
When the value of i=3(meaning in 3 seconds according to the setInterval function), I am trying to display another image 'im1' as an example, which I am unable to do. I am new with HTML5 and canvas. Any help and suggestions here is deeply appreciated.

cant get HTML5 canvas to work on any browser

I have just started learning how to draw on using HTML5 canvas, I'm trying to make a simple square but all I get is a blank screen, I don't get errors in the chrome console either
<!Doctype html>
<html>
<head>
<title>Drawing to a canvas</title>
<script type="text/javascript" language="javascript" >
window.onload = draw;
function draw()
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgba(0,200,0,1)";
ctx.fillRect = (36,10,50,50);
}
</script>
</head>
<body>
<canvas id="canvas1" width="400" height="300">
This text is displayed if your browser
does not support HTML5 Canvas.
</canvas>
</body>
</html>
This seems quite simple but it just won't work for me!
One error is the one Elon pointed out, but you are using the fillRect wrong as well:
ctx.fillRect = (36,10,50,50);
should be:
ctx.fillRect(36,10,50,50);
Please debug before asking for help!
You've got syntax error because you forgot about { after function name.
function draw() {
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgba(0,200,0,1)";
ctx.fillRect(36,10,50,50);
}

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.

Javascript Canvas Image onclick not working

I am failing at getting a DOM Image onclick event to work.
var context = document.getElementById('canvas').getContext('2d');
var image = new Image();
image.src = "foo.png"
image.onclick = function(e) { console.log("clicked"); }
setInterval(function() {
context.drawImage(image, 100, 100, 50, 50);
};
Why do I not get the log message when i click on the image. In developer tools i can see the onclick function is not null for the image.
Yes, what Musa said...and a few other things.
Some changes to your code
Image.src=”foo.png” should come after the image.onclick function
Context.drawImage should be inside the image.onclick function
setInterval is not needed as far as I can see
Try this:
<!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 context=document.getElementById("canvas").getContext("2d");
var image=new Image();
image.onload=function(){
context.drawImage(image,0,0);
}
image.src="http://i.imgur.com/nJiIJIJ.png";
document.getElementById("canvas").addEventListener("click", function(){console.log("clicked");}, false);
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
You cannot set onclick for a particular image added in canvas . You can set onclick for the whole canvas alone so you have to use any third party js or else you should do some calculations which finds that you clicked on the image of the canvas ..
Other users are right.
The image you draw on the canvas is a DOM element but it is rendered in a position which is not stored in the DOM.
This doesn't mean you can access it's position and compare it with the mouse position.
I'm using an external library here, but it does what you need: http://jsfiddle.net/Saturnix/cygUH/
this is the library used.
Since I can't post link to jsfiddles without posting the code, here's the script I've wrote for you.
function demo(g) {
g.ctx.font = "bold 16px Arial";
g.draw = function () {
g.ctx.clearRect(0, 0, g.width, g.height)
var posX = 0;
var posY = 0;
g.ctx.drawImage(image, posX, posY);
if (g.mouseX > posX && g.mouseX < image.width &&
g.mouseY > posY && g.mouseY < image.height &&
g.mousePressed)
g.ctx.fillText("You're clicking the image!", g.mouseX, g.mouseY);
}
}
You can cast a ray (with an onclick on the canvas) into the canvas and manually test your images for intersection with the ray. You should write a
objectsUnderPoint( x, y );
function that returns an array of all the images that intersect with the ray at x, y.
This is the way it is usually done in 3D engines as well. You ofcourse need to keep the image position as a property of the image for intersection testing.

Evaluating java script expression inside function argument

I am trying to define a scale variable (s), where the image scales dynamically according to its value. I don't think the expression s*100 is evaluating as there is no difference in size. What is wrong.
<html>
<body onload="draw();">
<canvas id="canvas" width="150" height="150"></canvas>
</body>
<script type="application/javascript">
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var s = 10000;
ctx.fillStyle = "rgba(0, 0, 200, 0.1)";
ctx.fillRect (0, 0, s*100, s*100);
}
}
</script>
</html>
The reason you don't see any change is because you are trying to render a gigantic rectangle onto a 150x150 canvas, so the part outside the canvas is ignored. Make your canvas really big and you'll see it working. Here's a working example, it keeps rendering the same square by increasing the scale each time. http://jsfiddle.net/3ZAex/2/
Figured it out.. it was because my canvas was too small.. width="150" height="150"

Categories