HTML5 отзывчивый холст: изменение размера холста на холсте браузера исчезает

Я хочу сделать отзывчивый холст, используя размер в процентах, и как только пользователь изменит размер окна, холст отрегулирует относительно. Я могу масштабировать холст, используя нижеприведенный код, но единственная проблема заключается в том, что я масштабирую размер окна, который вытаскивает рисунок мыши.

<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>

Спасибо.

Ответ 1

Работа с содержимым при изменении размера холста

Если вы изменяете размер холста, рисованное содержимое всегда стирается. Это то, как ведет себя холст.

Вы можете либо перерисовать содержимое после изменения размера, либо сохранить содержимое как данные изображения и восстановить после изменения размера (см. canvas.toDataURL).

Вот код и скрипт: 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>

Ответ 2

У меня также была та же проблема, с которой вы сталкиваетесь в mu-приложении, и после прочтения этого я пришел к такому выводу, что поведение элемента canvas таково, что оно очищается после повторной калибровки, единственное исправление для этого состоит в том, чтобы добавить слушателя к событию переразмерного окна и перерисовать холст при запуске события.

$(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);
}

Надеюсь, что это поможет.

Источник

Ответ 3

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

приведенный выше код эквивалентен clearRect, который используется для очистки холста. Так что вы не можете отрегулировать ширину и высоту, если хотите сохранить то, что было нарисовано ранее. в качестве решения вы можете создать новый холст с требуемой шириной и нарисовать содержимое предыдущего холста с помощью drawImage(c) c - это объект canvas. Затем вы должны удалить холст

Ответ 4

Спасибо. это было действительно полезно. ниже - код, который я пытался сделать.  

#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>

Ответ 5

Я создал плагин jQuery, который обрабатывает размер холста HTML5. Он был создан для преодоления разрыва между мобильными и настольными пользователями. Он по-прежнему является WIP, но он расширяем и содержит некоторые основные функции рисования.

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

Ответ 6

Я использую этот метод:

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);
}

Ответ 7

У меня была та же проблема. Мое решение использует свойство свойства 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 - коэффициент, чтобы сделать отступы холста от родительских границ. Вы можете сделать его равным нулю.

Я надеюсь, что это поможет кому-то: -)