How to center the image inside of canvas in javascript? - javascript

I have a problem with centring the image inside of the canvas. Canvas has to be full sized. The whole thing should create a web preloader. Styling image inside of css does not work in this case.
<style> canvas{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #000000;
z-index: 99; }
</style> <body>
<canvas id="c"><img id="logo" width="800" height="150" src="imgsource" alt="logo"></canvas> <div> web content </div>
<script>
jQuery(window).on('load', function() {
jQuery('#c').delay(7000).fadeOut('slow');
jQuery('body').delay(7000).css({'overflow':'visible'});
})
window.onload = function() {
var c = document.getElementById("c");
var ctx = c.getContext("2d");
var img = document.getElementById("logo");
ctx.drawImage(img, 50, 0);
} </script>

The following only demonstrates the centering of an image inside a canvas with drawImg. Note that the image to the left is from the html <img> element while the other is from the drawImg call.
Outside of stackoverflow you'd have to wait for the image to load before drawing it, but as you also already use .on('load', ...) i assume you are aware of that.
To avoid having two images, create the image element in javascript and don't add it to the document but only use it for rendering.
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
let img = document.getElementById("i");
//just to make the area the canvas occupies visible
ctx.fillStyle = 'grey';
ctx.fillRect(0, 0, canvas.width, canvas.height);
//draw the image centered
ctx.drawImage(
img,
canvas.width / 2 - img.width / 2,
canvas.height / 2 - img.height / 2
);
<html>
<body>
<img id="i" src="http://i.imgur.com/kdJicdy.png"/>
<canvas id="canvas" width="320" height="240">Your browser doesn't support canvas</canvas>
</body>
</html>

var canvas = document.getElementById('canvas');
var image = new Image();
image.src = 'http://placehold.it/300x550';
image.onload = function () {
var canvasContext = canvas.getContext('2d');
var wrh = image.width / image.height;
var newWidth = canvas.width;
var newHeight = newWidth / wrh;
if (newHeight > canvas.height) {
newHeight = canvas.height;
newWidth = newHeight * wrh;
}
var xOffset = newWidth < canvas.width ? ((canvas.width - newWidth) / 2) : 0;
var yOffset = newHeight < canvas.height ? ((canvas.height - newHeight) / 2) : 0;
canvasContext.drawImage(image, xOffset, yOffset, newWidth, newHeight);
};
<canvas id="canvas" width="500" height="500" style="border: 1px solid black" />

Related

How to overlay a canvas dynamically onto an image

I have an img tag and I need to draw on it with a transparent overlay.
I was thinking about a canvas mathing the image size and position, but because my context is dynamic I need to adjust there parameters with javascript.
I tried to work with canvas.style.left, canvas.style.top but they not seem to work as expected (canvas.style.left works only if I assign 0 to it).
Furthermore, when I assign the width and the height like this:
canvas.width = img.clientWidth
canvas.height = img.clientHeight
It seems not to get the right values.
I'm using DevExpress to dynamically load the BinaryImage from a Model fetched from a database, this is the portion of code:
<div class="container-fluid" style="margin: 10px; margin-bottom: 15px">
#if (Model.Image != null) {
Html.DevExpress().BinaryImage(
settings => {
settings.Name = "mapImage";
settings.Width = System.Web.UI.WebControls.Unit.Percentage(100);
}).Bind((Model.Image).ToArray()).GetHtml();
<canvas id="mapOverlay" ></canvas>
}
</div>
Note that the DevExpress code results in the following img element:
<img class="dxeImage_Material" id="mapImage" src="/DXB.axd?DXCache=e86a5e5f-7d8b-4704-9330-ec7b9fa2ad38" alt="" style="width:100%;">
Is there any DevExpress component to use I may not be aware of that I could use?
EDIT
Following this code:
function DrawPoint(x, y, z) {
$("#myModal").modal("show");
var canvas = document.getElementById("mapOverlay");
var c = canvas.getContext('2d');
console.log("Setting canvas stuff");
var img = document.getElementById('myMap');
console.log("Image x: " + img.x)
console.log("Image y: " + img.y)
canvas.width = img.width;
canvas.height = img.height;
canvas.style.left = img.x + "px";
canvas.style.top = img.y + "px";
clearCanvas();
c.beginPath();
c.arc(x, y, 10, 0, Math.PI * 2, false);
c.fillStyle = "red";
c.fill();
c.stroke();
c.closePath();
}
The console.logs inside the function tells me that img.x and img.y are both 0, but if I get their values from the console in my browser they have some value.
What can this be?
Note that the canvas width/height attributes are different from canvas width/height styles. Attributes effect drawing, while style effects rendering. See below:
document.addEventListener("DOMContentLoaded", function(event) {
var drawStuff = function(canvas, context) {
context.rect(0, 0, 100, 100);
context.stroke();
}
var imageMouseEnter = function(event) {
var image = event.target;
var canvas = document.getElementById("overlay");
var context = canvas.getContext("2d");
canvas.style.left = image.x + "px";
canvas.style.top = image.y + "px";
canvas.style.width = image.width + "px";
canvas.style.height = image.height + "px";
drawStuff(canvas, context);
};
var imageMouseExit = function(event) {
};
var images = document.getElementsByTagName('img');
for(var i = 0; i < images.length; i++) {
images[i].addEventListener('mouseover', imageMouseEnter);
images[i].addEventListener('mouseout', imageMouseExit);
}
});
<canvas id="overlay" width="100" height="100" style="position:absolute"></canvas>
<div style="width:350px">
<img src="http://via.placeholder.com/350x150" />
<img src="http://via.placeholder.com/145x100" />
<img src="http://via.placeholder.com/200x100" />
<img src="http://via.placeholder.com/350x65" />
</div>

Upload picture to canvas

I've done a single upload for image and put image to canvas, here is the DEMO. Now, the problem is that when I upload a picture and then I want to upload another one the previous picture still remain underneath.
This is my code:
JS:
var canvas = document.getElementById('main');
var ctx = canvas.getContext('2d');
var fileInput = document.getElementById('fileInputTest');
fileInput.addEventListener('change', imageLoader, false);
function imageLoader() {
var reader = new FileReader();
reader.onload = function(event) {
img = new Image();
img.onload = function() {
var MAX_WIDTH = 150;
var MAX_HEIGHT = 150;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
ctx.drawImage(img, 0, 0, width, height);
}
img.src = reader.result;
}
reader.readAsDataURL(fileInput.files[0]);
}
HTML:
<input type="file" id="fileInputTest" />
<canvas id="main" width="150" height="150"></canvas>
CSS:
#main {
border: 2px dotted black;
border-radius: 5px position: absolute;
}
JSFIDDLE DEMO
Just add this before you draw your image in context.
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, width, height);
You just have to clear your canvas area before drawing your image.

JS canvas resizing in all sides

I am trying to resize a canvas in all directions the way Photoshop does.
I tried with JS but it's not matching the output I got from the Photoshop CC canvas size feature.
Original Image (600 x 439): http://i.imgur.com/rXURSWC.jpg
Resized with JS code (580 x 430): http://i.imgur.com/fwUiHyF.png
Resized with Photoshop CC (Image->Canvas Size) (580 x 430): http://i.imgur.com/smXTNv2.jpg
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = 0;
var y = 0;
var width = 580;
var height = 430;
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, x, y, width, height);
};
imageObj.src = 'https://i.imgur.com/rXURSWC.jpg';
<body>
<canvas id="myCanvas" width="580" height="430"></canvas>
</body>
So, any idea how I can resize canvas in all directions the way photoshop CC does so that it can match to output of Photoshop CC.
JSFiddle: https://jsfiddle.net/f2L4b942/
What you are asking for is just to crop your image, but keep the anchor point in the middle.
This is easily implemented :
Set the x and y parameters of drawImage to the difference between the required size and the original one, divided by 2.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var requiredWidth = canvas.width = 580;
var requiredHeight = canvas.height = 430;
var img = new Image();
img.onload = function() {
// all you need is here
var offsetX = (requiredWidth - img.naturalWidth) / 2;
var offsetY = (requiredHeight - img.naturalHeight) / 2;
context.drawImage(img, offsetX, offsetY, img.naturalWidth, img.naturalHeight);
};
img.src = 'http://i.imgur.com/rXURSWC.jpg';
<canvas id="myCanvas" width="580" height="430"></canvas>
You could accomplish this by redefining the canvas width and height upon image load ...
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = 0;
var y = 0;
var imageObj = new Image();
imageObj.onload = function() {
canvas.width = this.width;
canvas.height = this.height;
context.drawImage(imageObj, x, y);
};
imageObj.src = 'http://i.imgur.com/rXURSWC.jpg';
body {
margin: 0px;
padding: 0px;
}
#myCanvas {
border: 1px solid black;
}
<canvas id="myCanvas" width="580" height="430"></canvas>

How to stretch image in canvas?

I need to stretch my image to the top and to the bottom in canvas.
How can I do this?
Here's the codepen
HTML
<canvas id="myCanvas" width="240" height="297" style="border:1px solid #d3d3d3;">
</canvas>
JS
window.onload = function() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image;
img.src = "http://www.w3schools.com/tags/img_the_scream.jpg"
ctx.drawImage(img, 10, 10);
}
drawImage allows you to pass the width and height as third and fourth parameter.
So your last line should be ctx.drawImage(img, 0, 0,c.width, c.height); in order to fill the entire canvas.
If you just want an image to stretch to fill in the height you can do something like this jsFiddle : https://jsfiddle.net/CanvasCode/92ekrbnz/
javascript
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image;
ctx.fillStyle = "#000";
ctx.fillRect(0,0,c.width,c.height);
img.src = "http://www.w3schools.com/tags/img_the_scream.jpg"
img.onload = function () {
ctx.drawImage(img, (c.width / 2) - (img.width / 2), 0, img.width, c.height);
}
However the link you provided basically just zooms into the image.
So you can do something like this jsFiddle : https://jsfiddle.net/CanvasCode/92ekrbnz/2/
javascript
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image;
var zoom = 1.0;
img.src = "http://www.w3schools.com/tags/img_the_scream.jpg"
setInterval(function () {
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, c.width, c.height);
ctx.drawImage(img, (c.width / 2) - ((img.width * zoom) / 2), (c.height / 2) - ((img.height * zoom) / 2),
img.width * zoom,
img.height * zoom);
}, 1);
document.getElementById("zoomIn").onclick = function () {
zoom += 0.1;
};
document.getElementById("zoomOut").onclick = function () {
if (zoom > 0.1) {
zoom -= 0.1;
}
};
Here is a more detailed answer of how to fill or fit a canvas while also keeping the image aspect.
Fill canvas

Draw a circle in the middle of canvas

Having -
HTML -
<canvas id="myCanvas" >
</canvas>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 30;
context.beginPath();
context.arc(centerX,centerY, radius, 0, 2 * Math.PI);
context.fillStyle = 'blue';
context.fill();
</script>
CSS-
#myCanvas {
border:2px solid;
display:inline-block;
width:500px;
height:400px;
}
http://jsfiddle.net/urielz/3E656/
but I get not accurate circle . How can I make it accurate circle ?
Demo Fiddle
If you just want set the canvas size in CSS, change your code to:
<canvas id="myCanvas"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var style = window.getComputedStyle(canvas);
if (canvas.getContext) {
canvas.width = parseInt(style.getPropertyValue('width'));
canvas.height = parseInt(style.getPropertyValue('height'));
}
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 30;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'blue';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
this.arc(x, y, radius, 0, Math.PI * 2, false);
this.fill();
</script>
You need to set explicitly the size of your canvas, otherwise it will get the default size: 300x150.
you should do something like this
<canvas id="myCanvas" width="500" height="400"></canvas>
or via javascript (before getting the context)
canvas.width = 500;
canvas.height = 400;
var context = canvas.getContext('2d');
You need to set the width of your canvas, like so:
<canvas id="myCanvas" width="500" height="400"></canvas>
Place below code after begin path:
var centerX = canvas.width;
var centerY = canvas.height;
context.arc(centerX*0.5,centerY*0.5,10,0 ,radius, 0, 2 * Math.PI);
Css:
#myCanvas {
border:2px solid;
display:inline-block;
width:600px;
height:300px;
}

Categories

Resources