UNPKG

ng-cw-v12

Version:

Angular UI component library

130 lines (125 loc) 7.46 kB
import * as i0 from '@angular/core'; import { Component, Input, ViewChild, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; class VideoTextComponent { constructor() { /** 展示的文本内容 */ this._text = ''; this.ncSrc = ''; this.dimensions = { width: 0, height: 0 }; this.isReady = false; this.textStyle = {}; this.maskId = `aurora-mask-${Math.random().toString(36).substring(2, 11)}`; } set ncText(value) { this._text = value; setTimeout(() => { this.start(); }); } get ncText() { return this._text; } ngOnInit() { } start() { this.computeTextStyles(); this.updateDimensions(); } computeTextStyles() { var _a; if ((_a = this.textContentRef) === null || _a === void 0 ? void 0 : _a.nativeElement) { const computedStyle = getComputedStyle(this.textContentRef.nativeElement); this.textStyle = this.extractTextStyles(computedStyle); } } updateDimensions() { var _a; if ((_a = this.svgTextRef) === null || _a === void 0 ? void 0 : _a.nativeElement) { try { const bbox = this.svgTextRef.nativeElement.getBBox(); this.dimensions = { width: Math.max(1, bbox.width), height: Math.max(1, bbox.height) }; this.isReady = true; } catch (e) { console.error('获取 SVG 元素尺寸时出错:', e); } } } getStyleString() { let styleStr = ''; for (const [key, value] of Object.entries(this.textStyle)) { if (value) { // 将驼峰命名转换为连字符命名 const cssKey = key.replace(/([A-Z])/g, '-$1').toLowerCase(); styleStr += `${cssKey}:${value};`; } } return styleStr; } // 提取文本相关样式的辅助方法 extractTextStyles(computedStyle) { return { fontSize: computedStyle.fontSize, fontFamily: computedStyle.fontFamily, fontWeight: computedStyle.fontWeight, fontStyle: computedStyle.fontStyle, letterSpacing: computedStyle.letterSpacing, lineHeight: computedStyle.lineHeight, textTransform: computedStyle.textTransform, fontVariant: computedStyle.fontVariant, fontStretch: computedStyle.fontStretch, fontFeatureSettings: computedStyle.fontFeatureSettings, textDecoration: computedStyle.textDecoration, textShadow: computedStyle.textShadow, }; } } VideoTextComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: VideoTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); VideoTextComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: VideoTextComponent, selector: "nc-video-text", inputs: { ncText: "ncText", ncSrc: "ncSrc" }, viewQueries: [{ propertyName: "textContentRef", first: true, predicate: ["textContent"], descendants: true }, { propertyName: "svgTextRef", first: true, predicate: ["svgText"], descendants: true }], ngImport: i0, template: "<span class=\"video-text relative inline-block align-middle\"\r\n [style.width]=\"dimensions.width ? dimensions.width + 'px' : 'auto'\"\r\n [style.height]=\"dimensions.height ? dimensions.height + 'px' : 'auto'\">\r\n\r\n <!-- \u9690\u85CF\u7684\u6587\u672C\u7528\u4E8ESEO -->\r\n <span class=\"sr-only\">\r\n {{ncText}}\r\n </span>\r\n\r\n <!-- \u89C6\u89C9\u5360\u4F4D\u7B26 -->\r\n <span #textContent style=\"opacity: 0;display: inline-block; white-space: nowrap;\"\r\n [style.position]=\"isReady ? 'absolute' : 'relative'\" aria-hidden=\"true\">\r\n {{ncText}}\r\n </span>\r\n\r\n <div class=\"absolute inset-0\" [style.opacity]=\"isReady ? 1 : 0\" style=\"transition: opacity 0.2s ease-in;\"\r\n aria-hidden=\"true\">\r\n\r\n <svg [attr.width]=\"dimensions.width\" [attr.height]=\"dimensions.height\" class=\"absolute inset-0\">\r\n <defs>\r\n <clipPath [attr.id]=\"maskId\">\r\n <text #svgText x=\"50%\" y=\"50%\" dominant-baseline=\"middle\" text-anchor=\"middle\"\r\n [attr.style]=\"getStyleString()\">{{ncText}}</text>\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n\r\n <video class=\"w-full h-full object-cover\" preload=\"auto\" autoPlay muted loop [style.clip-path]=\"'url(#' + maskId + ')'\"\r\n [style.-webkit-clip-path]=\"'url(#' + maskId + ')'\">\r\n <source [src]=\"ncSrc\">\r\n \u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u89C6\u9891\u6807\u7B7E\u3002\r\n </video>\r\n </div>\r\n</span>", styles: [":host{display:inline-block}.relative{position:relative}.absolute{position:absolute}.inset-0{top:0;right:0;bottom:0;left:0}.inline-block{display:inline-block}.align-middle{vertical-align:middle}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.h-full{height:100%}.w-full{width:100%}.object-cover{object-fit:cover}\n"] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: VideoTextComponent, decorators: [{ type: Component, args: [{ selector: 'nc-video-text', templateUrl: './video-text.component.html', styleUrls: ['./video-text.component.less'] }] }], ctorParameters: function () { return []; }, propDecorators: { ncText: [{ type: Input }], ncSrc: [{ type: Input }], textContentRef: [{ type: ViewChild, args: ['textContent'] }], svgTextRef: [{ type: ViewChild, args: ['svgText'] }] } }); class NcVideoTextModule { } NcVideoTextModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcVideoTextModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); NcVideoTextModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcVideoTextModule, declarations: [VideoTextComponent], imports: [CommonModule], exports: [VideoTextComponent] }); NcVideoTextModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcVideoTextModule, imports: [[ CommonModule ]] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcVideoTextModule, decorators: [{ type: NgModule, args: [{ declarations: [ VideoTextComponent ], imports: [ CommonModule ], exports: [ VideoTextComponent ] }] }] }); /** * Generated bundle index. Do not edit. */ export { NcVideoTextModule, VideoTextComponent }; //# sourceMappingURL=ng-cw-v12-video-text.js.map