web-dev-qa-db-fra.com

Canevas réactif HTML5: le redimensionnement du dessin de canevas du navigateur disparaît

Je veux créer un canevas réactif en utilisant la taille en pourcentage et une fois que l'utilisateur aura redimensionné la fenêtre, le canevas sera ajusté de manière relativement précise. le dessin de la souris disparaît.

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

Merci.

9
iawara

Traitement du contenu lors du redimensionnement d'une toile

Si vous redimensionnez la toile, le contenu dessiné est toujours effacé. C'est comme ça que la toile se comporte. 

Vous pouvez redessiner le contenu après le redimensionnement ou l'enregistrer en tant que données d'image et le restaurer après le redimensionnement (voir canvas.toDataURL). 

Voici le code et un violon: 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>
11
markE
c.attr('width', $(container).width() ); //max width
c.attr('height', $(container).height() ); //max height

le code ci-dessus est équivalent à clearRect qui est utilisé pour effacer le canevas. Aussi, vous ne pouvez pas ajuster la largeur et la hauteur si vous voulez conserver ce qui a été dessiné précédemment. vous pouvez créer un nouveau canevas avec la largeur requise. et dessinez le contenu de la toile précédente en utilisant drawImage(c) c est l’objet de toile .puis vous devez supprimer la toile

3
Arun Killu

J'ai également eu le même problème que celui auquel vous êtes confronté dans l'application mu, et après avoir pris connaissance de cela, j'en suis venu à la conclusion que le comportement de l'élément canvas est tel qu'il disparaît après le redimensionnement. La seule solution à ce problème est d'ajouter un écouteur pour l'événement de redimensionnement de la fenêtre et redessine la zone de dessin lorsque l'événement est déclenché.

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

J'espère que ça aide.

La source

3
Rahul Jain

Merci. c'était vraiment utile. ci-dessous est le code de ce que j’essayais de faire.

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

J'ai créé un plugin jQuery qui gère le redimensionnement de la toile HTML5. Il a été conçu pour combler le fossé entre les utilisateurs mobiles et les utilisateurs de bureau. Il s’agit toujours d’un WIP, mais il est extensible et intègre certaines fonctions de dessin de base.

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

2
tsanders

J'utilise cette méthode:

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

J'ai eu le même problème. Ma solution utilise la propriété CSS3 pour effectuer un zoom sur le conteneur de la zone de dessin du parent:

<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 pour faire des retraits de la toile à partir des frontières du parent. Vous pouvez le faire zéro.

J'espère que ça aide quelqu'un :-)

0
Paul Basenko