ng-cw-v12
Version:
Angular UI component library
130 lines (125 loc) • 7.46 kB
JavaScript
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