Make HTML canvas as image source fit the aspect ratio? - javascript

I am currently trying to make a pictionary application in HTML/CSS/PHP and after making the application I am trying to make it mobile friendly/responsive.
The way I am displaying the canvas that is being drawn on on the other players' screen is this:
javascript
let canvas = document.querySelector("canvas");
let base64dotpng = canvas.toDataURL();
ws.send("canvas:" + base64dotpng);
Which I am sending over a websocket. This works perfectly fine and when I read the data back in like this:
let ctx = document.querySelector("canvas").getContext('2d');
let canvasImage = new Image();
canvasImage.src = msg;
if (newRound) {
ctx.clearRect(0, 0, window.innerWidth * 0.525, window.innerHeight * 0.90);
}
ctx.drawImage(canvasImage, 0, 0);
However now that I'm implementing a mobile version whenever I load in a canvas on mobile the ratio of the canvas is a bit different and it does not load the full image.
css
This is my css on general vs mobile:
general:
#drawingCanvas {
display: inline-block;
background-color: white;
border-width: 0.3vh;
border-color: black;
border-style: solid;
position: absolute;
height: 90vh;
top: 5vh;
left: 20vw;
width: 52.5vw;
}
mobile:
canvas#drawingCanvas {
z-index: 1;
top: 0;
margin-left: -20%;
display: inline-block;
width: 52.5%;
height: 99%;
}
If the canvas was to be stretched on mobile that would be fine, but right now this is the difference:
how it is being drawn on a computer browser
vs
how it is getting displayed on mobile
(the phone is in landscape mode)
So the canvas appears to be loading in at full size
Thanks in advance,
Aap.

I have found an answer in the .drawImage method of context.
The 4th and 5th parameters can be used to rescale the canvas like so:
if (isMobile){
ctx.drawImage(canvasImage, 0,0,canvasImage.width*(window.innerWidth / (canvasImage.width/0.525)),canvasImage.height*(window.innerHeight/(canvasImage.height/0.9)));
} else {
ctx.drawImage(canvasImage, 0, 0);
}

Related

why html5 canvas is not full screen when vertical scrollbar appears

I'm using a full screen canvas as background of the first section of my page. But as soon as I add the second section and vertical scrollbar appears, the height of canvas reduces a little bit and a gap appears. here's my code:
P.S: Sorry, my code contained bugs, I fixed them. now you can see the red gap.
var canvas = document.getElementById('canvas')
var c = canvas.getContext('2d')
scaleCanvas()
window.addEventListener("resize", scaleCanvas)
function scaleCanvas() {
canvas.width = window.innerWidth
canvas.height = window.innerHeight
c.fillStyle = 'black'
c.fillRect(0, 0, canvas.width, canvas.height)
}
* {
box-sizing: border-box;
max-width: 100%;
}
body {
margin: 0;
padding: 0;
}
#first-section {
position: relative;
min-height: 100vh;
background-color: red; /* to see the gap */
}
#content {
position: relative;
z-index: 2;
}
#second-section {
min-height: 100vh;
background-color: blue;
}
#canvas {
display: block;
padding: 0;
margin: 0;
border: none;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
<div id="first-section">
<canvas id="canvas"></canvas>
<div id="content">content</div>
</div>
<div id="second-section"></div>
Assuming you mean full screen, and not full page. The two are very different.
If you mean full page then the link to the Screen API will also give you details on obtaining the page size.
Size full screen canvas.
The problem is that you have content that extends outside the page width and height (innerWidth, innerHeight)
The elements with ids first-section, content, and second-section must be inside the display area or else you will get a scroll bar. The scroll bar will change the innerWidth, innerHeight values subtracting the scrollbar width or height depending on which is visible.
To prevent scroll bars the best option is to keep all content inside innerWidth, and innerHeight
Full screen with scroll bars.
If you want have the scroll bars and you are using full screen you can use the Screen API to get the width and height of the display in pixels. You can set the canvas size to match the screen without the scroll bars effecting its size.
Note Do read the provided link to Screen as what defines the screen may not be as expected. EG more than one monitor, or device orientation will effect how you use the API.
Basic example
Thus when in full-screen mode you can set the canvas size and ignore scroll bars with
function sizeFullScreenCanvas() {
canvas.width = screen.width;
canvas.height= screen.height;
}

Set aspect ratio of image without src

I use images created on the fly to maintain the aspect ratio of boxes with a fixed height. Image sources are set as data-urls provided from a canvas with a given width and height, the images are then attached to divs which can contain any content, have any height, and still maintain a fixed aspect ratio.
This works well, however, on slower phones with less memory the large number of data-urls on the page can start to be a little bit of a drag. Some of the ratios can't be reduced below a certain point resulting in relatively large canvases.
Is there any way to set the ratio of an img element without setting its source? Is there any way to set the source to a format that is an truly empty image with only a width and height?
EDIT: The snippet below throws an error - iframe restrictions, probably having to do with making images. You can see an error free version over at this CodePen.
const wrapper = document.querySelector(".wrapper");
function addRatioBox(width, height = 1) {
const cvs = document.createElement("canvas");
const img = new Image(width, height);
const box = document.createElement("div");
cvs.width = width;
cvs.height = height;
img.src = cvs.toDataURL("image/png");
box.appendChild(img);
box.className = "ratioBox";
wrapper.appendChild(box);
}
addRatioBox(1);
addRatioBox(4, 3);
addRatioBox(16, 9);
addRatioBox(2, 1);
.ratioBox {
background: orange;
display: inline-block;
height: 100%;
margin-right: 10px;
}
.ratioBox img {
height: 100%;
width: auto;
display: block;
}
/* just a whole bunch of stuff to make things prettier from here on down */
.wrapper {
background: #556;
padding: 10px;
position: absolute;
height: 20%;
top: 50%;
left: 50%;
white-space: nowrap;
transform: translate(-50%, -50%);
}
body {
background: #334;
}
.ratioBox:last-of-type {
margin-right: 0;
}
<div class="wrapper"></div>

How to add, fix and display text in image using HTML?

I have project in which I have to add text in image, After adding it will become new image and then I have to display new image.
I am able to get image and I can add the text in image.
HTML:
<img src="pic_mountain.jpg" style="width:304px;height:228px;"/>
<h2>A Movie in the Park<br />Kung Fu Panda</h2>
CSS:
.image {
position: relative;
width: 100%; /* for IE 6 */
}
h2 {
position: absolute;
top: 50px;
left: 50px;
width: 100%;
}
my initial image is like:
After adding text it will look like:
now I need to fix this text for this image as a new image. I also want to use that new image for display without affecting original image.
Is there any solution for this?
If there any other way to add text using jquery or else, then please suggest me..
PHP has literally COUNTLESS libraries for doing just this but were all lazy and nobody wants to learn a new framework so heres some simple php functions to do just this
Note: you would have to use php and then ajax to update it in real time i am unaware of any way to do what your asking in javascript
<?php
$image_path = "images/image.jpeg";
//Set the Content Type
header('Content-type: image/jpeg');
// Create Image From Existing File
$jpg_image = imagecreatefromjpeg($image_path);
// Allocate A Color For The Text
$white = imagecolorallocate($jpg_image, 255, 255, 255);
// Set Path to Font File
$font_path = 'fonts/font.TTF';
// Set Text to Be Printed On Image
$text = "text to write to image";
// Print Text On Image
imagettftext($jpg_image, 25, 0, 75, 300, $white, $font_path, $text);
// Send Image to Browser
imagejpeg($jpg_image);
// Clear Memory
imagedestroy($jpg_image);
?>
Please not that this is an example using jpeg but php supports the exact same functionality for png,gif, and a few other image types
Hi now you can try to this way
.imgSec {
position: relative;
width: 300px;
margin:0 auto;
}
.imgSec img{width:100%;height:228px;}
.imgSec h2 {
position: absolute;
top: 50px;
left: 50px;
width: 100%;
}
<div class="imgSec">
<img src="http://i.stack.imgur.com/8GnUj.jpg" />
<h2>A Movie in the Park<br />Kung Fu Panda</h2>
</div>
The HTML
<div class="item">
<img src="http://i.stack.imgur.com/8GnUj.jpg" style="width:304px;height:228px;"/>
<h2>A Movie in the Park<br />Kung Fu Panda</h2>
</div>
And the css is
.item {
position: relative;
width: 100%; /* for IE 6 */
}
h2 {
position: absolute;
top: 50px;
left: 50px;
width: 100%;
}
You can use the Canvas 2D API.
Two steps :
use drawImage() to draw your image.
use fillText() to fill your text.
Complete demo :
/* okay there are actually a few more steps.. */
var img = new Image();
img.crossOrigin ='anonymous'; // not needed if you're not using images from an other domain
img.onload = function(){ // remember to wait before your image has loaded
// our canvas element
var canvas = document.createElement('canvas');
// its drawing context
var ctx = canvas.getContext('2d');
// don't resize the canvas with css
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0,0)
ctx.font ='25px sans-serif';
ctx.fillText('Hello world', 10, 40);
// just using it as a backgroundImage to demonstrate that you can export the result, you could also just append the canvas into the doc, or use the `toBlob()` method for use with FileSaver.js e.g.
document.body.style.backgroundImage = 'url('+canvas.toDataURL()+')';
out.href = canvas.toDataURL();
};
img.src = 'https://dl.dropboxusercontent.com/s/1alt1303g9zpemd/UFBxY.png?dl=0';
body{
width: 100vw;
height:100vh;
}
<a id="out"> show me an image instead </a>

Getting true dimensions of images with jquery on collected dom elements

I am trying to get the dimensions of images on a page for further use with a custom 'lightbox' or sorts. However, when trying both a pure js method, and a jquery method, I get the output undefined on my variables. Why is this? Is it because of jquery load event? I tried both onload and ready.
Basically I need the full dimensions of the image to justify whether it should be loaded in a lightbox with a click event or not.
Update I am now able to get console feedback from the function now, however it's not providing me a dimension of the image.
$('.postbody').find('img').each(function() {
var img = new Image(), width, height;
$(img).load(function() {
width = $(this).width();
height = $(this).height();
console.log('Width: '+width+' Height: '+height);
});
console.log($(this).attr('src'));
img.src = $(this).attr('src');
});
#theater-box {
display: none;
position: fixed;
width: auto;
height: auto;
min-width: 1005px;
max-width: 1428px;
padding: 10px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0,0,0,0.90);
border: 2px solid rgba(255,255,255,0.4);
}
.postbody {
width: 90%;
height: 90%;
background: rgba(100,50,50,0.5);
}
.postbody * img {
width: 100%;
max-width: 1168px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="theater-box"></div>
<div class="postbody">
<div id="someclass"><img src="https://e8zzxa.bl3301.livefilestore.com/storageservice/passport/auth.aspx?sru=https:%2f%2fe8zzxa.bl3301.livefilestore.com%2fy2pDapooeiISgUV7-ugpyADuRULJ_stpkiALbypYJHjNxrhUqcvRsZ6eRk4PiJlClABLOfByjulDSDLOMCEpHhggVkgvM4z5Gdq0Jo-C0e1pCU%2fMajipoorHighlands2.jpg&wa=wsignin1.0" /></div>
</div>
You are setting the variables asynchronously and getting it directly.
In pseudocode it is a bit like this:
Set the function to retrieve the width and height when the images loads
Display the width and height variables (not set yet)
The functions set in step 1 runs and sets the varaibles.
So your code that uses the width and height should be inside the image.load function.
I hope it helps, if you have any further questions dont hesitate to comment :-)
Perhaps you can just put the console.log line as the last line in the $(img).load function.
Try this...
$(img).load = function() {
var $this = $(this);
width = $this.width();
height = $this.height();
}
I'm not exactly sure why the original method (which works in a lot of examples) was not working here. So I found some awesome code by GregL from right here at Stackoverflow.
Essentially, the method loads a new, and hidden image into the body, and then captures the width and height before removing it.
$('.postbody').find('img').each(function() {
var img = $(this), width, height,
hiddenImg = img.clone().css('visibility', 'hidden').removeAttr('height').removeAttr('width').appendTo('body');
width = hiddenImg.height();
height = hiddenImg.width();
hiddenImg.remove();
console.log('Width: '+width+' Height: '+height);
});
Check out the Fiddle

CSS to keep background video centred

I've got a background video playing on a web page, and this CSS;
#video_background {
position: fixed;
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
top: 0px;
left: 0px;
z-index: -1000;
overflow: hidden;
}
..is keeping it centered, like I want it to, but it's keeping all of the edges within the browser window, rather than always being full-bleed. I'm trying to replicate what this site is doing;
http://marisapassos.com/#home
This site appears to have two sets of rules, one on a div that contains the video, and one on the video itself. Could someone explain to me why that works and what I'm doing doesn't? Is there also js working to keep the video on the linked site centered?
Yes, look at the video_background.js in the source of the website you linked to, specifically at the $(window).resize function:
$(window).resize(function() {
var windowWidth = $(window).width();
var windowHeight = $(window).height();
var width;
var height;
//size
width = windowWidth;
height = width*formH/formW;
if(height<windowHeight){
height = windowHeight;
width = formW*height/formH;
}
$div_holder.css("width", width);
$div_holder.css("height", height);
$div_holder.css("left", windowWidth/2-width/2);
$div_holder.css("top", windowHeight/2-height/2);
});
Left and top are defined in terms of both the windowWidth and (video) width which keeps the video centered.

Categories