ng-cw-v12
Version:
Angular UI component library
204 lines (199 loc) • 9.99 kB
JavaScript
import * as i0 from '@angular/core';
import { Component, ViewChild, Input, HostListener, NgModule } from '@angular/core';
class AutoScrollTextComponent {
constructor() {
this.position = 0;
this.isPaused = false;
this.lastTimestamp = 0;
this.pauseStartTime = 0;
// 滚动文本
this._text = '';
// 滚动速度,单位为像素/秒
this.ncSpeed = 50;
// 是否开启无缝滚动
this._loop = false;
// 开启无缝滚动时,间距,单位为像素
this.ncGap = 0;
// 是否启用鼠标悬停暂停滚动
this._pause = false;
}
set ncText(val) {
this._text = val;
setTimeout(() => {
if (this.textContainer && this.scrollText) {
this.resetScroll();
}
});
}
get ncText() {
return this._text;
}
set ncLoop(val) {
this._loop = val !== null && val !== undefined && val !== false && val !== 'false';
}
get ncLoop() {
return this._loop;
}
set ncPause(val) {
this._pause = val !== null && val !== undefined && val !== false && val !== 'false';
}
get ncPause() {
return this._pause;
}
ngOnInit() { }
ngOnDestroy() {
if (this.animationId) {
cancelAnimationFrame(this.animationId);
}
}
// 鼠标移入事件处理
onMouseEnter() {
if (this.ncPause) {
this.isPaused = true;
this.pauseStartTime = performance.now();
}
}
// 鼠标移出事件处理
onMouseLeave() {
if (this.ncPause && this.isPaused) {
this.isPaused = false;
const pauseDuration = performance.now() - this.pauseStartTime;
this.lastTimestamp += pauseDuration;
}
}
startScrolling() {
// 检查文本是否需要滚动
if (!this.textContainer || !this.scrollText)
return;
const containerWidth = this.textContainer.nativeElement.offsetWidth;
const textWidth = this.scrollText.nativeElement.offsetWidth;
// 只有当文本宽度大于容器宽度时才滚动
if (textWidth > containerWidth) {
this.lastTimestamp = 0;
const animate = (timestamp) => {
if (!this.lastTimestamp)
this.lastTimestamp = timestamp;
// 当不处于暂停状态时才计算位移
if (!this.isPaused) {
const elapsed = timestamp - this.lastTimestamp;
// 根据时间和速度计算位移
this.position += (elapsed / 1000) * this.ncSpeed;
// 当文本的最后一个字符出现在视窗内时创建复制文本实现无缝衔接
if (this.position >= textWidth - containerWidth) {
if (this.ncLoop) {
// 让文本平滑地重新开始滚动,而不是突然跳回开始位置
// 将第二份文本复制品拼接在原文本后面,实现无缝衔接效果
if (!this.scrollText.nativeElement.querySelector('.duplicate-text')) {
const duplicateText = document.createElement('span');
duplicateText.classList.add('duplicate-text');
duplicateText.textContent = this.ncText;
duplicateText.style.marginLeft = `${this.ncGap}px`;
this.scrollText.nativeElement.appendChild(duplicateText);
}
}
else {
// 不开启无缝滚动时,当文本的最后一个字符出现在视窗内时重新开始
this.position = 0;
}
}
// 实现真正的无缝滚动:当滚动位置超过第一段文本宽度时,重置位置并保持视觉连续
if (this.ncLoop && this.position >= textWidth + this.ncGap) {
// 重置位置,但保持视觉效果不变
this.position = 0;
// 移除复制的文本元素
const duplicateText = this.scrollText.nativeElement.querySelector('.duplicate-text');
if (duplicateText) {
this.scrollText.nativeElement.removeChild(duplicateText);
}
// 立即重新设置transform,避免闪烁
this.scrollText.nativeElement.style.transform = 'translateX(0)';
// 立即创建新的复制文本
const newDuplicateText = document.createElement('span');
newDuplicateText.classList.add('duplicate-text');
newDuplicateText.textContent = this.ncText;
newDuplicateText.style.marginLeft = `${this.ncGap}px`;
this.scrollText.nativeElement.appendChild(newDuplicateText);
}
else {
// 应用位移
this.scrollText.nativeElement.style.transform = `translateX(-${this.position}px)`;
}
// 更新时间戳
this.lastTimestamp = timestamp;
}
this.animationId = requestAnimationFrame(animate);
};
this.animationId = requestAnimationFrame(animate);
}
}
resetScroll() {
if (this.animationId) {
cancelAnimationFrame(this.animationId);
}
this.position = 0;
this.isPaused = false;
if (this.scrollText) {
this.scrollText.nativeElement.style.transform = 'translateX(0)';
// 清除可能存在的重复文本
const duplicateText = this.scrollText.nativeElement.querySelector('.duplicate-text');
if (duplicateText) {
this.scrollText.nativeElement.removeChild(duplicateText);
}
}
this.startScrolling();
}
}
AutoScrollTextComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: AutoScrollTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
AutoScrollTextComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: AutoScrollTextComponent, selector: "nc-auto-scroll-text", inputs: { ncText: "ncText", ncSpeed: "ncSpeed", ncLoop: "ncLoop", ncGap: "ncGap", ncPause: "ncPause" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" } }, viewQueries: [{ propertyName: "textContainer", first: true, predicate: ["textContainer"], descendants: true }, { propertyName: "scrollText", first: true, predicate: ["scrollText"], descendants: true }], ngImport: i0, template: "<div class=\"auto-scroll-container\" #textContainer>\r\n <div class=\"scroll-text\" #scrollText>\r\n <span>{{ ncText }}</span>\r\n </div>\r\n</div>\r\n", styles: [".auto-scroll-container{width:100%;overflow:hidden;white-space:nowrap;position:relative}.scroll-text{display:inline-block;white-space:nowrap}\n"] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: AutoScrollTextComponent, decorators: [{
type: Component,
args: [{
selector: 'nc-auto-scroll-text',
templateUrl: './auto-scroll-text.component.html',
styleUrls: ['./auto-scroll-text.component.less']
}]
}], ctorParameters: function () { return []; }, propDecorators: { textContainer: [{
type: ViewChild,
args: ['textContainer']
}], scrollText: [{
type: ViewChild,
args: ['scrollText']
}], ncText: [{
type: Input
}], ncSpeed: [{
type: Input
}], ncLoop: [{
type: Input
}], ncGap: [{
type: Input
}], ncPause: [{
type: Input
}], onMouseEnter: [{
type: HostListener,
args: ['mouseenter']
}], onMouseLeave: [{
type: HostListener,
args: ['mouseleave']
}] } });
class NcAutoScrollTextModule {
}
NcAutoScrollTextModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcAutoScrollTextModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
NcAutoScrollTextModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcAutoScrollTextModule, declarations: [AutoScrollTextComponent], exports: [AutoScrollTextComponent] });
NcAutoScrollTextModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcAutoScrollTextModule, imports: [[]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcAutoScrollTextModule, decorators: [{
type: NgModule,
args: [{
declarations: [
AutoScrollTextComponent
],
imports: [],
exports: [
AutoScrollTextComponent
]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { AutoScrollTextComponent, NcAutoScrollTextModule };
//# sourceMappingURL=ng-cw-v12-auto-scroll-text.js.map