Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Lupe mit Touchmove funktion ?
#1
Hallo,

ich bin neu hier. Mein Name ist Oliver und ich komme aus Graz/Österreich. Ich bin in der IT tätig und zu meinen Hobbys zählt unter anderem das erstellen von Websiten mit Perl und Javascript etc.

Jetzt hab ich hier ein kleines "Problem". Ich hab ein Javascript das mir eine Lupe über einer Bilddatei einblendet und den Bildauschnitt innerhalb der Lupe vergrössert. Das Script funktioniert eigentlich sehr gut, hab ich mehrere Bilder in der Webseite wird die Lupe über jedem Bild aufgebaut, verlässt man das Bild verschwindet die Lupe wieder. Auch auf einem Touchscreen lässt sich die Lupe beim antippen eines Bildes einblenden. Fährt man mit der Maus über das Bild so folgt die Lupe auch dem Mauszeiger. ABER: Hier ist genau mein Problem, mit der Maus funktioniert das bewegen der Lupe perfekt nur auf einem Touchscreen lässt sich die Lupe nicht bewegen sondern nur neu positionieren durch tippen auf ein Bild. Ich hab schon mit Touchevents heruzmgespielt komme aber auf keinen grünen Zweig. Vielleicht ist hier jemand der mir den Code ergänzen könnte damit ein touchmove mit dem Finder auf einem Touchscreen auch klappt ? Anbei der Code vom Script:

Für Hilfe wäre ich unendlich dankbar !!!
LG
Oliver

PS: In Javascript bin ich leider nicht wirklich so fit :-(.
------------------------------------------------------------------------------------------------


'use strict';

class imageLoupe {
constructor(image) {
// Original Image
this.originalImage = image;

// Enlarged Image
this.enlargedImage = document.createElement('img');
this.enlargedImage.src = this.originalImage.src;
this.enlargedImage.setAttribute('data-loupe-enlarged-image', '');

// Wrapper
this.wrapper = document.createElement('div');
this.wrapper.setAttribute('data-loupe-wrapper', '');

// Loupe
this.loupe = document.createElement('div');
this.loupe.setAttribute('data-loupe', '');

// Add elements to the DOM
this.wrapper.appendChild(this.loupe);
this.loupe.appendChild(this.enlargedImage);
this.originalImage.parentNode.insertBefore(this.wrapper, this.originalImage);
this.wrapper.appendChild(this.originalImage);

// Pass `this` through to methods
this.showLoupe = this.showLoupe.bind(this);
this.hideLoupe = this.hideLoupe.bind(this);
this.moveLoupe = this.moveLoupe.bind(this);

this.addEventListeners();
}

addEventListeners() {
this.originalImage.addEventListener('mouseenter', this.showLoupe);
this.originalImage.addEventListener('mouseleave', this.hideLoupe);
this.originalImage.addEventListener('mousemove',  this.moveLoupe);
this.originalImage.addEventListener('touchmove',  this.moveLoupe);
}

showLoupe() {
this.wrapper.style.zIndex = 1;
this.loupe.style.opacity = 1;
}

hideLoupe() {
this.wrapper.style.zIndex = 0;
this.loupe.style.opacity = 0;
}

moveLoupe(event) {
window.requestAnimationFrame(() => {
// Get the size and position of the original image
this.originalImageBCR = this.originalImage.getBoundingClientRect();

// Get the cursor coordinates on the original image
this.cursorX = event.x - this.originalImageBCR.left + this.originalImage.offsetLeft;
this.cursorY = event.y - this.originalImageBCR.top + this.originalImage.offsetTop;

// Determine the corresponding coordinates on the enlarged image
this.enlargedImageX = -((this.cursorX - this.originalImage.offsetLeft) / this.originalImageBCR.width * this.enlargedImage.width - this.loupe.offsetWidth / 2);
this.enlargedImageY = -((this.cursorY - this.originalImage.offsetTop) / this.originalImageBCR.height * this.enlargedImage.height - this.loupe.offsetHeight / 2);

// Center the loupe on the cursor
this.loupeX = this.cursorX - this.loupe.offsetWidth / 2;
this.loupeY = this.cursorY - this.loupe.offsetHeight / 2;

// Apply the translate values
this.enlargedImage.style.transform = `translate3d(${this.enlargedImageX}px, ${this.enlargedImageY}px, 0)`;
this.loupe.style.transform = `translate3d(${this.loupeX}px, ${this.loupeY}px, 0)`;

});
}


}

// Create a new loupe for each image
document.querySelectorAll('[data-loupe-image]').forEach(function(img) {
new imageLoupe(img);
});
Zitieren
#2
Hi Oliver, es wäre super wenn du uns den ganzen Code zusenden kannst damit man das ganze nachstellen könnte.

PS: Zu Perl: Warum arbeitest du noch mit Perl? Perl wird nicht mehr weiter entewickelt und könnte in Zukunft Fehler oder sicherheitsrelevante Probleme mit sich führen. Ich rate die Weiternutzung von Perl ab und empfehle dem Nachfolger Raku zu verwenden oder auf PHP oder Python umzusteigen.
"Gerne dürft ihr mir eine gute Bewertung da lassen aber auch gegenüber Kritik bin ich offen" Angel
Zitieren
#3
Hallo rzscout,

herzlichen Dank für Deinen Post, anbei mal ein ZIP-File mit allem was man bracht (ist das "Gerüst)", einfach das Verzeichnis "loupe_demo" auspacken und ins root-Verzeichnis von Deinem Webserver kopieren. Vielleicht kannst Du mir weiter helfen, ich probier hier schon seit Tagen herzum, komm aber nicht weiter, bin aber auch kein Javascript-Programmierer.

Warum Perl: ist aus meinem Werdegang so, ich hab in den 90ern mit Perl unter AIX und SGI angefangen.

DANKE für HILFE !!!!!!!!

LG
Oliver

PS: Ich hatte mit dem Programmierer des Ursprungscodes Kontakt, er hat kein Problem damit wenn ich oder jemand Anderes seinen Code verändert/bearbeitet, im Gegenteil, er würde sich sogar darüber freuen. Er selbst hat leider keine Zeit mehr die touchmove Funktion zu implementieren :-(


Angehängte Dateien
.zip   lupe_demo.zip (Größe: 216,12 KB / Downloads: 1)
Zitieren
#4
Hallo @"oliver_z3",
weil ich das Thema interessant finde, dachte ich, ich registriere mich Mal um antworten zu können. Bekomme jedoch die Meldung "Willkommen zurück" - ganz vergessen, dass ich mich früher schon mal registriert hatte.

Ich dachte zunächst, es liege daran, dass Du bei "touchstart" und "touchend" nichts tust um die Lupe sichtbar zu machen und zu verbergen aber das hat noch nicht zum Erfolg geführt.
Mit "touchmove" warst Du natürlich schon auf dem richtigen Wege. Das funktioniert dann ein wenig anders als ein einfaches event.target und berücksichtigt auch, dass mehrere Finger den Bildschirm berühren. Man kann das bei MDN nachlesen.

Diese Javascript funktioniert dann bei mir, ich kann die Lupe durch Ziehen mit dem Finger bewegen:
Code:
        'use strict';

        class imageLoupe {
            constructor(image) {
                // Original Image
                this.originalImage = image;

                // Enlarged Image
                this.enlargedImage = document.createElement('img');
                this.enlargedImage.src = this.originalImage.src;
                this.enlargedImage.setAttribute('data-loupe-enlarged-image', '');

                // Wrapper
                this.wrapper = document.createElement('div');
                this.wrapper.setAttribute('data-loupe-wrapper', '');

                // Loupe
                this.loupe = document.createElement('div');
                this.loupe.setAttribute('data-loupe', '');

                // Add elements to the DOM
                this.wrapper.appendChild(this.loupe);
                this.loupe.appendChild(this.enlargedImage);
                this.originalImage.parentNode.insertBefore(this.wrapper, this.originalImage);
                this.wrapper.appendChild(this.originalImage);

                // Pass this through to methods
                this.showLoupe = this.showLoupe.bind(this);
                this.hideLoupe = this.hideLoupe.bind(this);
                this.moveLoupe = this.moveLoupe.bind(this);

                this.addEventListeners();
            }

            addEventListeners() {
                this.originalImage.addEventListener('mouseenter', this.showLoupe);
                this.originalImage.addEventListener('mouseleave', this.hideLoupe);
                this.originalImage.addEventListener('mousemove', this.moveLoupe);
                this.originalImage.addEventListener('touchstart', this.showLoupe);
                this.originalImage.addEventListener('touchend', this.hideLoupe);
                this.originalImage.addEventListener('touchmove', event => {
                    // Added additional parameter "isTouch"
                    // Set to true when device is operated by touches
                    this.moveLoupe(event, true)
                });
            }

            showLoupe() {
                this.wrapper.style.zIndex = 1;
                this.loupe.style.opacity = 1;
            }

            hideLoupe() {
                this.wrapper.style.zIndex = 0;
                this.loupe.style.opacity = 0;
            }

            moveLoupe(event, isTouch) {
                window.requestAnimationFrame(() => {
                    // Get the size and position of the original image
                    this.originalImageBCR = this.originalImage.getBoundingClientRect();
                    // Get position according to parameter "isTouch"
                    let posX, posY;
                    if (isTouch) {
                        // Device is operated by touches
                        posX = event.targetTouches[0].clientX;
                        posY = event.targetTouches[0].clientY;
                        // Disable default action (panning)
                        event.preventDefault();
                    } else {
                        // Device is operated by mouse
                        posX = event.x;
                        posY = event.y;
                    }
                    // Get the cursor coordinates on the original image
                    this.cursorX = posX - this.originalImageBCR.left + this.originalImage.offsetLeft;
                    this.cursorY = posY - this.originalImageBCR.top + this.originalImage.offsetTop;

                    // Determine the corresponding coordinates on the enlarged image
                    this.enlargedImageX = -((this.cursorX - this.originalImage.offsetLeft) / this.originalImageBCR.width * this.enlargedImage.width - this.loupe.offsetWidth / 2);
                    this.enlargedImageY = -((this.cursorY - this.originalImage.offsetTop) / this.originalImageBCR.height * this.enlargedImage.height - this.loupe.offsetHeight / 2);

                    // Center the loupe on the cursor
                    this.loupeX = this.cursorX - this.loupe.offsetWidth / 2;
                    this.loupeY = this.cursorY - this.loupe.offsetHeight / 2;

                    // Apply the translate values
                    this.enlargedImage.style.transform = `scale(2) translate3d(${this.enlargedImageX}px, ${this.enlargedImageY}px, 0)`;
                    this.loupe.style.transform = `translate3d(${this.loupeX}px, ${this.loupeY}px, 0)`;

                });
            }


        }

        // Create a new loupe for each image
        document.querySelectorAll('[data-loupe-image]').forEach(function (img) {
            new imageLoupe(img);
        });
Ich habe Kommentare hinzu gefügt wo ich etwas geändert habe.
Glaube denen, die die Wahrheit suchen, und zweifle an denen, die sie gefunden haben.
(Andrι Gide (1869-1951), frz. Schriftst., 1947 Nobelpreis)
Zitieren
#5
Hallo Sempervivum,

Du bist ein Gott !!!!!!!!!! Genau das wollte ich haben, zwei Kleinigkeiten hab ich bei Deinem Source geändert:

this.originalImage.addEventListener('touchend', this.hideLoupe); ....hab ich raus genommen damit die Lupe dort stehen bleibt wo ich mit dem Finger die Touchfläche verlasse und nicht verschwindet

this.enlargedImage.style.transform = `scale(1) translate3d(${this.enlargedImageX}px, ${this.enlargedImageY}px, 0)`; ....scale(2) hab ich auf 1 geändert damit die Lupenfunktion nicht so gross ist und die Touch-Position am Originalimage genau ist, bei 2 wird das Originakimage doppelt so gross und die Touchposition passt nicht mehr. Die Lupenvergrösserung ist dadurch zwar nicht so gross passt bei mir aber besser.

Ich danke Dir 100000 mal, genau das wollte ich haben.
GlG
Oliver
Zitieren
#6
Hallo Oliver,
freut mich, dass es auch bei dir funktioniert.

Das mit dem scale war nur eine Notlösung von mir weil ich überhaupt keine Vergrößerung feststellen konnte. Möglicher Weise fehlte mir da noch etwas im CSS. Wenn Du den Faktor auf 1 setzt, kannst Du das scale auch weg lassen.

Vielleicht interessiert sich der Urheber auch für diese Erweiterung?

Beste Grüße, Ulrich
Glaube denen, die die Wahrheit suchen, und zweifle an denen, die sie gefunden haben.
(Andrι Gide (1869-1951), frz. Schriftst., 1947 Nobelpreis)
Zitieren
#7
Hallo Ulrich,

ich hab das scale mal weg gelassen und das funktioniert bei mir dann auch perfekt (hab es aber wieder mit scale(1) rein gegeben, dann kann ich das immer ändern wenn ich möchte ;-)). Warum das Vergrössern bei Dir nicht so geklappt hat mit scale(1) kann das an der Image-Grösse hängen. Bei mir ist es so das ich ein Image in einem DIV auf eine fixe Grösse setze, wenn diese Grösse gleich der Imagegrösse ist dann hab ich keine vergrösserung, ist das Image aber grösser als die grösse im DIV dann wird vergrössert, ist das Image kleiner als die Grösse des DIV dann wird das Image schon im DIV vergrössert, die Lupe verkleinert das Image dann. Man kann da dann ganz lustige Effekte erziehlen.

Ich gebe Deinen Code dem ursprünglichen Entwickler weiter, der freut sich sicher darüber dass das Teil weiter entwickelt wurde und Verwendung findet.

Danke Dir nochmals für Deine Bemühungen und Hilfe, Du hast mich richtig "glücklich" gemacht :-).

GlG
Oliver
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen:
2 Gast/Gäste