Ankündigung

Einklappen
Keine Ankündigung bisher.

onResize

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • onResize



    hallo,
    ja, ich schon wieder. Nochmals Danke für die Hinweise. Auch an hellbringer, ich hatte tatsächlich ein falsches Bild von header
    ()

    Nun etwas neues. Es geht um das Canvas Element. Ich hab da meine besagte Anwendung. Um Größenänderungen des Browsers (resize durch user) habe ich meine Styles angepasst (@media screen).
    Nur bei dem Canvas Container geht das so einfach nicht. Das heißt, man kann den schon ändern, aber dadurch ändert sich nicht die Größe des Inhaltes. Und selbst wenn, würde mir das nichts nutzen, weil ich den genauen Faktor der Größenanpassung benötige. Also habe ich den onResize Event benutzt und starte damit ein Javascript. Dieses liest die tatsächliche Größe das Containers aus, in dem sich das Canvas befindet, berechnet auf Grund der Daten und der zu zeigenden Bildgröße einen Faktor und legt eine neue Größe für das Canvas fest. Über Ajax starte ich dann eine Funktion, die mir das Canvas mit Inhalt richtig anpasst. Damit das aber nicht bei jedem Pixel passiert, was viel zu aufwändig wäre, begrenze ich das auf eine Schrittweite von 200px
    PHP-Code:
    if(aktuelle_Größe 200 == 0
    Soweit die Theorie. In der Praxis klappt das nur, wenn ich den Browser gaaaaaanz langsam ändere. Ziehe ich den mit der Maus schnell größer oder kleiner, springt meine Abfrage nicht an. Wie kann ich das so hinbekommen, das ich eine Größenänderung des Browsers so abfange, dass ich aller 200 Pixel Größenänderung einen befahl absenden kann, mit dem ich dann das Script zum vergrößern oder verkleinern starte?

    Bisher habe ich das:

    PHP-Code:

    function changeCanvasSize(sessiontokencm_key){   // werte für die Session, für die Berechnung unwichtig
      
    changeSize getMaxValues();                       // gibt mir die aktuelle Höhe und Breite

     //useSizeWidth, useSizeHeight, useSizeWidthTemp, useSizeHeightTemp    sind als globale Variablen außerhalb der Funktion definiert  

      
    if(changeSize[0] % 10 == || changeSize[1] % 10 == 0){
        if(
    changeSize[0] % 200 == || changeSize[1] % 100 == 0){
         
    useSizeWidth Math.round(changeSize[0]);
         
    useSizeHeight Math.round(changeSize[1]);
                
    //console.log("width ",Math.round(useSizeWidth), " / ", "height ", Math.round(useSizeHeight));

          
    if((useSizeWidthTemp != useSizeWidth && useSizeWidth 800 && useSizeWidth 1400) || (useSizeHeightTemp != useSizeHeight && useSizeHeight 400 && useSizeHeight 800)){
            
    useSizeWidthTemp  useSizeWidth;
            
    useSizeHeightTemp useSizeHeight;

            var 
    url "mein_script.php?actionName=resizeCanvas&resizeWidth=" changeSize[0] + "&resizeHeight=" changeSize[1] + "&cm_key=" cm_key  "&sessionId=" session  "&token=" token;
            
    // mein_script.php berechnet auf Grundlage der verfügbaren Größe und der Größe des anzuzeigenden Bildes im Canvas (aus Datenbank) die neue Größe des Canvas

            
    if(!xmlhttp3){
              if (
    window.XMLHttpRequest){                                     // code for IE7+, Firefox, Chrome, Opera, Safari
                
    xmlhttp3 = new XMLHttpRequest();
                }else{                                                        
    // code for IE6, IE5
                      
    xmlhttp3 = new ActiveXObject("Microsoft.XMLHTTP");
                      }
              }

            
    xmlhttp3.arguments "Error_setNewSize";
            
    xmlhttp3.onload = function(){
                                        if (
    xmlhttp3.readyState == 4) {
                                          
    //alert(url);
                                          
    alert("--> " xmlhttp3.responseText);                                               //wenn ich den Browser langsam ändere, erhalte ich hier richtige Werte.
                                          
    dataAllObj JSON.parse(xmlhttp3.responseText);                                      //wenn ich den Browser schnell ändere, passiert hier gar nichts
                                          
    var dataAllObj3 JSON.parse(xmlhttp3.responseText);
                                          
    //alert(dataAllObj3[3]);
                                          
    var dataAll ajaxResponse(dataAllObj[3]);
                                          
    //alert(dataAll[0][0] + " / " + dataAll[0][1]);
                                          
    var newData = new Array(Math.round(dataAll[0][0]),Math.round(dataAll[0][1]));
                                          
    toolGoToCanvas("startMat""resizeCanvas"JSON.stringify(newData), 0);              //startet Javascript Funktion zur Anpassung des Canvas mit Inhalt
                                          
    }
                                        }
            
    xmlhttp3.onerror xmlhttp3Error;                                                                                  //die Funktion existiert
            
    xmlhttp3.open("POST"urltrue);
            
    xmlhttp3.send(null);
            return 
    false;
            }
          }
        }
      } 
    Es wäre mir auch geholfen, wenn ich die Funktion starten könnte, sobald die Größenänderung stoppt, also der User die Maus wieder loslässt und die Änderung des Browsers damit beendet. Nur fällt mir da leider gar nicht ein, wie ich den Zeitpunkt abfangen soll. onResize gibt mir ja nur den Start der Änderung, aber nicht das Ende.

  • #2
    Ich würde an Deiner Stelle nicht diesen Aufwand betreiben, sondern meinem Canvas größere Abmessungen geben und diesen per css skalieren,,,,

    HTML-Code:
    <!doctype html>
    <html lang="en">
      <meta charset="UTF-8">
      <title>Canvas Resize</title>
      <style>
        #myCanvasContainer{
          width:50%;
          margin-left:auto;
          margin-right:auto;
        }
        canvas {
          background: grey;
          display: block;
          margin: 0 auto;
          width:100%;
        }
      </style>
      <div id="myCanvasContainer">
        <canvas width="1600" height="1200"></canvas>
      </div>
      <script>
        var canvas = document.querySelector('canvas');
        var context = canvas.getContext('2d');
        var centerX = canvas.width / 2;
        var centerY = canvas.height / 2;
        context.beginPath();
        context.arc(centerX, centerY, 500, 0, 2 * Math.PI, false);
        context.fillStyle = 'red';
        context.fill();
        context.lineWidth = 50;
        context.strokeStyle = '#000000';
        context.stroke();
      </script>

    Kommentar


    • #3
      Danke, aber so einfach ist es leider nicht. Wir haben über 10 Canvas Elemente, die alle verschiedene Daten enthalten. Diese wiederum sind in einem "großen Canvas" vereint. dann gibt es ein "Anzeigecanvas", das ist das, was wir skalieren müssen. Aber alle dort darin befindlichen Elemente sind als Objekte und Gruppen ausgeführt. In dem Canvas kann man einzelne Dateien bewegen und diese Bewegungen müssen dann in das "große Canvas" übertragen werden. Pixelgenau inklusive Skalierung. Und genau dort hängt es dann. Wir nutzen auch ein Framework (fabric.js), darin gibt es zwar einen Scale Funktion, aber die hat Fehler. Das haben wir jetzt gemerkt, nach zig tausend Zeilen Quellcode. Das ändern wir jetzt nicht mehr. Deshalb eben die Variante mit dem Javascript, was im Intervall die Größe ändert.
      Ich hab noch eine andere Lösung gefunden. Mit einem Timer. Das hat den Charme, das es erst feuert, wenn der User den Browser wieder in Ruhe lässt. Ist auch noch nicht ganz 100% aber schon nahe dran.
      PHP-Code:
      var changeSize;   var TO;
      function 
      changeCanvasSize(sessiontokencm_key){
        
      clearTimeout(TO);
        
      TO setTimeout(startResize400cm_keysessiontoken);   //Start der eigentlichen Funktion
        

      Kommentar


      • #4
        seit wann kann man in einem oder mehreren css skalierten Canvas nicht pixelgenau arbeiten?

        Kommentar


        • #5
          Was weiß ich. Ich weiß nur, das es nicht passt. Praktisch. Dazu kommt, wie gesagt, das wir fabric Canvas benutzen, und das hat einen Fehler. Der einzige, der uns bisher aufgefallen ist. Und der betrifft Scale. Die Canvas Elemente werden von fabric noch mit einem "Hilfscanvas" versehen. Das hat normalerweise keinen Einfluss. Aber hier eben schon. Die Größenangaben stimmen nicht.

          Kommentar


          • #6
            Also gut, wenn dem so ist. würde ich im timeout die Zeitdifferenz zwischen lastMouseMove und und aktTime messen. Bei einer Differenz > 0,1 Sek neu zeichnen...

            Kommentar


            • #7
              Es wäre mir auch geholfen, wenn ich die Funktion starten könnte, sobald die Größenänderung stoppt, also der User die Maus wieder loslässt und die Änderung des Browsers damit beendet. Nur fällt mir da leider gar nicht ein, wie ich den Zeitpunkt abfangen soll. onResize gibt mir ja nur den Start der Änderung, aber nicht das Ende.
              debounce suchst Du wohl, möglicherweise auch Throttel.
              Zu debounce mit underscore bei resize von walsh:
              https://davidwalsh.name/javascript-debounce-function

              Kommentar


              • #8
                Wenn Du also unbedingt neu zeichnen willst, würde ich es wie folgt erledigen.

                1.) Beim "resizen" würde ich die Funktionalität der Skalierung durch CSS nutzen. Das ist vollkommen ausreichend.

                2.) Nach dem Beenden von "resize" den ganzen Kram neu "zeichnen"

                Ein kurzes Beispiel zur Vorgehensweise:

                HTML-Code:
                <!doctype html>
                <html lang="de">
                <head>
                  <meta charset="UTF-8">
                  <title>On Resize Finished</title>
                  <p id=test>
                  <script>
                    t=onresize=e=>clearTimeout(t)&(t=setTimeout('test.innerHTML+="finished"',200))
                  </script>
                Das Thema hatten wir hier schon unter https://www.php.de/forum/webentwickl...rowserfensters

                Kommentar


                • #9
                  Danke für die vielen Hinweise. Scalierung per CSS wäre toll, wenn das in fabric.js richtig funktionieren würde. Tut es aber leider nicht. Die erstellen für Objekte und Gruppen Hilfscanvas Elemente. Wozu genau weiß ich nicht und will ich auch nicht wissen. Wenn ich das rausfinden will, brauche ich ja Monate dazu. Jedenfalls werden diese Hilfscanvas nicht richtig scaliert. Und damit passen dann auch die weiteren Abfragen nicht mehr. Das ist schon sehr umfangreich, was ich da habe.

                  Kommentar

                  Lädt...
                  X