zoro17: Elementeigenschaften dynamisch ins DOM

Hallo zusammen,

ich habe folgende Aufgabe:
Ich muss auf einem canvas ein Polygon dynamisch auf Knopfdruck zeichnen,
das sich per Drag and Drop verschieben und z.B. bei Doppelklick wieder
entfernen läßt.

Was ich bisher geschaft habe:
Polygon (div Container) per Knopfdruck auf canvas zeichnen.
Statisches Polygon per Drag and Drop verschieben.

Was mir fehlt:
Einbinden des neu gezeichneten Polygons ins DOM, um dem Polygon per class(?)
Zuordnung Drag and Drop beizubringen oder per Doppelklick verschwinden zu
lassen.
Wie ist das Polygon als Dom Node zu behandeln? Geht das?
Spielt es eine Rolle, dass das Polygon im canvas eingebunden ist?

Vielleicht kann mir jemand helfen.
Danke und Gruß

  1. Hallo,

    naja, hast du jemals mal irgendwas im DOM modifiziert? Hast Du Beispielcode? Einen kleinen Test gebaut?

    Gruß

    jobo

    1. Hallo,

      naja, hast du jemals mal irgendwas im DOM modifiziert? Hast Du Beispielcode? Einen kleinen Test gebaut?

      Gruß

      jobo

      Habe Textnodes dazugebaut, einen Wert gegeben bzw. Erscheinungsbild geändert. Da betraff immer nur Strings und Co.
      Habe noch kein grafisches Element eingebaut, verändert oder ihm
      neue Funktionalität gegeben.
      Was ist denn ein Polygon vom Typ her? Dann käme ich schon weiter...

      Danke und Gruß

      1. Hallo,

        Hallo,

        naja, hast du jemals mal irgendwas im DOM modifiziert? Hast Du Beispielcode? Einen kleinen Test gebaut?

        Gruß

        jobo

        Habe Textnodes dazugebaut, einen Wert gegeben bzw. Erscheinungsbild geändert. Da betraff immer nur Strings und Co.
        Habe noch kein grafisches Element eingebaut, verändert oder ihm
        neue Funktionalität gegeben.
        Was ist denn ein Polygon vom Typ her? Dann käme ich schon weiter...

        Ich dachte du willst dem umgebenden Div eine Styleeigenschaft verpassen. Alle Elemente sind doch eben Elemente, ich verstehe die Frage nicht ganz. U.u. musst du dem Canvas-Element einen Style verpassen. Wenn das geht. Textnodes kannst du ja auch keinen Stil direkt anhängen, nur dem umgebenden Element.

        Gruß

        jobo

        1. Beim statischen Test habe ich das webkitdragdrop Tool (Javascript)
          verwendet, da kann man mittels <div> Rechtecke definieren, welche eine
          Drag-Funktion bzw. ein Drop-Funktion haben.
          Über Klassenzuordnung wird diese Eigenschaft dem Rechteck mitgegeben.
          Alle Rechtecke stecken in einem canvas.
          Diese Rechtecke kann man über den ganzen Bildschirm schieben.
          Der Nachteil dieser Methode ist, dass ich beim Aufbau der Seite schon wissen muß, wieviele Rechtecke ich brauche.

          Beim dynamischen Test male ich Polygone mittels Javascript in den canvas.
          Bsp.:
          function poly(){
          var poly=[ 5,5, 100,50, 50,100, 10,90 ];
          var canvas=document.getElementById("testcanvas1")
          var ctx = canvas.getContext('2d');
          ctx.fillStyle = '#f00';

          ctx.beginPath();  
          ctx.moveTo(poly[0], poly[1]);  
          for( item=2 ; item < poly.length-1 ; item+=2 ){ctx.lineTo( poly[item] , poly[item+1] )}  
            
          ctx.closePath();  
          ctx.fill();  
          

          }

          Jetzt stehe vom dem Problem, dass ich dem Polygon zur Laufzeit die Drag&Drop Eigenschaften mitgeben möchte. Da dachte ich an DOM, wie
          z.B. ctx["onclick"] = new Function("alert('!');");
          Aber das müßte ctx im DOM hängen oder?

          Habe ich das richtig verstanden:
          Wenn ich per Javasript etwas in einen Canvas male, wird das DOM
          der Seite nicht beeinflußt? Und selbst wenn ich das wollte ginge das nicht?

          Wie kann ich die Klasse ans Polygon hängen?
          Hänge da etwas in der Luft.

          Danke und Gruß

          1. Habe ich das richtig verstanden:
            Wenn ich per Javasript etwas in einen Canvas male, wird das DOM
            der Seite nicht beeinflußt? Und selbst wenn ich das wollte ginge das nicht?

            Eigentlich muss das so sein, da ich den canvas per Javascript ohne
            DOM-Manipulation verändern kann.

            Gruß

          2. Der Nachteil dieser Methode ist, dass ich beim Aufbau der Seite schon wissen muß, wieviele Rechtecke ich brauche.

            Prinzipiell lässt sich so etwas aber auch mit einer beliebigen Anzahl umsetzen.

            Beim dynamischen Test male ich Polygone mittels Javascript in den canvas.

            Jetzt stehe vom dem Problem, dass ich dem Polygon zur Laufzeit die Drag&Drop Eigenschaften mitgeben möchte. Da dachte ich an DOM, wie
            z.B. ctx["onclick"] = new Function("alert('!');");
            Aber das müßte ctx im DOM hängen oder?

            Der Kontext ist bloß ein Objekt, dass dir die Programmierschnittstelle zum Zeichnen auf der Canvas bietet. Es ist nicht Teil des DOM. Im DOM sind nur HTML-Elemente. Wenn du Klicks auf die Canvas behandeln willst, dann musst du den click-Event beim canvas-Element verarbeiten.

            document.getElementById("testcanvas1").onclick = handler;
            oder
            document.getElementById("testcanvas1").addEventListener('click', handler, false);
            http://molily.de/js/event-handling-grundlagen.html

            Das überwacht sämtliche Klicks auf die Canvas. Damit kannst du natürlich noch keine Klicks auf die einzelnen Polygone behandeln.

            Wenn ich per Javasript etwas in einen Canvas male, wird das DOM
            der Seite nicht beeinflußt?

            Richtig.

            Und selbst wenn ich das wollte ginge das nicht?

            Richtig.

            Wie kann ich die Klasse ans Polygon hängen?

            Kannst du nicht. Das Polygon existiert nicht. Du zeichnest bloß Pixel auf die Leinwand. Canvas ist total low-level.

            Was du auf die Canvas zeichnest, hat mit HTML-Elementen und CSS-Formatierungen nichts zu tun. Das ist ein Universum für sich.

            Wenn das Polygon einen Status haben soll, brauchst du ein JavaScript-Objekt, was den Polygon repräsentiert, was eine Größe und eine Position hat.

            Wie ich im anderen Posting schrieb, ist es möglich, aber aufwändig, Events vom Canvas-Element auf eigene internen Canvas-Zeichenobjekte abzubilden. Man muss eigenes Hit-Testing machen. Die verlinkte Bibliothek tut das beispielsweise. Es gibt noch viele andere dieser Sorte, etwa ProcessingJS oder EaselJS.

            Ich glaube aber auch, dass dir eine SVG-Lösung z.B. mit RaphaelJS bei der Drag-and-Drop-Geschichte schneller weiterhilft. SVG-Elemente liegen einfach im HTML-DOM, sind über CSS formatierbar und bei ihnen passieren direkt Ereignisse.
            Daher fällt das Umrechnen von der Canvas auf die internen Objekte weg, das übernimmt in dem Fall der Browser.

            Mathias

            1. Hallo molily,
              danke für die ausführliche Erklärung!
              Meine Szenario war nicht vollständig beschrieben. Ich habe folgendes vor:

              Es gibt "vorgezeichnete" Polygone auf dem Bildschirm. Weitere Polygone
              sollen per Drag&Drop andocken (evtl. mit Regelwerk, ob andocken möglich ist).
              Einige Objekte sollen sogar auf das vorgezeichnete Objekt draufgezogen werden,
              so dass sich dieses umfärbt.
              Da man nicht weiß, was der Anwender so zusammenbaut, muss ich am Ende
              ein Bildschirmfoto schießen und auf dem Webserver speichern.
              Deshalb der canvas, von dem man so ein Foto schießen kann.
              Das alles klappt soweit nur, wenn ich alle Drag-Objekte vorher schon anbiete.
              Das könnten sehr viele sein, leider.
              Deshalb die Idee, das Dragobjekt nur bei Bedarf zu erstellen.

              So wie es aussieht, muss ich auf das dynamische Erstellen verzichten.

              Gruß

  2. Hi,

    Ich muss auf einem canvas ein Polygon dynamisch auf Knopfdruck zeichnen,
    das sich per Drag and Drop verschieben und z.B. bei Doppelklick wieder
    entfernen läßt.

    Wie ist das Polygon als Dom Node zu behandeln? Geht das?

    Gar nicht, und nein.
    Canvas hat kein DOM.

    Im Canvas kannst du höchstens Pfade verwenden und per save/restore Zustände sichern und Transformationsmatrizen anwenden.

    Wenn du ein DOM haben willst, in dem du einzelne „Elemente“ einer Grafik ansprechen kannst, dann solltest du SVG verwenden.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. Üblicherweise baut man sich bei Canvas selbst ein Objektmodell. Halt die Objekte, die gezeichnet werden, indem man in jedem Frame z.B. ihre draw-Methode aufruft. Erst darin werden dann die spezifischen Canvas-Operationen durchgeführt. Es sind natürlich auch andere Repräsentationen denkbar. Diese Objekte hängen in einer Display List, die einer Stage zugeordnet ist. Beim Rendern wird diese Display List abgearbeitet. Maus-Events können von der Stage an die betreffenden Objekte durchgegeben werden. Siehe etwa die Bibliothek https://github.com/molily/liquid.

      Mathias

  3. Hallo,

    sprichst du von HTML5 canvas, also dem <canvas>-Element und der entsprechenden 2D-Zeichenschnittstelle oder erzeugst du ganz normale HTML-Elemente (du nennst von div-Elemente) und formatierst diese mit CSS?

    Mathias