jQuery HTML5 响应式画布:调整浏览器画布的大小绘制消失

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15878377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 15:57:37  来源:igfitidea点击:

HTML5 responsive canvas: resizing the browser canvas draw disappear

javascriptjqueryhtmlcanvas

提问by iawara

I want to make a responsive canvas using size in percentage and once user will resize the window the canvas adjust relatively. I am able to scale the canvas by using below code but the only problem is as i scale the window size the mouse drawing disappear.

我想使用百分比大小制作一个响应式画布,一旦用户调整窗口大小,画布就会相对调整。我可以使用下面的代码缩放画布,但唯一的问题是当我缩放窗口大小时,鼠标绘图消失了。

<style>
body{margin:0px;padding:0px;background:#a9a9a9;}
#main{
display:block;
width:80%;
padding:50px 10%;
height:300px;
} 
canvas{display:block;background:#fff;}
</style>
</head>
<body>
<div id="main" role="main">
<canvas id="paint" width="100" height="100">
< !-- Provide fallback -->
</canvas>
</div> 

<script>

var c = document.getElementById('paint');
var ctx = c.getContext('2d');
var x = null;
var y;

c.onmousedown = function(e){
x = e.pageX - c.offsetLeft;
y = e.pageY - c.offsetTop;
ctx.beginPath();
ctx.moveTo(x,y);

}

c.onmouseup = function(e){
x=null;

}


c.onmousemove = function(e){
if(x==null) return;
x = e.pageX - c.offsetLeft;
y = e.pageY - c.offsetTop; 
ctx.lineTo(x,y);
ctx.stroke();

}

$(document).ready( function(){
//Get the canvas &
var c = $('#paint');

var container = $(c).parent();

//Run function when browser resizes
$(window).resize( respondCanvas );

function respondCanvas(){ 
    c.attr('width', $(container).width() ); //max width
    c.attr('height', $(container).height() ); //max height

    //Call a function to redraw other content (texts, images etc)
}

//Initial call 
respondCanvas();

}); 


</script>

Thanks.

谢谢。

回答by markE

Dealing with contents when resizing a canvas

调整画布大小时处理内容

If you resize the canvas, the drawn content is always erased. That's how canvas behaves.

如果您调整画布大小,绘制的内容总是会被擦除。这就是画布的行为方式。

You can either redraw the content after resizing or you can save the content as image data and restore after resizing (see canvas.toDataURL).

您可以在调整大小后重绘内容,也可以将内容保存为图像数据并在调整大小后恢复(请参阅 canvas.toDataURL)。

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/V6SVz/

这是代码和小提琴:http: //jsfiddle.net/m1erickson/V6SVz/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:10px; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    // draw some content
    ctx.lineWidth=3;
    ctx.fillStyle="blue";
    ctx.strokeStyle="red";
    ctx.rect(50,50,100,50);
    ctx.fill();
    ctx.stroke();
    ctx.font="14px Verdana";
    ctx.fillStyle="white";
    ctx.fillText("Scale Me",65,75);

    function saveResizeAndRedisplay(scaleFactor){

        // save the canvas content as imageURL
        var data=canvas.toDataURL();

        // resize the canvas
        canvas.width*=scaleFactor;
        canvas.height*=scaleFactor;

        // scale and redraw the canvas content
        var img=new Image();
        img.onload=function(){
            ctx.drawImage(img,0,0,img.width,img.height,0,0,canvas.width,canvas.height);
        }
        img.src=data;

    }

    $("#resizer").click(function(){ saveResizeAndRedisplay(1.5); });

}); // end $(function(){});
</script>

</head>

<body>
    <button id="resizer">Click to resize the canvas</button><br/>
    <canvas id="canvas" width=200 height=150></canvas>
</body>
</html>

回答by Arun Killu

c.attr('width', $(container).width() ); //max width
c.attr('height', $(container).height() ); //max height

the above code is equivalent to clearRectwhich is used to clear the canvas .so you cannot adjust the width and height if you want to retain what was drawn previously. as a solution you can create a new canvas with required width and draw the content of previous canvas using drawImage(c)c is the canvas object .then you have to delete the canvas

上面的代码等价于clearRectwhich 用于清除画布。因此如果您想保留之前绘制的内容,则无法调整宽度和高度。作为解决方案,您可以创建一个具有所需宽度的新画布并使用drawImage(c)c绘制先前画布的内容是画布对象。然后您必须删除画布

回答by Rahul Jain

I also had the same issue that your are facing in mu application, and after reading about it i came to this conclusion that the behavior of the canvas element is such that it clears itself after re-sizing, the only fix for this is to add a listener for the window re-size event and redraw the canvas when the event if fired.

我也遇到了你在 mu 应用程序中面临的同样问题,在阅读了它之后,我得出这样的结论,即画布元素的行为在重新调整大小后会自行清除,唯一的解决方法是添加窗口大小调整事件的侦听器,并在触发事件时重绘画布。

$(window).resize(function(e) {
// function to redraw on the canvas
});



$(document).ready(function(e){
    var c = $('#example'); // getting the canvas element
    var ct = c.get(0).getContext('2d');
    var container = $(c).parent();
    $(window).resize( respondCanvas ); //handling the canvas resize
    function respondCanvas(){ 
        // makign the canvas fill its container
        c.attr('width', $(container).width() ); //max width
        c.attr('height', ($(container).height() -20 )); //max height
    }
    respondCanvas();
    make_image('images/india.png',1,1);
}

Hope it helps.

希望能帮助到你。

Source

来源

回答by iawara

Thanks. it was really helpful. below is the code what i was trying to do.

谢谢。这真的很有帮助。下面是我试图做的代码。

#main{
display:block;
width:80%;
height:300px;
background:#e0e0e0;
} 
canvas{display:block;background:#fff;border:1px solid red;}

</style>

<script>

$(function(){

var container=document.getElementById("main");
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");

// draw some content
//alert(canvas.width);

var w=$(container).width();
var h=$(container).height();



$(window).resize( saveResizeAndRedisplay );
function saveResizeAndRedisplay(){

    // save the canvas content as imageURL
    var data=canvas.toDataURL();

    // resize the canvas
    canvas.width = $(container).width();
    canvas.height = $(container).height();
    //alert($(container).width());

    // scale and redraw the canvas content
    var img=new Image();
    img.onload=function(){
        ctx.drawImage(img,0,0,img.width,img.height);
    }
    img.src=data;

}

saveResizeAndRedisplay();

}); 
</script>

</head>

<body>

<div id="main" role="main">
 <canvas id="canvas" width=200 height=150></canvas>
</div>

<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var x = null;
var y;

canvas.onmousedown = function(e){
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
ctx.beginPath();
ctx.moveTo(x,y);
}

canvas.onmouseup = function(e){
x=null;
}


canvas.onmousemove = function(e){
if(x==null) return;
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop; 
ctx.lineTo(x,y);
ctx.stroke();
}
</script>

回答by tsanders

I've created a jQuery plugin that handles HTML5 canvas resizing. It was built to bridge the gap between mobile and desktop users. It is still a WIP but it is extensible, and has some basic drawing functions built in.

我创建了一个处理 HTML5 画布大小调整的 jQuery 插件。它旨在弥合移动和桌面用户之间的差距。它仍然是一个 WIP,但它是可扩展的,并且内置了一些基本的绘图功能。

http://trsanders.github.io/responsive-sketchpad/

http://trsanders.github.io/responsive-sketchpad/

回答by karaxuna

I use this method:

我用这个方法:

var context = document.getElementById('paint').getContext('2d');
var canvas = context.canvas;

function responsive(width){
    var p = width / canvas.width;
    canvas.width *= p;
    canvas.height *= p;

    var scaleFactor = context.scaleFactor || 1;
    context.scale(p * scaleFactor, p * scaleFactor);
    context.scaleFactor = p * scaleFactor;
}

var mq = window.matchMedia("(min-width: 735px)");
mq.addListener(applyChanges);
applyChanges();

function applyChanges(){
    if(!mq)
        responsive(350);
    else
        responsive(735);
}

回答by Paul Basenko

I had the same problem. My solution is using CSS3's property zoom to the parent's container of the canvas:

我有同样的问题。我的解决方案是使用 CSS3 的属性缩放到画布的父容器:

<div id="parent_div">
    <div id="constructor_div">
         <canvas width="600" height="900">
    </div>
</div>

<script>
    constructor_zoom();

    $(window).resize(function() {
        constructor_zoom();
    });

    function constructor_zoom()
    {
        var parent_width = $('#parent_div').width();
        var item_width = $('#constructor_div').width();
        var coef = 0.1;

        $('.constructor_image').css('zoom', parent_width/item_width - coef);
    }
</script>

coef - coefficient to make indents of the canvas from the parent's borders. You may make it zero.

coef - 从父边界缩进画布的系数。你可以让它为零。

I hope it helps to somebody :-)

我希望它对某人有所帮助:-)