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
Ähnliche Artikel
4950 mal gelesen.


9 Comments
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: 00: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: 09:40
Ja super genau so meinte ich das.
Danke.
Gruß Andreas
Dienstag 7.September 2010: 14:20
[...] habe das Rubberband überarbeitet und hier ein Beispiel, wie aus einem vorhandenen Bild damit ein Ausschnitt markiert [...]
Freitag 13.Mai 2011: 06:29
Hi,
tausend Dank für dieses aufgeräumte Script. Das hat mir viel gebracht, und vor allem viel Arbeit/Fummelei gespart! Großen Respekt... Eine kleine Schönheitsanmerkung: Es heißt original, nicht orginal
Aber das Script funktioniert natürlich auch mit Rechtschreibfehler im Variablennamen. VIELEN VIELEN DANK!
Sebastian
Freitag 13.Mai 2011: 07:32
Freut mich.
Und danke für den Hinweis auf das Original, dass war mir gar nicht bewußt. Man lernt nie aus.
Einen Kommentar hinterlassen