I have this snippet of code that makes an SVG and draws it to a canvas.
Jsbin Link: https://jsbin.com/lehajubihu/1/edit?html,output
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>JS Bin</title>
<style>
#imgNode {
border: "10px dotted black";
}
</style>
</head>
<img id="imgNode" style="border: 1px dotted black"></img>
<body>
<script>
const { body } = document;
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const tempImg = document.createElement("img");
tempImg.addEventListener("load", onTempImageLoad);
tempImg.src =
"data:image/svg+xml," +
encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml"><style>em{color:red;}</style><em>I</em> lick <span>cheese</span></div></foreignObject></svg>'
);
const targetImg = document.querySelector("#imgNode")
function onTempImageLoad(e) {
ctx.drawImage(e.target, 0, 0);
targetImg.src = canvas.toDataURL();
}
</script>
</body>
</html>
The code does work but the width and height is not dynamic. From the image, we can see that the size is very big compared to the size of the actual HTML as shown below
How do I make the image/canvas render only the HTML and no extra space?
In your image rendering function onTempImageLoad(e) you can add this:
function onTempImageLoad(e) {
canvas.width = tempImg.width;
canvas.height = tempImg.height;
ctx.drawImage(e.target, 0, 0);
targetImg.src = canvas.toDataURL();
}
But you need to check your svg because it's the one that contains extra spaces.
It seems to be in 300x150, you can do some tests by setting the size of the svg in pixels by replace width="100%" and height="100%".
tempImg.src =
"data:image/svg+xml," +
encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" width="100px" height="50px"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml"><style>em{color:red;}</style><em>I</em> lick <span>cheese</span></div></foreignObject></svg>'
);
Related
I wanted to take a picture of a photo I have on my webpage using a canvas to get a local url for it. Obviously, this is redundant because I already have the url for the photo, but it would be useful in other contexts (like videos). When I execute this code, a white box appears that is not the image I use for testing purpose. Where am I going wrong here?
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="main.js" defer></script>
</head>
<style>
img{
height: 500px;
width: 500px;
}
</style>
<body>
<img id="test" src="img_url">
<button onclick="takePhoto()">Click Me</button>
</body>
</html>
JS:
var width=200
var height=300
function takePhoto(){
var test = document.getElementById("test")
var canvas = document.createElement("canvas")
document.body.appendChild(canvas)
var cxt = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
cxt.drawImage(test, width, height);
var data = canvas.toDataURL('image/png');
console.log(data)
}
The 3 params version of drawImage() is
drawImage(source, x, y);
You did set the x and y params to the width and height of the canvas, which means the browser will draw the image from the bottom right corner of the canvas, which obviously doesn't do much.
You probably wanted the 5 params version
drawImage(source, x, y, resizeWidth, resizeHeight);
Where you'd set x and y to 0.
I'm currently working on an html canvas javascript game, and it's just about finished, but I want to scale up the canvas so the whole game is bigger. I tried using something like
var imgData = ctx.getImageData(0, 0, 300, 500);
ctx.putImageData(imgData,0,0,0,0,360,600)
but using this method I couldn't increase the size of the image. What is the best method for this?
There are multiple ways you can achieve this, the two that i've experimented with would use 2 seperate canvases, putImageData is a little weird, and does not work well for scaling up, what i would recommend, is have a separate canvas, the size of the scaled up version, and then use ctx.drawImage to draw the first canvas on the scaled up version:
var c = document.getElementById('c');
var ctx = c.getContext('2d');
var c2 = document.getElementById('c2');
var ctx2 = c2.getContext('2d')
ctx.fillStyle = "red";
ctx.fillRect(10,10,100,100)
var scaleX = c2.width / c.width;
var scaleY = c2.height / c.height;
ctx2.drawImage(c,0,0,c2.width,c2.height)
canvas{
border: 2px solid black
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<canvas id="c" width="200" height="200"></canvas>
<canvas id="c2" width="400" height="400" ></canvas>
<script src="script.js"></script>
</body>
</html>
The other way is to just scale up the context, then draw the image at 0,0, with no width or height specified:
var c = document.getElementById('c');
var ctx = c.getContext('2d');
var c2 = document.getElementById('c2');
var ctx2 = c2.getContext('2d')
ctx.fillStyle = "red";
ctx.fillRect(10,10,100,100)
var scaleX = c2.width / c.width;
var scaleY = c2.height / c.height;
ctx2.scale(scaleX,scaleY)
ctx2.drawImage(c,0,0)
ctx2.scale(1/scaleX,1/scaleY)
canvas{
border: 2px solid black
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<canvas id="c" width="200" height="200"></canvas>
<canvas id="c2" width="400" height="400" ></canvas>
<script src="script.js"></script>
</body>
</html>
One more option is to use the css scale() tag, but that messes with mouse clicks, and is really annoying so i wouldn't do that. Keep in mind, all methods that scale up the canvas (unless your scaling up coordinates and redrawing), will result in blur.
Hope this helps :D
I want to change all images src of document to dataURL.
I am trying to draw all image in canvas through for of loop but it doesn't work.
Help me!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<img src="./adudio1.png" alt=""height="300px"width="200px"class="i">
<img src="./adudio1.png" alt=""height="300px"width="500px"class="i">
</body>
<script>
const img = document.querySelectorAll("img");
for(items of img){
let c = document.createElement("canvas");
document.querySelector("body").append(c);
c.height=items.height;
c.width=items.width;
c.style="border:2px solid #CCC;";
ctx = c.getContext("2d");
ctx.drawImage(items,0,0)
}
</script>
</html>
Your code isn't waiting for the images to load. Add your canvas drawing code to the onload function of each image to execute it only once the image data arrives.
const images = document.querySelectorAll("img");
for (const image of images) {
image.onerror = function () {
console.error("image failed to load");
};
image.onload = function () {
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.height = image.height;
canvas.width = image.width;
canvas.style = "border: 2px solid #CCC;";
ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
};
}
<img src="http://placekitten.com/200/300"
alt=""
height="300"
width="200"
class="i"
>
<img src="http://placekitten.com/200/300"
alt=""
height="300"
width="200"
class="i"
>
As an aside, height="300px"width="500px" needs spaces between properties and doesn't need px after each value.
Use const item rather than items to avoid creating a global in your loop.
here is my code below I can't figure out what I'm doing wrong. when I preview it, the image isn't there, just the canvas border.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Page Title</title>
</head>
<canvas id="myCanvas" width="200" height="100"
style="border:1px solid #000000;">
</canvas>
<body>
<script>
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var sticky = new Image();
sticky.src = "sticky.png";
sticky.onload = function() {
context.drawImage(sticky, 0, 0);
};
</script>
</body>
</html>
the console displays the link to your file. look there if the correct
Maybe you should have to wait until the image is loaded before you draw it. Try this instead:
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
make_base();
function make_base()
{
base_image = new Image();
base_image.src = 'http://techtastico.com/files/2014/06/Apple-Swift-Logo.png';
base_image.onload = function(){
context.drawImage(base_image, 0, 0);
};
}
<canvas id="myCanvas" width="200" height="100"
style="border:1px solid #000000;">
</canvas>
I have created an HTML5 canvas game which involves dragging and selecting objects(words) from two canvases. The screen also has two buttons. But unfortunately my program is hard coded in terms of selecting words as I have entered the co-ordinates where the words are drawn on canvas. My screen resolution is 1366 x768. Now whenever the resolution is changed, the buttons move somewhere else and the mouse never selects the dragged words rather some words else above it. I am in a big trouble now, please help !!
<html>
<head>
<title>Word Search</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type = text/css href="style.css">
<script type="text/javascript" src="keywords.js"></script>
<script type="text/javascript" src="game.js"></script>
<script type="text/javascript" src="highlight.js"></script>
<script type="text/javascript" src="grid.js"></script>
<script src="http://code.createjs.com/easeljs-0.7.0.min.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>
<h1 id="heading">Find Keywords</h1>
<h3 id="results">Drag through the lettered Squares..!</h3>
<canvas id ='canvas1' height = 450 width="450" style= "border :1px solid black"> </canvas>
<canvas id ='canvas2' height = 450 width="250" style= "border :1px solid black"></canvas>
<input type='button' value="HIGHLIGHT ALL" id="button1" onclick="highlight();" />
<input type='button' value="NEXT" id="button2" onclick="next();"/>
<script>
var words =[];
window.onload = function(){
begin();
};
function begin()
{
wordSearchPuzzle();
}
function wordSearchPuzzle()
{
words.length=0;
words = getwords(8);
var puz =wordfind(words);
game(words,puz);
}
function next()
{
var canvas = document.getElementById("canvas1");
var ctx1 = canvas.getContext("2d");
var canvas2 = document.getElementById("canvas2");
var ctx2 = canvas2.getContext("2d");
ctx1.clearRect(0, 0, canvas.width, canvas.height);
ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
wordSearchPuzzle();
}
</script>
</body>
</html>
This is possible, I have done it int he past with a canvas that would be dynamically sized based on the screen size.
If I remember correctly i did something like this.
I placed the canvas in a div, and gave the div a dynamic width, something like style="width: 30%"
I placed the canvas inside this div and tied css to give the canvas a style="width: 100%"
<div style="width:30%">
<canvas id="can" style="width:100%"></canvas>
</div>
I tied into the window resized event and read the client size to determine the element width and height to change the canvas
window.resize = function(){
var canvas = document.getElementById("can");
canvas.width = canvas.clientWidth;
canvas.height = //some value based on width
}
You then need to redraw your canvas as resizing will clear the canvas of all content