Javascript Rubberband
Beschreibung
Um mit der Maus Bereiche zu markieren wird ein sogenanntes Rubberband (dt. Gummiband) benutzt. Die Funktionsweise ist aus Grafikprogrammen bekannt oder auch dem Windows Desktop. Wenn die Maus mit gedrückter linken Maustaste bewegt wird, wird ein rechteckiger Kasten gebildet, der den Bereich der ausgewählt werden soll markiert.
Dazu habe ich diese kleine Skript geschrieben, dass einfach in eine Seite eingebunden werden kann. Mit Hilfe von Events kann das Verhalten gesteuert werden.
Funktionsweise
Das Javascript Rubberband basiert auf ein globales Objekt Namens Rubber, da es nur ein Rubberband geben kann. Die ini()-Funktion starten es. Wenn nun die Maus gedrückt wird erscheint ein Rechteck mit einer gepunkteten Linie. Die Events Rubber.onstart, Rubber.onmove und Rubber.onend werden gefeuert, den Eventfunktionen wird ein Objekt als Parameter übergeben, dass die Position und Größe des Rubberbands hat. Geben die Funktion false zurück wird der Event unterbrochen. D.h. beim onstart Event, wird das Band nicht angezeigt beim move Event nicht vergrößert und beim end Event nicht beendet.
Verwendung
Eingebunden wird das Skript mit den üblichen script-Tag:
<script type="text/javascript" src="rubber.js"></script>
Rubber.ini()
Dann muss es initialisiert werden
Rubber.ini([EventHandler]); |
Der optionale Parameter EventHandler ist eine Funktionsreferenz auf einen EventListener, z.b. addEvent(), falls eigene Eventlistener verwendet werden müssen. Ohne diese Angabe verwendet das Skript [object].onmousedown. Der Aufruf des EventHandler erfolgt so
eventHandler(object, 'onevent', func), der erste Parameter ist das Objekt auf dem der Event stattfindet, der zweite ein String mit dem Eventnamen (inklusive on) und der dritte die Referenz auf die Funktion. Will man also z.b. die addEventListener() Funktion des Firefox einbinden müßte der Aufruf so aussehen:
Rubber.ini( function(obj, evt, func) { |
obj.addEventListener(evt.substring(2), func, false); |
return false; |
} |
); |
Events
Das Rubberband feuert drei Events, alle Events haben ein Objekt als Parameter, das die Position und die Größe des Rubberbands definieren.
- onstart(rect)
- Wird gefeuert, wenn die Maustaste gedrückt wird.
- onmove(rect)
- Wird beim ziehen gefeuert, in
rectzeigt auf das Rechteck vor der Berechnung des Mausposition, d.h. wird hierfalsezurückgegeben, wird das Rubberband nicht mehr vergrößert. - onend(rect)
- Wird gefeuert, wenn die Maustaste losgelassen wurde.
Beispiel
Ein typisches Beispiel ist ein Bild bei dem ein Auschnitt markiert werden soll.
| Orginal: | Auschnitt auf die Orginalgröße vergrößert: | onmove Event: |
|
|
Rubber.onmove = function(r) {
r.width = ;
r.height = ;
r.top = ;
r.left = ;
}
|
window.onload = function() { |
Rubber.ini(); |
var info = document.getElementById('info'); |
var onmove = document.getElementById('onmove'); |
Rubber.onstart = function(r) { |
var orginal = document.getElementById('bild'); |
var p = getPos(orginal); |
// Nur der Bereich des Bildes kann markiert werden. |
return (r.top >= p.top && r.left >= p.left |
&& (r.width + r.left) <= (orginal.width + p.left) |
&& (r.height + r.top) <= (orginal.height + p.top) |
); |
} |
Rubber.onmove = function(r){ |
var s = this.getSize(); |
var p = this.getPos(); |
var orginal = document.getElementById('bild'); |
var p = getPos(orginal); |
if(onmove) { |
var out = onmove.getElementsByTagName('span'); |
out[0].innerHTML = s.width; |
out[1].innerHTML = s.height; |
out[2].innerHTML = p.top; |
out[3].innerHTML = p.left; |
} |
// Nur der Bereich des bildes |
return (r.top >= p.top && r.left >= p.left |
&& (r.width + r.left) <= (orginal.width + p.left) |
&& (r.height + r.top) <= (orginal.height + p.top) |
); |
} |
Rubber.onend = function() { |
/* |
Hier wird der Auschnitt berechnet, der markiert wurde |
und in einem DIV mit der Größe des Orginalbildes angezeigt |
d.h. es kann zu Verzerrungen kommen. |
*/ |
var s = this.getSize(); |
var p = this.getPos(); |
var orginal = document.getElementById('bild'); |
var zoom = document.getElementById('zoom'); |
var zoom_faktor_x = parseInt( orginal.width / s.width * 100) / 100; |
var zoom_faktor_y = parseInt( orginal.height / s.height * 100) / 100; |
// Die Größe des Bildes |
zoom.firstChild.width = parseInt( orginal.width * zoom_faktor_x) ; |
zoom.firstChild.height = parseInt( orginal.height * zoom_faktor_y) ; |
// Die Position des Bildes |
var top = p.top - getPos(orginal).top; |
var left = p.left - getPos( orginal).left; |
zoom.firstChild.style.top = -(top * zoom_faktor_y) + 'px'; |
zoom.firstChild.style.left = -(left* zoom_faktor_x) + 'px'; |
zoom.firstChild.style.display = 'inline'; |
if(!info) return true; |
info.innerHTML = '<pre><small>' |
+ 'Position im Bild :<b>' + top + 'px</b> x <b>' + left + 'px</b> (oben x links)<br>' |
+ 'Größe :<b>' + s.width + 'px</b> x <b>' + s.height + 'px</b> (breite x höhe)<br>' |
+ 'zoom x/y : ' + zoom_faktor_x + ' x ' + zoom_faktor_y |
+ '= ' + zoom.firstChild.height + ' x ' + zoom.firstChild.width + '<br>' |
+ '</small></pre>' |
; |
return true; |
} |
} |
var getPos = function(obj) { |
var top = 0; |
var left = 0; |
var o = obj; |
do { |
top += parseInt(o.offsetTop); |
left += parseInt(o.offsetLeft); |
o = o.offsetParent; |
} while(o); |
return { top: top, left: left}; |
}; |
Download
3271 mal gelesen.


6 Kommentare Einen Kommentar hinterlassen »
Kommentare
Sonntag 16.November 2008: 20:31
Hallo,
tolles Beispiel!
Einziges Manko ist dass nach dem Schneiden das Bild verzerrt ist wenn das Seitenverhältnis sich ändert. Kann man das ändern so dass das Bild sich so ändert dass es die Maße des Ausschnitts hat?
Gruß Andreas
Sonntag 16.November 2008: 23:19
Eine tolle Funktion, aber nicht ganz fertig.
Zum Beispiel wird beim Ziehen des Rahmens r.top und r.left nicht verändert.
Ich habe einer vergleicgbare Funktion mal in einem Kontaktforum gesehen, da konnte man sein Portrait zurechtschneiden.
MfG Kalle
Montag 17.November 2008: 0:55
Wieso sollte beim ziehen die Position des rubberbandes geändert werden?
@Andreas: Das Beispiel zeigt nur die Funkktionalität und die Events des rubberband, es muss dann entsprechend den eigenen Bedürfnissen angepaßt werden, in der onend Eventfunktion.
Montag 17.November 2008: 17:30
Hallo,
fürchte es ist nicht möglich,
ich habe schon mehrere Stunden damit zugebracht das herauszufinden.
schade.
Andreas
Montag 17.November 2008: 17:53
Die Frage dabei ist, was möchtest? Das Beispielskript brechnet ja den zoom Faktor anhand der Größe des Auschnitts. Ich hab mal ein Beispiel online gestellt, wo du den Zoomfaktor verändern kannst.
Dienstag 18.November 2008: 9:40
Ja super genau so meinte ich das.
Danke.
Gruß Andreas
Einen Kommentar hinterlassen