Last active
May 5, 2021 19:54
-
-
Save NickHatBoecker/84a8c8514b486370c1aece4b02c3ae7a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// src/components/Newsticker.vue | |
<script> | |
export default { | |
props: { | |
text: { type: String, required: true }, | |
}, | |
data: () => ({ | |
elementId: 'newsticker', | |
elementWrapperId: 'newstickerWrapper', | |
animationFrame: null, | |
boxWidth: 0, | |
resetPosition: null, | |
lastUpdate: null, | |
position: 0, | |
pixelPerUpdate: 2, // Pixelanzahl die der Text bei jedem Update verschoben wird | |
timeout: 20, // Millisekunden eher das nächste Update getriggert wird | |
paused: false, // Startet die Animation direkt beim Aufruf | |
}), | |
mounted () { | |
this.startAnimation() | |
}, | |
destroyed () { | |
// Wir entfernen hier den Listener, den wir im mounted Hook registriert haben. | |
// So stellen wir sicher, dass er bspw. bei einem Routen-Wechsel nicht weiter ausgeführt wird. | |
this.stopAnimation() | |
}, | |
methods: { | |
toggleAnimation () { | |
if (this.paused) { | |
this.startAnimation() | |
} else { | |
this.stopAnimation() | |
} | |
this.paused = !this.paused | |
}, | |
startAnimation () { | |
// Statt den bekannteren Funktionen "setTimeout" und "setInterval" nutzen wir hier "requestAnimationFrame". | |
// Diese Funktion stoppt automatisch wenn der Browser minimiert ist oder der Browser-Tab nicht im Fokus ist. | |
// Das schont CPU und Akku. | |
this.animationFrame = window.requestAnimationFrame(this.update) | |
}, | |
stopAnimation () { | |
window.cancelAnimationFrame(this.animationFrame) | |
}, | |
update () { | |
// Wenn die Animation vom User gestoppt wurde, brechen wir direkt aus. | |
if (this.paused) return | |
const now = Date.now() | |
if (this.lastUpdate && (now - this.lastUpdate) < this.timeout) { | |
// Wenn der timeout noch nicht erreicht wurde, wird der Text nicht verschoben. | |
// Wir müssen aber startAnimation() aufrufen um die Schleife weiterlaufen zu lassen. | |
this.startAnimation() | |
return | |
} | |
this.calculateStartAndResetPositions() | |
this.updatePosition() | |
// lastUpdate wird auf den aktuellen Timestamp gesetzt, damit wir ihm im nächsten Update überprüfen können | |
this.lastUpdate = now | |
// Mit startAnimation() starten wir den nächsten Schleifenvorgang. | |
this.startAnimation() | |
}, | |
/** | |
* [1] Der Text soll von rechts einlaufen. Wir setzen die Startposition also auf das rechte Ende des Wrappers. | |
* | |
* [2] Wenn der Text den linken Rand des Wrappers erreicht hat (Position 0), soll der Text | |
* zurück an die Startposition gesetzt werden. Dazu errechnen wir die Text-Breite und | |
* | |
* [3] setzen die errechnete resetPosition | |
*/ | |
calculateStartAndResetPositions () { | |
this.startPosition = this.$refs[this.elementWrapperId].offsetWidth // [1] | |
const textWidth = this.$refs[this.elementId].clientWidth // [2] | |
this.resetPosition = 0 - this.textWidth // [3] | |
}, | |
updatePosition () { | |
const currentPosition = this.getCurrentPosition() | |
let newPosition = `${currentPosition - this.pixelPerUpdate}px` | |
if (currentPosition <= this.resetPosition) { | |
// Der Text hat die in updateWidths errechnete End-Position erreicht. | |
// Also setzen wir ihn wieder an die Startposition. | |
newPosition = `${this.startPosition}px` | |
} | |
this.$refs[this.elementId].style.left = newPosition | |
}, | |
getCurrentPosition () { | |
let currentPosition = this.$refs[this.elementId].style.left | |
currentPosition = parseInt(currentPosition.replace('px', ''), 10) | |
if (!currentPosition) { | |
// currentPosition ist noch nicht gesetzt. Wir müssen also den Start festlegen. | |
currentPosition = this.startPosition | |
} | |
return currentPosition | |
}, | |
}, | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment