Reputation: 3058
I am creating specific size image of 1200W x 300H and when its done I pass the image back to my server. I have all that working.
However, when the image is created, that 1200x300 size blows off the page for many users - especially on a mobile device. Is there any method I can use that can create the image at the specific 1200x300 but then visually display the image on a smaller scale to fit the screen?
Currently the best I am able to do is use a DIV with overflow:hidden
to keep the DIV correctly sized on the page, but that doesn't scale the actual image down. In fact the image is mostly off centered only seeing the left part of the image on the screen.
<div style="overflow:hidden;" >
<canvas id="canvas" width="1200" height="300">
Your browser does not support Canvas.
</canvas>
</div>
If I shrink the canvas to fit the page, then the created image is the smaller size and not the size I need passed back to the server.
Is it possible to do this?
============= UPDATE ================
<div style="overflow:hidden;" >
<canvas id="displayCanvas" width="1200" height="300">
Your browser does not support Canvas.
</canvas>
<canvas id="realCanvas" width="1200" height="300">
Your browser does not support Canvas.
</canvas>
</div>
#CSS
#realCanvas {
width:100vw;
height: 25vw ;
}
#JS
function buildBanner () {
Debugger.log("Drawing Canvas");
if(!canvasSupport()) {
return;
}
var wCanvas = 1200 ;
var hCanvas = 300 ;
var wImg = 400 ;
var hImg = 100 ;
var hRatio = wCanvas / wImg ;
var vRatio = hCanvas / hImg ;
var ratio = Math.min ( hRatio, vRatio );
var centerShift_x = ( wCanvas - wImg*ratio ) / 2;
var centerShift_y = ( hCanvas - hImg*ratio ) / 2;
var displayCanvas = document.getElementById('displayCanvas') ;
var displayContext = displayCanvas.getContext('2d');
var realCanvas = document.getElementById('realCanvas');
var realContext = realCanvas.getContext('2d');
var text1 = document.getElementById('textType1') ;
var text2 = document.getElementById('textType2') ;
if (text1.checked) {
var bannerText = document.getElementById('cVendor').value ;
console.log("Text1: "+ bannerText) ;
} else if (text2.checked) {
var bannerText = document.getElementById('cVendorName').value ;
console.log("Text2: "+ bannerText) ;
}
var textStrokeColor = "#000000";
var textBaseline = "middle";
var textAlign = "center";
// This is the event handler for listening for a key up event in the text box form
// It will call the textBoxChanged function to update the text in the canvas
var fontSize = document.getElementById("fontSize").value;
var fontFaceSelect = document.getElementById("fontFace");
var fontFace = fontFaceSelect.options[fontFaceSelect.selectedIndex].value ;
var fontWeightSelect = document.getElementById("fontWeight");
var fontWeight = fontWeightSelect.options[fontWeightSelect.selectedIndex].value ;
var fontStyleSelect = document.getElementById("fontStyle");
var fontStyle = fontStyleSelect.options[fontStyleSelect.selectedIndex].value ;
var fillTypeSelect = document.getElementById("fillType");
var fillType = fillTypeSelect.options[fillTypeSelect.selectedIndex].value ;
var strokeTypeSelect = document.getElementById("strokeType");
var strokeType = strokeTypeSelect.options[strokeTypeSelect.selectedIndex].value ;
var textFillColor = document.getElementById("textFillColor").value ;
var bgFillColor = document.getElementById("bgFillColor").value ;
var imageData = document.getElementById("createImageData");
realContext = drawScreen(realContext,wCanvas,hCanvas,4);
displayContext = drawScreen(displayContext,wImg,hImg,1) ;
var imageDataDisplay = document.getElementById("imageDataDisplay");
imageDataDisplay.value = realCanvas.toDataURL();
function drawScreen(thisContext,x,y,xSize) {
thisContext.clearRect(0, 0, x, y);
var metrics = thisContext.measureText(bannerText);
var textWidth = metrics.width;
var xPosition = x / 2
var yPosition = y / 2;
// Draws the Text Box
thisContext.globalAlpha = 1.0;
thisContext.fillStyle = bgFillColor ;
thisContext.fillRect(0,0,x,y);
// Draws the actual text
var xFontSize = fontSize * xSize ;
thisContext.font = fontWeight + " " + fontStyle + " " + xFontSize + "px " + fontFace;
thisContext.textBaseline = textBaseline;
thisContext.textAlign = textAlign;
var tempColor;
switch(fillType) {
case "colorFill":
Debugger.log("Color Fill");
tempColor = textFillColor;
break;
case "linearGradient":
Debugger.log("Linear Gradient");
var linGradient = thisContext.createLinearGradient(xPosition-textWidth/2, yPosition, xPosition+textWidth/2, yPosition);
linGradient.addColorStop(0, textFillColor);
tempColor = linGradient;
break;
case "radialGradient":
Debugger.log("Radial Gradient");
var radGradient = thisContext.createRadialGradient(xPosition, yPosition, 1, xPosition, yPosition, textWidth/2);
radGradient.addColorStop(0, textFillColor);
tempColor = radGradient;
break;
}
switch(strokeType) {
case "fill":
thisContext.fillStyle = tempColor;
thisContext.fillText(bannerText, xPosition, yPosition);
break;
case "stroke":
thisContext.strokeStyle = textStrokeColor;
thisContext.strokeText(bannerText, xPosition, yPosition);
break;
case "both":
thisContext.fillStyle = tempColor;
thisContext.fillText(bannerText, xPosition, yPosition);
thisContext.strokeStyle = textStrokeColor;
thisContext.strokeText(bannerText, xPosition, yPosition);
break;
}
return thisContext ;
}
}
Upvotes: 0
Views: 451
Reputation: 12891
This could be done by listening to a resize
event and manipulating the CSS width & height properties accordingly but there's an easier way if your <canvas>
element is always the same size.
To understand what's going on you need to know that the width & height set via the canvas' elements own attributes is the 'real' resolution of the canvas. What size is actually rendered on screen can be controlled by the CSS width & height properties.
What we want to do is scale the canvas to fill the browser's available vertical viewport and scale it's height while maintaining the canvas' original aspect ratio.
First we need to calculate it's aspect ratio: 300 / 1200 = 0.25
which means it's height is 1/4 of it's width. In plain english we want to make the canvas width 100% the viewport's width and it's height 25% the viewport's width.
Luckily this transfers directly to the CSS vw
unit. e.g. 100vw==100% viewport width
.
So all you have to do is setting the canvas CSS width to 100vw
and it's height to 25vw
.
Here's an example:
let image = new Image();
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
image.crossOrigin = 'anonymous';
image.onload = (e) => {
context.drawImage(e.target, 0, 0, canvas.width, canvas.height);
}
image.src = 'https://picsum.photos/id/10/1200/300';
#canvas {
background-color: black;
width: 100vw;
height: 25vw;
}
<div style="overflow:hidden;">
<canvas id="canvas" width="1200" height="300">
Your browser does not support Canvas.
</canvas>
</div>
Upvotes: 2