tufan: Event-Handler

hallo..

ich habe vor kurzem angefangen ein neues programm zu schreiben, mit dem ich über den browser bilder bearbeiten kann. zur visuellen darstellung, bessergesagt, für die vereinfachung der aktionen benütze ich javascript. dabei habe ich zur zeit ein problemkind: erstellen eines auswahlbereiches auf einem bild.

das problem resultiert dabei hauptsaechlich daraus, dass ich, nachdem ich eine aktion mittels "onmousemove" starte, diese nicht mehr stoppen kann. in javascript dokus habe ich dafür auch keine lösung gefunden. wenn dies also irgendwie möglich ist, ist der rest dieses beitrages wahrscheinlich uninteressant, da das problem gelöst waere :o)

nun zur detailierten beschreibung:

ich habe ein bild, das mittels <input type=image> darstelle. (könnte genauso gut <img src.. > nehmen)
darauf soll der benützer mittels klicken und ziehen (auf einem beliebigen punkt über dem bild) ein auswahlrechteck erstellen können.

dafür habe ich zunaechst einen unsichtbaren <div> bereich, sagen wir Layer1 (1px x 1px).

bei gedrückter maustaste startet die funktion showLayer(), die den Layer1 ersmal sichtbar macht und bei einer mouse bewegung die weitere funktion draw() aufruft.
draw() macht nichts anderes als die breite und höhe des Layer1 mit der mouse-coordinaten gleich zu setzen, also die auswahl zu erstellen.

bei losgelassener mousetaste sollte die funktion fix() aufgerufen werden, die wiederum die letzten coordinaten des mousezeigers dem Layer1 zuweisen soll.

<input type="image" src="testimg.jpg" style="cursor:crosshair" onmousedown="showLayer();" onmouseup="fix();">

somit sollte in der theorie ein auswahlrechteck erstellt werden.
habe ich bisjetzt einen denkfehler ?
denn, die praxis zeigt, dass Layer1 einfach nicht fix-bleibt, sondern in der höhe und breite der mouse weiter folgt. onmousemove wird einfach nicht mehr gestoppt, und die bedingung onmouseup zeigt keine wirkung.

kann mir jemand sagen warum das so ist, bzw. ob es eine lösung dafür gibt?

zur lösung dieses problems habe ich bisschen improvisiert und -wie man aus dem unteren code entnehmen kann- 2 div bereiche eingesetzt: (so wie unten dargestellt kann ich zwar ein rechteck erstellen, aber nicht immer; und es traten weitere probleme auf)

<input type="image" src="testimg.jpg" style="cursor:crosshair" onmousedown="showLayer();" onmouseup="hideLayer();">

function showLayer()
{
   document.getElementById('layer3').style.visibility = "hidden";
   x = window.event.offsetX;
   y = window.event.offsetY;
   document.getElementById('layer2').style.left = x;
   document.getElementById('layer2').style.top = y;

document.getElementById('layer3').style.left = x;
   document.getElementById('layer3').style.top = y;

document.getElementById('layer2').style.visibility = "visible";

document.onmousemove = draw;
   document.onmouseup= hideLayer;
   document.onmouseup = fix;
}
function draw()
{
   h= window.event.offsetX;
   i= window.event.offsetY;

x = h- parseInt(eval('document.getElementById("layer2").style.left'));
   y = i- parseInt(eval('document.getElementById("layer2").style.top'));
   if (x<0) x = h;
   if (y<0) y = i;

document.getElementById('layer2').style.width = parseInt(x);
   document.getElementById('layer2').style.height = parseInt(y);
}

function hideLayer()
{
   document.getElementById('layer2').style.visibility = "hidden";
}
function fix()
{
   h= window.event.clientX;
   i= window.event.clientY;

x = h- parseInt(eval('document.getElementById("layer2").style.left'));
   y = i- parseInt(eval('document.getElementById("layer2").style.top'));
   if (x<0) x = h;
   if (y<0) y = i;
   document.getElementById('layer3').style.width = x;
   document.getElementById('layer3').style.height = y;
   document.getElementById('layer3').style.visibility = "visible";
}

der code ist bisjetzt recht umstaendlich ich weiss; aber noch ist alles in der testphase, deswegen bitte ich um verstaendnis :-)
(PS: es genügt, -vorerst mal- wenn das ganze unter IE >6.0 funktioniert. auf netscape, mozilla etc. muss ich -noch- nicht acht nehmen)

bin für jeden vorschlag dankbar.

grüsse,

tufi

  1. ich habe ein bild, das mittels <input type=image> darstelle. (könnte genauso gut <img src.. > nehmen)
    darauf soll der benützer mittels klicken und ziehen (auf einem beliebigen punkt über dem bild) ein auswahlrechteck erstellen können.

    Ich bin mir nicht sicher was du machen willst. Aber es klingt stark nach einem rubberband wie das z.b. http://www.faqts.com/knowledge_base/view.phtml/aid/1431/fid/128

    Struppi.

    1. nicht ganz, das was ich machen will, aber habe ein paar sachen von dem skript dazugelernt.

      danke für die info.

      grüsse,

      tufi

  2. Hi,

    <input type="image" src="testimg.jpg" style="cursor:crosshair" onmousedown="showLayer();" onmouseup="fix();">

    somit sollte in der theorie ein auswahlrechteck erstellt werden.
    habe ich bisjetzt einen denkfehler ?
    denn, die praxis zeigt, dass Layer1 einfach nicht fix-bleibt, sondern in der höhe und breite der mouse weiter folgt. onmousemove wird einfach nicht mehr gestoppt, und die bedingung onmouseup zeigt keine wirkung.

    kann mir jemand sagen warum das so ist, bzw. ob es eine lösung dafür gibt?

    zur lösung dieses problems habe ich bisschen improvisiert und -wie man aus dem unteren code entnehmen kann- 2 div bereiche eingesetzt: (so wie unten dargestellt kann ich zwar ein rechteck erstellen, aber nicht immer; und es traten weitere probleme auf)

    <input type="image" src="testimg.jpg" style="cursor:crosshair" onmousedown="showLayer();" onmouseup="hideLayer();">

    function showLayer()
    {
       document.getElementById('layer3').style.visibility = "hidden";
       x = window.event.offsetX;

    x enthält jetzt eine Zahl.

    document.getElementById('layer2').style.left = x;

    left kann mit einer Zahl nichts anfangen, es wird eine Länge erwartet.

    document.getElementById('layer2').style.top = y;

    gleiches gilt für top usw.

    x = h- parseInt(eval('document.getElementById("layer2").style.left'));

    wozu soll hier bitte das eval dienen?

    document.getElementById('layer2').style.width = parseInt(x);

    auch width (und height) erlauben keine Zahl als Wert.

    function fix()
    {
       x = h- parseInt(eval('document.getElementById("layer2").style.left'));

    s.o.

    document.getElementById('layer3').style.width = x;

    s.o.

    Zu dem von Dir angesprochenen Problem:
    bei onmousedown setzt Du den Eventhandler für onmousemove. Dieser bleibt logischerweise solange erhalten, bis er durch einen anderen ersetzt wird.
    Das geschieht aber im gezeigten Code (und insbesondere in der Funktion fix) nirgends.

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
    1. Hi,

      hallo und danke für die schnelle antwort.

      x = window.event.offsetX;

      x enthält jetzt eine Zahl.

      document.getElementById('layer2').style.left = x;

      left kann mit einer Zahl nichts anfangen, es wird eine Länge erwartet.

      hmm.. mit Laenge meinst du die form "eine Zahl + px" oder ? ich habe angenommen, dass die zahlenwerte automatisch in laengenwerte umgewandelt werden, da es funktioniert hat. Aber ich habe inzwischen "px" dazugehaengt.

      x = h- parseInt(eval('document.getElementById("layer2").style.left'));

      wozu soll hier bitte das eval dienen?

      in dem fall brauchte ich "die zahl" als linker anfangspunkt vom layer2 damit ich das von x abziehen kann. das hat erst dann funktioniert, nachdem ich eval() dazugehaengt habe (da ich angenommen habe, dass eval den wert mir als zurückliefert, was in der praxis bisjetzt kein problem gemacht hat. Geht es auch anders/ besser? )

      Zu dem von Dir angesprochenen Problem:
      bei onmousedown setzt Du den Eventhandler für onmousemove. Dieser bleibt logischerweise solange erhalten, bis er durch einen anderen ersetzt wird.

      so logisch ist es als JavaScript anfaenger nicht; denn der Eventhandler für onmousemove wird in einer funktion gesetzt, und ich nahm an, dass wenn die funktion verlassen wird, auch die ausführung saemtlicher darin enthaltenen methoden abgebrochen werden - was natürlich nicht stimmte.

      eine lösung via document.onmousemove = null; (welche ich aus dem von Struppi vorgeschlagenen skript abgeschaut habe) löste das problem :)

      danke nochmals,

      grüsse,

      tufi

      1. Hi,

        bei onmousedown setzt Du den Eventhandler für onmousemove. Dieser bleibt logischerweise solange erhalten, bis er durch einen anderen ersetzt wird.
        so logisch ist es als JavaScript anfaenger nicht; denn der Eventhandler für onmousemove wird in einer funktion gesetzt, und ich nahm an, dass wenn die funktion verlassen wird, auch die ausführung saemtlicher darin enthaltenen methoden abgebrochen werden - was natürlich nicht stimmte.

        Du steigst in ein Auto ein, schaltest die Zündung ein und steigst aus dem Auto aus.
        Ist die Zündung jetzt ausgeschaltet?

        cu,
        Andreas

        --
        Warum nennt sich Andreas hier MudGuard?
        Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
        1. Du steigst in ein Auto ein, schaltest die Zündung ein und steigst aus dem Auto aus.
          Ist die Zündung jetzt ausgeschaltet?

          .. da ist wahres dran :)

  3. Hallo,

    vieleicht hilft dir http://www.j-berkemeier.de/LogistischeAbbildung.html weiter. Hier kann man mit der Maus ein Rechteck ziehen, um eine Ausschnittsvergrößerung der Abbildung zu berechnen. Aber Vorsicht: die Rechnung, vor allem die Grafik, ist extrem CPU-lastig (optimiert für die 6-GHz-CPU-Generation).

    Gruß, Jürgen

    1. Hallo,

      hallo,

      danke für den verweis. die dort dargestellte lösung ist zwar viel komplizierter als das was ich machen möchte, aber ich werde sie mir genauer anschauen.

      grüsse,

      tufi

      1. Hallo,

        kleine Hilfe: wichtig sind das div mit der ID "zoom" und die Funktionen start_zoom, end_zoom, start_rect, end_rect, rect und mouse_pos. Der Rest ist für die Berechnung und Darstellung der Logistischen Abbildung. Das Rechteck kannst Du auch einfacher mit einem div mit Rahmen und transparentem Hintergrund realisieren.

        Gruß, Jürgen