Announcement

Collapse
No announcement yet.

JavaScript-Animation verstehen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • JavaScript-Animation verstehen

    Hallo!

    Ich hab aus diesem Buch hier https://www.apress.com/9781430227908 mir mal ein Beispiel angeguckt und versuch grad, es zu verstehen. Der Sourcecode ist auf der Seite frei verfügbar, deswegen geh ich mal davon aus, dass ich das hier posten darf:

    Code:
    <!DOCTYPE html>
    <html>
      <title>HTML5 Canvas Example</title>
    
      <style type="text/css">
        @import url("styles.css");
        <!-- #heatmap {
            background-image: url("mapbg.jpg");
        } -->
      </style>
    
      <h1>HTML5 Canvas Example</h1>
      <p id="support">Your browser supports HTML5 Canvas!</p>
      <h2>Heatmap </h2>
      <canvas id="heatmap" class="clear" style="border: 1px solid ; " height="300" width="300"> </canvas>
        <button id="resetButton">Reset</button>
      
      <script>
        function log() {
            console.log(arguments);
        }
    
        var points = {};
        var SCALE = 3;
    
        var x = -1;
        var y = -1;
    
        function loadDemo() {
            document.getElementById("resetButton").onclick = reset;
    		
            canvas = document.getElementById("heatmap");
            context = canvas.getContext('2d');
            context.globalAlpha = 0.2;
    		// set the canvas to have a high transparency value for its global drawing operations
            context.globalCompositeOperation = "lighter";
    		// set the composite mode to cause new draws to lighten the underlying pixels rather than replace them
    	
            function sample() {
                if (x != -1) {
                    addToPoint(x,y)
                }
                setTimeout(sample, 100);
            }
    
            canvas.onmousemove = function(e) {
               x = e.clientX - e.target.offsetLeft;
                y = e.clientY - e.target.offsetTop;
                addToPoint(x,y)
            }
    
            sample();
        }
    
    
    
        function reset() {
            points = {};
            context.clearRect(0,0,300,300);
            x = -1;
            y = -1;
        }
    
    
    
    // a lookup table of colors to use when drawing heat on the canvas
        function getColor(intensity) {
            var colors = ["#072933", "#2E4045", "#8C593B", "#B2814E", "#FAC268", "#FAD237"];
            return colors[Math.floor(intensity/2)]; 
        }
    
    
    
    	// Whenever the mouse moves or hovers over an area of the canvas, a point is drawn. The point grows
    // in size (and brightness) the longer the mouse stays in the immediate area.
    
        function drawPoint(x, y, radius) {
                context.fillStyle= getColor(radius);
                radius = Math.sqrt(radius)*6;
    
                context.beginPath();
                context.arc(x, y, radius, 0, Math.PI*2, true)
    
                context.closePath();
                context.fill();
        }
    
    
    
        function addToPoint(x, y) {
            x = Math.floor(x/SCALE);
            y= Math.floor(y/SCALE);
    		
            if (!points[[x,y]]) {
                points[[x,y]] = 1;
            } else if (points[[x,y]]==10) {
    	return
            } else {
                points[[x,y]]++;
            }
            drawPoint(x*SCALE,y*SCALE, points[[x,y]]);
        }
    
        window.addEventListener("load", loadDemo, true);
      </script>
    </html>
    Ich hab mit Folgendem Probleme:

    1. was genau bewirkt das
    Code:
    if( x != -1)
    in der Funktion sample()? - Wenn ich da irgendwas Anderes als -1 reinschreibe, beginnt die Animation sofort im oberen linken Eck des canvas..
    2. Ich kapier den Rückgabewert der getColor-Funktion nicht. Die bekommt als Wert den Radius übergeben (drawPoint()) und nutzt das dann, um die Farben auszuwählen. Aber welchen Wert hat der Wert, der in Math.floor steht?
    3. Welchen Wert hat der Parameter radius in der drawPoint()-Funktion?
    4. Das points[]-Array verstehe ich auch nicht. Was ist das für eine Konstruktion? points[[x,y]] und wieso kann man da einfach ++inkrementieren?

    Soweit erstmal, vielen Dank schon mal!

  • #2
    Hallo,
    ich versuchs mal ...
    Originally posted by Vokabulator View Post
    1. was genau bewirkt das
    Code:
    if( x != -1)
    in der Funktion sample()? - Wenn ich da irgendwas Anderes als -1 reinschreibe, beginnt die Animation sofort im oberen linken Eck des canvas..
    != ist der Ungleich-Operator und gleichbedeutend mit <>. x ist eine Globale Variable, die mit -1 initialisiert wird. Solange x also auf -1 steht, wird addToPoint(x,y) NICHT aufgerufen.
    Originally posted by Vokabulator View Post
    2. Ich kapier den Rückgabewert der getColor-Funktion nicht. Die bekommt als Wert den Radius übergeben (drawPoint()) und nutzt das dann, um die Farben auszuwählen. Aber welchen Wert hat der Wert, der in Math.floor steht?
    Math.floor ermittelt zu einer gebrochen rationalen Zahl die nächstkleinere Ganzzahl. Oder einfacher, floor schneidet den gebrochenen Anteil einer Zahl ab. In dem konkreten Fall wird der übergebene Radius durch 2 geteilt und dann an Math.floor übergeben. Wenn ich das Richtig überblicke kann jeder Punkt einen "Radius" von 1 - 10 haben. Damit ergeben sich für die möglichen Farben 6 Werte (1/2 => 0,5 => 0 bis 10/2 => 5 => 5) und die stehen in dem Array colors. Damit soll wohl erreicht werden, dass die Punkte nicht nur immer größer sondern auch immer heller (von Dunkelblau bis Gelborange) werden. (Steht ja auch so im Kommentar )
    Originally posted by Vokabulator View Post
    3. Welchen Wert hat der Parameter radius in der drawPoint()-Funktion?
    Der radius wird beim ersten Zeichnen auf 1 gesetzt
    [highlight=javascript]
    if (!points[[x,y]]) {
    points[[x,y]] = 1;
    [/highlight]
    und dann bei jedem Durchlauf um 1 erhöht bis maximal 10
    [highlight=javascript]
    else if (points[[x,y]]==10) {
    return
    } else {
    points[[x,y]]++;
    [/highlight]
    Originally posted by Vokabulator View Post
    4. Das points[]-Array verstehe ich auch nicht. Was ist das für eine Konstruktion? points[[x,y]] und wieso kann man da einfach ++inkrementieren?
    points ist kein Array! points wird als Objekt initialisiert
    [highlight=javascript]
    var points = {};
    [/highlight]
    Der Ausdruck points[[x,y]] ist etwas Tricky... Javascript kennt zwei Möglichkeiten auf die Eigenschaften eines Objektes zuzugreifen. Zum Einen direkt über den Namen in der Form
    [highlight=javascript]
    myObject.myProperty = 'irgendeinText';
    [/highlight]
    Oder über die Eigenschaftsliste (ähnlich einem Array) in der Form
    [highlight=javascript]
    myObject['myProperty'] = 'irgendeinText';
    [/highlight]
    Die zweite Variante macht dann Sinn, wenn der Eigenschaftsname Zeichen enthält, die den direkten Zugriff syntaktisch unmöglich machen. Soll meine Eigenschaft z.B. 'my Property' oder 'my.Property' heissen, dann lässt sich das nicht über den Namen machen, da myObject.my Property syntaktisch falsch und myObject.my.Property ein völlig anderer Kontext ist. Hier geht also nur myObject['my Property'] bzw. myObject['my.Property']. Eigenschaften von Objekten lassen sich also wie ein Assoziatives Array ansprechen oder besser andersrum, Arrays sind in JS einfach Objekte.
    Mit dem Ausdruck [x,y] - was als solches erstmal ein Array ist - macht es sich der Autor des Codes etwas einfach und damit dem unerfahrenen Leser etwas schwer. Da der Zugriff über die Eigenschaftsliste einen String erwartet, wird hier das gegebene Array implizit in einen String konvertiert. Angenommen x ist 1 und y ist 2, dann kommt mit [x,y] ein String '1,2' raus.
    Mit der Zuweisung
    [highlight=javascript]
    points[[x,y]] = 1
    [/highlight]
    in der addToPoint Funktion, wird also für das Objekt points eine Eigenschft '<x>,<y>' mit dem Wert 1 angelegt, wobei <x> und <y> die konkreten Werte der beiden Variablen sind.
    Man hätte das auch "lesefreundlicher" lösen können, wenn man eine explizite Typumwandlung gewählt hätte, etwa
    [highlight=javascript]
    var index = String(x) + ',' + String(y);
    points[index] = 1
    [/highlight]
    Den numerischen Wert, der sich hinter points[[x,y]] verbirgt (also im ersten Fall eine 1) kann man natürlich einfach mit ++ inkrementieren.

    Gruß Falk
    Zuletzt editiert von Falk Prüfer; 13.02.2014, 11:38.
    Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

    Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

    Comment


    • #3
      Vielen Dank zunächst mal!

      Auf das mit dem point-Objekt wäre ich in Jahren nicht gekommen

      Noch mal zum if(x != -1) - den nicht-gleich-Operator verstehe ich, aber nicht, warum -1 da steht. Ist das -1 einfach als "außerhalb des Canvas" zu verstehen?

      Und wegen der Farben: D. h. also, die getColor-Funktion bekommt z. B. 3.67 übergeben, das wird durch 2 geteilt (1.835), was dann wegen floor zu 1 wird?

      Und die gesamte Funktion addToPoints
      > Die bewirkt, dass sich die Punkte im Radius vergrößern, richtig? D.h. hier werden die x-y-Werte des Punktes und die Position verändert.

      Was ich noch nicht genau kapiere ist, warum x (und y) erst noch x = Math.floor(x/SCALE) haben. Das x steht ja für die Mausposition auf der x-Achse, oder?

      Comment


      • #4
        Originally posted by Vokabulator View Post
        ...Noch mal zum if(x != -1) - den nicht-gleich-Operator verstehe ich, aber nicht, warum -1 da steht. Ist das -1 einfach als "außerhalb des Canvas" zu verstehen?
        So ähnlich ... -1 ist ein imaginärer Startwert der normalerweise nicht vorkommt. Das könnte auch jeder andere negative Wert oder NULL sein. Solange also nach dem Start die Maus nicht bewegt wird, solange passiert nichts. Bei der ersten Mausbewegung besitzt x dann einen gültigen Wert und die Animation startet.

        Originally posted by Vokabulator View Post
        ...Und wegen der Farben: D. h. also, die getColor-Funktion bekommt z. B. 3.67 übergeben, das wird durch 2 geteilt (1.835), was dann wegen floor zu 1 wird?
        Wenn ich das richtig überblicke, dann bekommt diese Funktion immer den "Radius" übergeben. Das ist ein ganzzahliger Wert zwischen 1 und 10. Durch das Teilen durch 2 und das floor wird die Farbe halt nur bei jedem zweiten Schritt geändert. 1 wird zu 0, 2 zu 1, 3 zu 1, 4 zu 2, 5 zu 2, etc.

        Originally posted by Vokabulator View Post
        ... Und die gesamte Funktion addToPoints
        > Die bewirkt, dass sich die Punkte im Radius vergrößern, richtig? D.h. hier werden die x-y-Werte des Punktes und die Position verändert.
        Ich würde sagen, hier werden die Position und der Radius des Punktes geändert.

        Originally posted by Vokabulator View Post
        ... Was ich noch nicht genau kapiere ist, warum x (und y) erst noch x = Math.floor(x/SCALE) haben. Das x steht ja für die Mausposition auf der x-Achse, oder?
        Da am Anfang die X und Y-Werte durch SCALE geteilt, dann jedoch wieder mit SCALE multipliziert an drawPoint übergeben werden, ist SCALE hier sowas wie eine Empfindlichkeit. Man kann die Maus also um SCALE Pixel bewegen um den aktuellen Punkt zu verändern, danach wird an der neuen Stelle ein neuer Punkt angelegt. Die Variablen x und y innerhalb der Funktion addToPoint sind lokale Variablen (da sie als Parameter übergeben werden) und haben nichts mit den beiden globalen Variablen x und y zu tun! Das ist eine typische Falle bei der Verwendung globaler Variablen und zeugt nicht gerade von gutem Stil.

        Gruß Falk
        Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

        Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

        Comment

        Working...
        X