Wie kann ich das HTML5- <canvas>
Element automatisch an die Seite anpassen?
Zum Beispiel kann ich eine <div>
Skalierung erhalten, indem ich die Eigenschaften height
und width
auf 100% setze, aber eine <canvas>
wird nicht skaliert, oder?
Wie kann ich das HTML5- <canvas>
Element automatisch an die Seite anpassen?
Zum Beispiel kann ich eine <div>
Skalierung erhalten, indem ich die Eigenschaften height
und width
auf 100% setze, aber eine <canvas>
wird nicht skaliert, oder?
Antworten:
Ich glaube, ich habe eine elegante Lösung dafür gefunden:
JavaScript
/* important! for alignment, you should make things
* relative to the canvas' current width/height.
*/
function draw() {
var ctx = (a canvas context);
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
//...drawing code...
}
CSS
html, body {
width: 100%;
height: 100%;
margin: 0;
}
Hat bisher keine großen negativen Auswirkungen auf die Leistung für mich gehabt.
body, html { margin: 0px;}
Die folgende Lösung hat bei mir am besten funktioniert. Da ich relativ neu im Codieren bin, möchte ich eine visuelle Bestätigung haben, dass etwas so funktioniert, wie ich es erwartet habe. Ich habe es auf der folgenden Website gefunden: http://htmlcheats.com/html/resize-the-html5-canvas-dyamically/
Hier ist der Code:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Resize HTML5 canvas dynamically | www.htmlcheats.com</title>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0px;
border: 0;
overflow: hidden; /* Disable scrollbars */
display: block; /* No floating content on sides */
}
</style>
</head>
<body>
<canvas id='c' style='position:absolute; left:0px; top:0px;'>
</canvas>
<script>
(function() {
var
// Obtain a reference to the canvas element using its id.
htmlCanvas = document.getElementById('c'),
// Obtain a graphics context on the canvas element for drawing.
context = htmlCanvas.getContext('2d');
// Start listening to resize events and draw canvas.
initialize();
function initialize() {
// Register an event listener to call the resizeCanvas() function
// each time the window is resized.
window.addEventListener('resize', resizeCanvas, false);
// Draw canvas border for the first time.
resizeCanvas();
}
// Display custom canvas. In this case it's a blue, 5 pixel
// border that resizes along with the browser window.
function redraw() {
context.strokeStyle = 'blue';
context.lineWidth = '5';
context.strokeRect(0, 0, window.innerWidth, window.innerHeight);
}
// Runs each time the DOM window resize event fires.
// Resets the canvas dimensions to match window,
// then draws the new borders accordingly.
function resizeCanvas() {
htmlCanvas.width = window.innerWidth;
htmlCanvas.height = window.innerHeight;
redraw();
}
})();
</script>
</body>
</html>
Der blaue Rand zeigt Ihnen den Rand der Leinwand zum Ändern der Größe und befindet sich immer am Rand des Fensters, sichtbar auf allen 4 Seiten, was bei einigen der anderen oben genannten Antworten NICHT der Fall war. Ich hoffe es hilft.
overflow: hidden
und display: block
ist das, was mir gefehlt hat, damit das richtig funktioniert.
Grundsätzlich müssen Sie das Ereignis onresize an Ihren Körper binden. Sobald Sie das Ereignis erfasst haben, müssen Sie nur die Größe der Zeichenfläche mit window.innerWidth und window.innerHeight ändern.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Canvas Resize</title>
<script type="text/javascript">
function resize_canvas(){
canvas = document.getElementById("canvas");
if (canvas.width < window.innerWidth)
{
canvas.width = window.innerWidth;
}
if (canvas.height < window.innerHeight)
{
canvas.height = window.innerHeight;
}
}
</script>
</head>
<body onresize="resize_canvas()">
<canvas id="canvas">Your browser doesn't support canvas</canvas>
</body>
</html>
Wenn Sie die Breite und Höhe des Canvas-Koordinatenraums basierend auf den Abmessungen des Browser-Clients festlegen, müssen Sie die Größe ändern und neu zeichnen, wenn die Größe des Browsers geändert wird.
Eine weniger komplizierte Lösung besteht darin, die zeichnbaren Dimensionen in Javascript-Variablen beizubehalten, die Canvas-Dimensionen jedoch basierend auf den Dimensionen screen.width, screen.height festzulegen. Verwenden Sie CSS, um Folgendes anzupassen:
#containingDiv {
overflow: hidden;
}
#myCanvas {
position: absolute;
top: 0px;
left: 0px;
}
Das Browserfenster wird im Allgemeinen nie größer als der Bildschirm selbst sein (außer wenn die Bildschirmauflösung falsch angegeben wird, wie dies bei nicht übereinstimmenden Doppelmonitoren der Fall sein könnte), sodass der Hintergrund nicht angezeigt wird und die Pixelproportionen nicht variieren. Die Leinwandpixel sind direkt proportional zur Bildschirmauflösung, es sei denn, Sie verwenden CSS zum Skalieren der Leinwand.
Ein reiner CSS- Ansatz, der zur obigen Lösung von @jerseyboy beiträgt.
Funktioniert in Firefox (getestet in Version 29), Chrome (getestet in Version 34) und Internet Explorer (getestet in Version 11).
<!DOCTYPE html>
<html>
<head>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
canvas {
background-color: #ccc;
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.fillRect(25,25,100,100);
ctx.clearRect(45,45,60,60);
ctx.strokeRect(50,50,50,50);
}
</script>
</body>
</html>
Link zum Beispiel: http://temporaer.net/open/so/140502_canvas-fit-to-window.html
Aber seien Sie vorsichtig, wie @jerseyboy in seinem Kommentar feststellt:
Das Neuskalieren der Zeichenfläche mit CSS ist problematisch. Zumindest in Chrome und Safari entsprechen die Maus- / Touch-Ereignispositionen nicht 1: 1 den Canvas-Pixelpositionen, und Sie müssen die Koordinatensysteme transformieren.
function resize() {
var canvas = document.getElementById('game');
var canvasRatio = canvas.height / canvas.width;
var windowRatio = window.innerHeight / window.innerWidth;
var width;
var height;
if (windowRatio < canvasRatio) {
height = window.innerHeight;
width = height / canvasRatio;
} else {
width = window.innerWidth;
height = width * canvasRatio;
}
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
};
window.addEventListener('resize', resize, false);
Wenn Sie nicht möchten, dass die Leinwand Ihre Bilddaten automatisch hochskaliert (das ist die Antwort von James Black, aber sie sieht nicht hübsch aus), müssen Sie die Größe selbst ändern und das Bild neu zeichnen. Leinwand zentrieren
Wenn Ihr Div die Webseite vollständig ausgefüllt hat, können Sie dieses Div ausfüllen und so eine Leinwand erstellen, die das Div ausfüllt.
Sie finden dies möglicherweise interessant, da Sie möglicherweise ein CSS verwenden müssen, um den Prozentsatz zu verwenden. Dies hängt jedoch davon ab, welchen Browser Sie verwenden und inwieweit er mit der Spezifikation übereinstimmt: http://www.whatwg.org/ specs / web-apps / current-work / mehrseitig / the-canvas-element.html # the-canvas-element
Die intrinsischen Abmessungen des Canvas-Elements entsprechen der Größe des Koordinatenraums, wobei die Zahlen in CSS-Pixeln interpretiert werden. Das Element kann jedoch durch ein Stylesheet beliebig dimensioniert werden. Während des Renderns wird das Bild auf diese Layoutgröße skaliert.
Möglicherweise müssen Sie die Offsetbreite und -höhe des Div oder die Fensterhöhe / -breite abrufen und als Pixelwert festlegen.
CSS
body { margin: 0; }
canvas { display: block; }
JavaScript
window.addEventListener("load", function()
{
var canvas = document.createElement('canvas'); document.body.appendChild(canvas);
var context = canvas.getContext('2d');
function draw()
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.moveTo(0, 0); context.lineTo(canvas.width, canvas.height);
context.moveTo(canvas.width, 0); context.lineTo(0, canvas.height);
context.stroke();
}
function resize()
{
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
draw();
}
window.addEventListener("resize", resize);
resize();
});
Wenn Sie daran interessiert sind, Seitenverhältnisse beizubehalten und dies in reinem CSS (angesichts des Seitenverhältnisses) zu tun, können Sie Folgendes tun. Der Schlüssel ist der padding-bottom
auf dem ::content
Element, der die Größe des container
Elements angibt. Die Größe ist relativ zur Breite des übergeordneten Elements festgelegt, die 100%
standardmäßig verwendet wird. Das hier angegebene Verhältnis muss mit dem Verhältnis der Größen auf dem canvas
Element übereinstimmen .
// Javascript
var canvas = document.querySelector('canvas'),
context = canvas.getContext('2d');
context.fillStyle = '#ff0000';
context.fillRect(500, 200, 200, 200);
context.fillStyle = '#000000';
context.font = '30px serif';
context.fillText('This is some text that should not be distorted, just scaled', 10, 40);
/*CSS*/
.container {
position: relative;
background-color: green;
}
.container::after {
content: ' ';
display: block;
padding: 0 0 50%;
}
.wrapper {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
canvas {
width: 100%;
height: 100%;
}
<!-- HTML -->
<div class=container>
<div class=wrapper>
<canvas width=1200 height=600></canvas>
</div>
</div>
Mit jQuery können Sie die Größe des Fensters verfolgen und die Breite Ihrer Zeichenfläche auch mit jQuery ändern.
So ähnlich
$( window ).resize(function() {
$("#myCanvas").width($( window ).width())
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;">
(function() {
// get viewport size
getViewportSize = function() {
return {
height: window.innerHeight,
width: window.innerWidth
};
};
// update canvas size
updateSizes = function() {
var viewportSize = getViewportSize();
$('#myCanvas').width(viewportSize.width).height(viewportSize.height);
$('#myCanvas').attr('width', viewportSize.width).attr('height', viewportSize.height);
};
// run on load
updateSizes();
// handle window resizing
$(window).on('resize', function() {
updateSizes();
});
}());
Ich denke, genau das sollten wir tun: http://www.html5rocks.com/en/tutorials/casestudies/gopherwoord-studios-resizing-html5-games/
function resizeGame() {
var gameArea = document.getElementById('gameArea');
var widthToHeight = 4 / 3;
var newWidth = window.innerWidth;
var newHeight = window.innerHeight;
var newWidthToHeight = newWidth / newHeight;
if (newWidthToHeight > widthToHeight) {
newWidth = newHeight * widthToHeight;
gameArea.style.height = newHeight + 'px';
gameArea.style.width = newWidth + 'px';
} else {
newHeight = newWidth / widthToHeight;
gameArea.style.width = newWidth + 'px';
gameArea.style.height = newHeight + 'px';
}
gameArea.style.marginTop = (-newHeight / 2) + 'px';
gameArea.style.marginLeft = (-newWidth / 2) + 'px';
var gameCanvas = document.getElementById('gameCanvas');
gameCanvas.width = newWidth;
gameCanvas.height = newHeight;
}
window.addEventListener('resize', resizeGame, false);
window.addEventListener('orientationchange', resizeGame, false);
Ich verwende skizze.js. Nachdem ich den Befehl init für die Zeichenfläche ausgeführt habe, ändere ich die Breite und Höhe mit jquery. Die Bemaßungen basieren auf dem übergeordneten Element.
$ ('# DrawCanvas'). Sketch (). Attr ('height', $ ('# DrawCanvas'). Parent (). Height ()). Attr ('width', $ ('# DrawCanvas'). Parent ().Breite());