Autor Zpráva
návštěvník
Profil *
Ke knihovně springy.js
http://getspringy.com/demo.html
jsem vytvořil funkci getNode, která nahrazuje současnou funkci .nearest ( Layout.ForceDirected.prototype.nearest ).

Aplikace se spouští dokolečka a vykresluje ikony, které se pohybují na canvasu.

    Springy.requestAnimationFrame = __bind(this.requestAnimationFrame ||
        this.webkitRequestAnimationFrame ||
        this.mozRequestAnimationFrame ||
        this.oRequestAnimationFrame ||
        this.msRequestAnimationFrame ||
        (function(callback, element) {
            this.setTimeout(callback, 10);
        }), this);

Nejsem tak sběhlý v Jquery, takže tomu callbacku a časovači až tak moc nerozumím, ale chápu to tak, že tick() ovlivňuje rychlost vykreslování. Defaultní tick je 0.03 a to bylo na mě moc rychle, tak jsem to nastavil na 0.15.

Springy.requestAnimationFrame(function step() {
            t.tick(0.15);

            if (render !== undefined) {
                render();
            }

            // stop simulation when energy of the system goes below a threshold
            if (t._stop || t.totalEnergy() < t.minEnergyThreshold) {
                t._started = false;
                if (onRenderStop !== undefined) { onRenderStop(); }
            } else {
                Springy.requestAnimationFrame(step);
            }
        });

springyui.js obsahuje událost mousemove, ze které spouštím svoji novou funkci layout.getNode()

  jQuery(canvas).mousemove(function(e) {

    var canvasPosition = jQuery(this).offset();
    nearest = layout.getNode(
      canvasPosition,
      e.pageX - canvasPosition.left, // x
      e.pageY - canvasPosition.top // y
      );
    p = layout.getMousePoint();            
    var s = nearest.node.coords;        

která prochází 150 uzlů v mém programu ve smyčce, volá další funkce na uzly které jsou vidět a dál dělá převod a počítá vzdálenost mezi uzly, aby našel nejbližší uzel. Vadí mi na tom to že se dle mého názoru tato funkce spouští zbytečně často. Vyjde-li například vzdálenost nearest.distance větší než hodnota V konstanty /nazveme ji třeba/ "K", pak je kurzor myši mimo ikonu a netřeba volat getNode tak často. Konstanta K je float, tam bych musel udělat převod na vzdálenost v pixelech. Pokud tedy vzdálenost v pixelech je větší než 32 px, pak je myš mimo ikonu a netřeba často volat getNode. Chtělo by to trackovat polohu myši vzhledem k ikoně a "času". Ale jak to udělat? Chtěl bych se vyhnout volání další funkce zevnitř .mousemove. Chtělo by to navyšovat nějakou proměnnou ale v jakých intervalech a jak to realizovat? Abych mohl nadefinovat pravidla pro volání getNode() např. tak, že je li myš daleko (nearest.distance má velkou hodnotu), bude se čekat déle; je-li myš blíže (nearest.distance má střední hodnotu) bude se čekat kratší dobu, je li myš blízko ikoně bude se čekat jen chvíli a je-li nad ikonou, budu např. spouštět getNode() co druhé volání. Pokud čas ještě neuplynul mousemove vrátí false.

Určitě v JS existuje funkce na získání přehledu o času, ale to si nemyslím že by bylo nejefektivnější řešení volat funkci po každém mousemove, spíš bych upřednostnil jen navyšování hodnoty. Si bych měl použít setTimeout a jako vstupní argument dát proměnnou kterou budu moci měnit zevnitř springy. Ale potřeboval bych s tím poradit protože je to prostě programování pro pokročilé a nechci tu knihovnu zkazit tím že bych to zavedl na nesprávném místě. Navíc nevím jak přesně funguje requestAnimationFrame, jaký je vztah mezi tím tickem a setTimeout a argumentem callback ve funkci __bind().
návštěvník
Profil *
Mohl by mi teda aspoň někdo popsat co dělá to __bind? Mám za to že by bind mělo přidělit funkci která bude volána při jakési události, ale nechápu pak tu řadu argumentů kombinované s operátorem OR ||

Prostě bych byl vděčný za radu jak vytvořit časovač který by běžel pod Layout.ForceDirected
http://getspringy.com/springy.js
že bych tedy vytvořil časovač něco jako

this.delay=200;
this.run=false;
this.setTimeout(this.run=true, this.delay); // smyčka

A když se tedy this.run nastaví na true, tak geNode se spustí a pak za nastaví this.run=false a bude se čekat na opětovné zavolání this.setTimeout(this.run=true, this.delay);
_es
Profil
návštěvník:
Mohl by mi teda aspoň někdo popsat co dělá to __bind?
Prečo sa pýtaš nás a nie tvorcov tej „knižnice“, kde je tá funkcia definovaná?
Chamurappi
Profil
Reaguji na návštěvníka:
Nejsem tak sběhlý v Jquery, takže tomu callbacku a časovači až tak moc nerozumím
Uvedené funkce nemají vůbec nic společného s jQuery.

Navíc nevím jak přesně funguje requestAnimationFrame, jaký je vztah mezi tím tickem a setTimeout a argumentem callback ve funkci __bind().
Očekával bych, že requestAnimationFrame zavolá funkci v callbacku co nejdříve to dává z hlediska vykreslování smysl. Může to být po pár milisekundách, nebo i po sekundě, pokud stránka není vidět – v tom spočívá kouzlo této metody, není určená k časování, ale k optimálnímu překreslování.
První blok kódu s tím __bindem je očividně jen polyfill, který sjednocuje prohlížeče, protože to některé podporují oprefixovaně nebo vůbec…
Tipnul bych si, že __bind bude jistit, že v this uvnitř toho funkčního výrazu se setTimeoutem je to, co tam má být… tedy skoro určitě window. Ale protože je window globální objekt, je to zbytečné.

Myslím, že tohle zkoumání __bindu je ti téměř jistě k ničemu, sehnal sis na hraní Porsche a snažíš se mu rozebrat párátkem autorádio ve snaze zlepšit jízdní vlastnosti…

A když se tedy this.run nastaví na true
Což nastane okamžitě, ne až po uplynutí 200 milisekund, protože na třetím řádku provádíš this.run=true a tvé volání je pak srovnatelné s this.setTimeout(true, this.delay).

Určitě v JS existuje funkce na získání přehledu o času, ale to si nemyslím že by bylo nejefektivnější řešení volat funkci po každém mousemove
Zjistit čas je řádově mnohem snazší než všechno ostatní, co tam děláš.
Hlavně ten ping pong se souřadnicemi vypadá dost krkolomně. Uvnitř e máš univerzálně funkční clientX a clientY, které ti vrací pozici ve vztahu k oknu. V this.getBoundingClientRect() jsou zase souřadnice elementu ve vztahu k oknu. Ale ty je nepoužíváš, místo toho saháš po jQueryovském offsetu, který interně volá také getBoundingClientRect a přičítá ke zjištěným hodnotám stav odrolování, a po pageX a pageY, které jQuery též kvůli kompatibilitě dopočítává tak, že ke clientX a clientY připočítává stav odrolování. Myslíš, že zjistit stav odrolování je snazší, než zeptat se systému, kolik je new Date().getTime()?
návštěvník
Profil *
Chamurappi:
Dík za vysvětlení, je to dost složité.

„A když se tedy this.run nastaví na true“
Což nastane okamžitě, ne až po uplynutí 200 milisekund, protože na třetím řádku provádíš this.run=true a tvé volání je pak srovnatelné s this.setTimeout(true, this.delay).

Já to použil spíš jako nekompletní pseudo kód. To nastavení na třetím řádku nemá být na třetím ale někde uvnitř té události .mousemove ...

Díky za rady zkusím to přizpůsobit
návštěvník
Profil *
Funguje skvěle. Snažím se ještě dořešit druhou část týkající se převodu:

"Konstanta K je float, tam bych musel udělat převod na vzdálenost v pixelech. Pokud tedy vzdálenost v pixelech je větší než 32 px, pak je myš mimo ikonu a netřeba často volat getNode."

setMousePoint vypočítává převod ze screen coordinates x,y na point x,y . Protože matematika mi nikdy nešla tak ještě prosím o pomoc jak vyřešit ten převod vzdálenosti do px. Dá se to na základě těchto údajú?

Layout.ForceDirected.prototype.setMousePoint = function(x,y) {
    var size = this.currentBB.topright.subtract(this.currentBB.bottomleft);
    this.mousepoint.x = (x / this.canvas.width) * size.x + this.currentBB.bottomleft.x;
    this.mousepoint.y = (y / this.canvas.height) * size.y + this.currentBB.bottomleft.y;
    return this.mousepoint;    
    };
  
Layout.ForceDirected.prototype.toScreen = function(p, distance) {
    var size = this.currentBB.topright.subtract(this.currentBB.bottomleft);
    var sx = p.subtract(this.currentBB.bottomleft).divide(size.x).x * this.canvas.width;
    var sy = p.subtract(this.currentBB.bottomleft).divide(size.y).y * this.canvas.height;
    // this.distance =
    return new Springy.Vector(sx, sy);
    };

Buď to udělat jako převod distance na this.distance tj. z float na px nebo převést tu konstantu 32 (px) na float, což by bylo výkonově lepší protože bych to převedl jen jednou a víc netřeba to měnit.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0