wordpress 中文文件名厦门建网站做优化
2026/3/26 22:00:33 网站建设 项目流程
wordpress 中文文件名,厦门建网站做优化,洛阳疾控最新通告今天,推广平台有哪些大的公司最近在搓一个Lyricify Lite类似物#xff0c;原本使用渐变画刷实现歌词高亮#xff0c;但是发现视觉效果与Apple Music相去甚远#xff1a;单纯使用白色渐变画刷缺乏“高亮”的光照感觉#xff0c;而Apple Music的歌词高亮则更像是有光线投射在歌词上#xff0c;形成一种柔…最近在搓一个Lyricify Lite类似物原本使用渐变画刷实现歌词高亮但是发现视觉效果与Apple Music相去甚远单纯使用白色渐变画刷缺乏“高亮”的光照感觉而Apple Music的歌词高亮则更像是有光线投射在歌词上形成一种柔和的发光效果。受到吕毅大佬的文章使用 WPF 做一个可以逼真地照亮你桌面的高性能阳光 - walterlv启发遂尝试使用HLSL编写一个简单的文本高亮着色器。先来看实装在LemonLite中的效果整体上高亮文本与背景混色自然渐变过渡由WPF动画驱动高亮部分就有了光感。以下是本文的最小可运行示例TwilightLemon/TextHighlighterTest: WPF 流光特效文本控件一、实现思路简单说一下踩过的几个坑直接给TextBlock焊上Effect会导致文本像素化变得模糊而且难以处理文本边界使用VisualBrush内部套一个Rectangle with Effect, 然后用这个VisualBrush作为TextBlock的Foreground性能极差给Rectangle with Effect做一个Clip裁剪出文本形状性能可以但是需要复刻TextBlock的排版逻辑最终使用了第三种方案并将其封装成一个用户控件。如此一来HLSL着色器要干的事情就很简单了取一个高亮过渡位置pos根据采样像素的X坐标计算光照强度然后将这个强度与文本颜色做加法混合即可。二、HLSL着色器代码为了适配歌词高亮需求我又追加了一些特性支持高亮颜色自定义支持高亮宽度调整支持切换高亮模式加法混合/线性渐变以下是完整的HLSL代码 咋没有hlsl高亮呢? sampler2D input : register(s0); float HighlightPos : register(c0); float HighlightWidth : register(c1); float4 HighlightColor : register(c2); float UseAdditive : register(c3); // 0 lerp, 1 additive float HighlightIntensity : register(c4); float4 main(float2 uv : TEXCOORD) : COLOR { float4 color tex2D(input, uv); float d max(0, uv.x - HighlightPos); float glow saturate(1 - d / HighlightWidth); glow glow * glow; float intensity glow * HighlightColor.a * HighlightIntensity; float3 lerpResult lerp(color.rgb, HighlightColor.rgb, intensity); float lerpAlpha lerp(color.a, 1.0, intensity); float3 additiveResult color.rgb HighlightColor.rgb * intensity; color.rgb lerp(lerpResult, additiveResult, UseAdditive); color.a lerp(lerpAlpha, color.a, UseAdditive); return color; }着色器输入参数参数作用/* by 01130.hk - online tools website : 01130.hk/zh/worldtime.html */ input输入纹理文本像素/* by 01130.hk - online tools website : 01130.hk/zh/worldtime.html */ HighlightPos高亮过渡位置0-1从左到右, 当然也可以取负数HighlightWidth高亮衰减宽度0-1HighlightColor高亮颜色含透明度UseAdditive混合模式开关0线性渐变1加法混合HighlightIntensity高亮强度倍数计算过程采样 → 读取当前像素颜色color tex2D(input, uv)计算距离 → 像素X坐标与高亮位置的距离d max(0, uv.x - HighlightPos)计算光晕强度 → 根据距离生成平滑衰减glow saturate(1 - d / HighlightWidth)glow glow * glow // 平方处理使衰减更陡峭最终强度 光晕 × 颜色透明度 × 强度倍数混合处理 → 根据UseAdditive选择混合方式线性渐变在原色和高亮色间插值加法混合直接叠加高亮色函数说明saturate(x)- 将值钳制在 [0, 1] 范围内step(edge, x)- 如果 x edge 返回 0否则返回 1lerp(a, b, t)- 线性插值计算 a (b-a)×ttex2D(sampler, uv)- 从纹理采样指定坐标的像素编译并加载着色器编译HLSL代码生成.ps文件然后在WPF中使用PixelShader类加载fxc /T ps_3_0 /E main /Fo TextGlow.psTextGlow.hlsl封装成Effect类此处不做赘述只需要严格按照参数顺序传递即可。三、WPF用户控件封装核心出装用一个Rectangle承载着色器效果通过FormattedText生成文本的几何形状作为裁剪路径这样WPF只会渲染文本区域并且保留清晰的文本边缘。属性继承与元数据覆写为了让高亮控件支持标准的文本属性字体、大小、粗细等使用了WPF的元数据覆写机制。在静态构造函数中对FontFamily、FontSize、FontWeight等属性进行OverrideMetadata绑定到统一的OnTextPropertyChanged回调。当这些属性变化时触发文本裁剪的重新计算。类似地Foreground属性也被覆写当文本颜色改变时直接更新Rectangle的填充颜色。1staticHighlightTextBlock()2{3FontFamilyProperty.OverrideMetadata(typeof(HighlightTextBlock),4newFrameworkPropertyMetadata(SystemFonts.MessageFontFamily, OnTextPropertyChanged));5FontSizeProperty.OverrideMetadata(typeof(HighlightTextBlock),6newFrameworkPropertyMetadata(14.0, OnTextPropertyChanged));7FontWeightProperty.OverrideMetadata(typeof(HighlightTextBlock),8newFrameworkPropertyMetadata(FontWeights.Normal, OnTextPropertyChanged));9ForegroundProperty.OverrideMetadata(typeof(HighlightTextBlock),10newFrameworkPropertyMetadata(Brushes.Black, OnForegroundChanged));11}1213privatestaticvoidOnForegroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)14{15if(disHighlightTextBlock control)16control.PART_Rectangle.Fill e.NewValueasBrush;17}这样用户就可以像使用普通TextBlock一样使用这个控件享受XAML的属性绑定和样式系统。文本排版与裁剪UpdateTextClip()方法负责创建排版对象 - 通过FormattedText将文本按照控件的字体、大小、样式参数进行排版获得与实际渲染完全一致的文本度量varformattedText newFormattedText( Text, CultureInfo.CurrentCulture, FlowDirection,newTypeface(FontFamily, FontStyle, FontWeight, FontStretch), FontSize, Brushes.Black, VisualTreeHelper.GetDpi(this).PixelsPerDip);处理换行与宽度约束 - 当启用TextWrapping时从Width、MaxWidth或ActualWidth中取出约束宽度。只有在需要换行且有约束宽度的情况下才设置MaxTextWidth让文本自动折行varconstraintWidth !double.IsNaN(Width) Width 0?Width : (!double.IsInfinity(MaxWidth) MaxWidth 0?MaxWidth : ActualWidth);if(TextWrapping ! TextWrapping.NoWrap constraintWidth 0) formattedText.MaxTextWidth constraintWidth;计算容器尺寸 - NoWrap下容器宽度就是文本宽度换行模式下则为约束宽度以确保Rectangle的大小与实际文本范围匹配varcontainerWidth TextWrapping TextWrapping.NoWrap?textWidth : (constraintWidth0? constraintWidth : textWidth);处理文本对齐 - 根据TextAlignment计算文本相对于容器的起始偏移用于居中和右对齐然后生成Rectangle时传入这个偏移量同时更新Rectangle的水平对齐属性使其与文本对齐方式一致doubleoffsetX 0;if(containerWidth textWidth) { offsetX TextAlignmentswitch{ TextAlignment.Center (containerWidth - textWidth) /2, TextAlignment.Right containerWidth -textWidth, _0}; }生成并应用裁剪 - 调用formattedText.BuildGeometry()得到精确的文本轮廓Rectangle设置为Rectangle.Clip。这样着色器的输出就被限制在文本像素范围内vargeometry formattedText.BuildGeometry(newPoint(offsetX,0)); PART_Rectangle.Clipgeometry; PART_Rectangle.WidthcontainerWidth; PART_Rectangle.Height textHeight;高亮参数的动画驱动高亮效果的三个关键参数HighlightPos、HighlightWidth、HighlightColor都被暴露为依赖属性在属性变化回调中直接同步到着色器 Effect 对象publicstaticreadonlyDependencyProperty HighlightPosProperty DependencyProperty.Register( nameof(HighlightPos),typeof(double),typeof(HighlightTextBlock),newPropertyMetadata(0.0, OnHighlightPosChanged));privatestaticvoidOnHighlightPosChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {if(disHighlightTextBlock c) c._effect.HighlightPos (double)e.NewValue; }这样就可以在XAML中轻松使用Storyboard和DoubleAnimation 驱动HighlightPos的平滑变化从而实现光线扫过文本的连贯动画效果。四、看看效果对比Additive叠加和Lerp线性渐变两种模式可以看到Additive模式下高亮部分更亮更有光感而Lerp模式尾段偏灰。尝试使用彩色高亮变成了混色效果。写在最后LemonLite正在龟速开发中过程中遇到的各种问题和解决方案都会陆续写成博客分享出来欢迎各位大佬持续关注。什么你问我开头的背景是怎么做的见上一篇文章WPF 使用GDI提取图片主色调并生成Mica材质特效背景 - Twlms Blog参考资料WPF 像素着色器入门使用 Shazzam Shader Editor 编写 HLSL 像素着色器代码 - walterlv使用 WPF 做一个可以逼真地照亮你桌面的高性能阳光 - walterlv本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布但务必保留文章署名TwilightLemon不得用于商业目的基于本文修改后的作品务必以相同的许可发布。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询