当前位置: 首页 > news >正文

如何用低代码的思路设计文字描边渐变组件

前言

文字特效设计一直是困扰 Web 前端 Css 世界多年的问题, 比如如何用纯 Css 实现文字描边, 渐变, 阴影等, 由于受限于浏览器兼容性的问题, 我们不得不使用其他替代方案来实现.

平时工作中我们使用 PS 等设计工具能很容易的实现文字渐变等特效, 但是随着可视化技术的成熟, 我们需要把传统软件的能力移植到 web 端, 让用户在 Web 端也能有和桌面软件一样的体验效果, 那么我们就需要想一套优雅的方案了, 接下来我会从文本特效的

  • 描边

  • 阴影

  • 渐变

这3个纬度来和大家分享一下用前端实现的解决方案, 并提供一种可复用的文本组件设计方案, 让大家更容易的来是使用文字特效.

你将收获

  • 文字渐变, 阴影, 描边的3种方案实现

  • 组件设计的一些通用方法和原则

  • 如果在低代码平台中优雅的设计功能强大的文字组件

  • 技术脑洞

正文

先来介绍一下文字描边和阴影的设计方案.

文字描边的2种css方案

  1. css3text-stroke

我们可以使用如下样式来实现简单的描边效果:

-webkit-text-stroke: 1px #000000;

在w3c上演示的效果如下:

d652e2808c3d839314de5ee5e099e413.png

但是缺点就是兼容性不是特别好, 如果不考虑太多浏览器的兼容问题, 大家可以直接用这种方案.

  1. 使用text-shadow 模仿描边效果

使用此方案有点就是兼容性好, 不需要加浏览器前缀,  方案如下:

.text-shadow {text-shadow: #000 1px 0 0, #000 0 1px 0, #000 -1px 0 0, #000 0 -1px 0;color: #fff;
}

显示效果:

f2e6f340e651365134b6071cc26696fd.png

刚才介绍的文字描边引用了阴影来实现,  自然我们要想实现文字阴影, 可以直接使用text-shadow, 并且我们可以实现多种阴影的效果, 甚至能用它实现3D文字效果(并不建议这么做, 性能有待考量)

32bae912349d0c9a5a513e3c1515b0d3.png

实现文字渐变的3种方案

文字渐变css3也提供了对应的特性, 但是兼容性并不是很好, 目前还不推荐使用, 有如下2种方案:

// 方案1. 背景裁切+背景渐变实现
{background-image: -webkit-gradient(linear, left center, right center, from(blue), to(red)); /* 背景色渐变 */-webkit-background-clip: text;  /* 设置背景的显示区域 */-webkit-text-fill-color: transparent; /* 避免字体颜色覆盖 */
}// 方案2: mask
{-webkit-mask-image: -webkit-gradient(linear, 0 0, 0 bottom, from(red), to(blue));
}

效果如下:

25c7c76d0bfd2b13256c6c3797245ae3.png

根据笔者的实验, 更推荐用另一种兼容性更好的方案—— svg.

接下来我们看看使用svg实现文字渐变的效果.

a07b07f6b8aea99f6d41b70691a520d1.png

具体实现方案大家需要具备一点的 svg 基础知识,  这里给大家分享一下我的实现代码:

<svg style={{width: '100%',textShadow: `${shadow[1]}px ${shadow[0]}px ${shadowSize}px`,
}}><defs><linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" style={{'stopColor': upColor, 'stopOpacity': 1}} /><stop offset="100%" style={{'stopColor': backColor, 'stopOpacity':1}} /></linearGradient></defs><text x={pos[1]} y={pos[0]} fill="url(#grad)" style={{fontSize, textAnchor: 'start'}}>Dooring文字渐变效果</text>
</svg>

以上代码中upColor(前景色), backColor(背景色), 我们可以动态配置, 同时我们还可以改变渐变的方向, 通过linearGradient 标签的xy属性. 大家感兴趣的可以私下研究一下.

通过这种方案, 我们就能实现展现能力非常强的文字特效了. 接下来我会分享一下如何用组件化或者低代码的思路, 将文字特效封装成一个高可复用的组件.

如果优雅的设计功能强大的文字组件

在介绍组件设计思路之前,有必要介绍一下著名的SOLID原则.

SOLID(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)是由罗伯特·C·马丁提出的面向对象编程和面向对象设计的五个基本原则。利用这些原则,程序员能更容易和高效的开发一个可维护和扩展的系统。 SOLID被典型的应用在测试驱动开发上,并且是敏捷开发以及自适应软件开发的基本原则的重要组成部分。

  • S 单一功能原则: 规定每个类都应该有一个单一的功能,并且该功能应该由这个类完全封装起来。所有它的服务都应该严密的和该功能保持一致。

  • O 开闭原则: 规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。遵循这种原则的代码在扩展时并不需要改变。

  • L 里氏替换原则: 派生类(子类)对象可以在程序中代替其基类(超类)对象,是对子类型的特别定义.

  • I 接口隔离原则: 指明应用或者对象应该不依赖于它不使用的方法。接口隔离原则(ISP)拆分非常庞大臃肿的接口成为更小的和更具体的接口,这样应用或对象只需要知道它们感兴趣的方法。这种缩小的接口也被称为角色接口。接口隔离原则(ISP)的目的是系统去耦合,从而容易重构,更改和重新部署。接口隔离原则是在SOLID (面向对象设计)中五个面向对象设计(OOD)的原则之一,类似于在GRASP (面向对象设计)中的高内聚性。

  • D 依赖反转原则: 是指一种特定的解耦 形式,使得高层次的模块不依赖于低层次的模块的实现细节,依赖关系被颠倒(反转),从而使得低层次模块依赖于高层次模块的需求抽象。

掌握好这5个原则将有利于我们开发出更优秀的组件,请默默记住.接下来我们来看看文字特效组件的设计思路.

30d23b8ac12a63c83dd626eabe5bd3ea.png

以上组件设计是结合 组件化 + 低代码 的开发思路设计的, 组件化帮助我们将业务实现封装地更易用, 低代码的思路让我们将组件和业务结合起来, 通过一种更系统的思维来设计组件.

具体在组件场景的用法如下:

<Text fontSize={14} fontFamily=宋体"pos ={[0, 20]}animation="fade in"
>文字渐变
</Text>

这种方式可以更好的让前端工程师无需关注底层实现直接使用复杂功能, 更近一步地考虑, 如果要让组件通过零代码的方式拖拽配置生成, 我们就需要考虑更多系统性的问题, 比如组件的Schema定义, 系统交互事件如何配置, 如何通过属性配置面板来实现组件样式的搭建.

目前我在Dooring零代码平台中的实现方式是对组件配置项设计一套DSL结构, 通过DSL来动态渲染配置项:

const Chart: ChartSchema = {// 配置项列表editAttrs: [{key: 'layerName',type: 'Text',cate: 'base',},{key: 'y',type: 'Number',cate: 'base',},...DataConfig, // 数据配置项...eventConfig, // 事件配置项],// 组件默认属性config: {width: 200,height: 200,zIndex: 1,layerName: '柱状图',labelColor: 'rgba(188,200,212,1)',// ... 其他配置初始值multiColor: ['rgba(91, 143, 249, 1)', 'rgba(91, 143, 249, 1)', 'rgba(91, 143, 249,,1)', 'rgba(91, 143, 249, 1)'],data: [{name: 'A',value: 25,},{name: 'B',value: 66,}],},
}

我们通过遍历  editAttrs 结构就可以得到一个属性配置面板:

13e54929220c305ba79926e7420bbf26.png

按照这样的思路, 我们实现一个兼容低代码平台的文字特效组件结构可能长这样:

import React, { memo, useState, useRef, useEffect } from 'react'
import { ITextConfig } from './schema';
import { cpClick, isEditorPage } from '@/utils/cpTool';
import ani from '../animate.css';
import classnames from 'classnames';const TextCp = memo((props: ITextConfig) => {const { cpName,text, fontSize,fontFamily,pos = [0, 20],dir,bgColor, padding, radius,animation,animationTurn,delay,interaction = {}, // ...} = props;const { type, content } = interaction;const [visible, setVisible] = useState(false);const [isEditable, setEditable] = useState(false);const textRef = useRef<any>(null);const [data, setData] = useState<string>('');const handleClick = () => {cpClick(type, content, () => {setVisible(true)})}const handleDoubleClick = () => {if(!isEditorPage()) {return}setEditable(true);setTimeout(() => {textRef.current.focus();textRef.current.value = text;}, 30)}const handleSaveText = () => {window.handleTextUpdate(textRef.current.value)setEditable(false)}// 数据源...const direction = dir === 'hor' ? {x1: "0%", y1: "0%", x2: "100%", y2:"0%"} : {x1: "0%", y1: "0%", x2: "0%", y2:"100%"}return (<><div className={classnames('dooring-text', animation !== 'none' && ani[`animate__${animation}`])}style={{ fontSize: _gaw(fontSize), fontFamily,fontWeight: +fontWeight,backgroundColor: bgColor,padding,borderRadius: radius,animationIterationCount: animationTurn,animationDelay: delay + 's',letterSpacing: space + 'px',}} onClick={handleClick} onDoubleClick={handleDoubleClick}><svg style={{width: '100%',textShadow: `${shadow[1]}px ${shadow[0]}px ${shadowSize}px`,}}><defs><linearGradient id="grad" {...direction}><stop offset="0%" style={{'stopColor': upColor, 'stopOpacity': 1}} /><stop offset="100%" style={{'stopColor': backColor, 'stopOpacity':1}} /></linearGradient></defs><text x={pos[1]} y={pos[0]} fill="url(#grad)" style={{fontSize, textAnchor: 'start'}}>{ addSpaceEntity(data || text) }</text></svg>{ isEditable && <input ref={textRef} style={{border: 'none',position: 'absolute',top: 0,left: 0,fontSize,fontFamily,width: '100%',height: '100%',textAlign: 'left',color: 'rgba(60,60,60,1)'}} onBlur={handleSaveText} />}</div></>);
});
export default TextCp;

这样我们既可以单独使用组件, 也可以在Dooring零代码平台中通过拖拽的方式更简单地使用组件了.

最后

我们可以通过上面介绍的方式将任何已有组件包装的更扩展, 组件的开发结构变成了:

  • schema(DSL定义)

  • index(组件实现)

这样设计之后组件会有更好的可移植性和扩展性, 当然未来webcompoent更加成熟稳定了, 我们可以通过更健壮的模式来设计组件. 后续我也会持续分享可视化低代码相关的技术实现, 欢迎大家随时和我交流.

更多推荐

  • (10月最新) 前端图形学实战: 从零开发几何画板(vue3 + vite版)

  • 从零开发一款可视化大屏制作平台

  • 如何设计可视化搭建平台的组件商店?

  • Dooring无代码搭建平台技术演进之路

相关文章:

如何用低代码的思路设计文字描边渐变组件

前言 文字特效设计一直是困扰 Web 前端 Css 世界多年的问题, 比如如何用纯 Css 实现文字描边, 渐变, 阴影等, 由于受限于浏览器兼容性的问题, 我们不得不使用其他替代方案来实现. 平时工作中我们使用 PS 等设计工具能很容易的实现文字渐变等特效, 但是随着可视化技术的成熟, 我…...

Linux 网络通信

(一)套接字Socket概念 Socket 中文意思是“插座”&#xff0c;在 Linux 环境下&#xff0c;用于表示进程 x 间网络通信的特殊文件 类型。本质为内核借助缓冲区形成的伪文件。 既然是文件&#xff0c;那么理所当然的&#xff0c;我们可以使用文件描述符引用套接字。Linux 系统…...

借力互联网,民营医院探索互联网医疗服务的发展方向

民营医院互联网医疗服务是指利用互联网技术和平台&#xff0c;为患者提供更加便捷、高效的医疗服务。在当前数字化时代&#xff0c;互联网医疗服务正逐渐成为医疗行业的新趋势&#xff0c;也为民营医院开拓了更广阔的发展空间。下面将围绕这一主题进行讨论&#xff1a; 首先&a…...

office tool plus工具破解word、visio等软件步骤

第一步&#xff1a;下载工具 破解需要用到office tool plus软件 office tool plus软件下载地址&#xff1a;Office Tool Plus 官方网站 - 一键部署 Office 选择其中一个下载到本地&#xff08;本人选择的是第一个的云图小镇下载方式&#xff09; 第二步&#xff1a;启动工具 …...

python之pyqt专栏5-信号与槽1

在上一篇文章&#xff0c;我们了解到如果想要用代码改变QLabel的文本内容&#xff0c;可以调用QLabel类的text()函数。 但是现在有个这样的需求&#xff0c;界面中有一个Button与一个Label&#xff0c;当点击Button时&#xff0c;将Label的内容改变为“Hello world&#xff01;…...

【JMeter】不同场景下的接口请求

场景1: 上传文件接口即Content-Type=multipart/form-data 步骤: 1. 接口url,method以及path正常填写 2.文件上传content-type是multipart/form-data,所以可以勾选【use multipart/form-data】,如果还有其他请求头信息可以添加一个请求头元件 3.请求参…...

十八数字文化受邀参加版博会“区块链+版权”创新应用试点研讨会

2023年11月23日至25日&#xff0c;以“版权新时代 赋能新发展”为主题的第九届中国国际版权博览会在成都市中国西部国际博览城和天府国际会议中心举办。版博会是我国版权领域唯一的综合性、国际性、国家级版权专业博览会&#xff0c;本届版博会由国家版权局主办&#xff0c;四川…...

Centos 7 离线安装(tar) NodeJS 16 和 Vue

目录 一、下载Nodejs二、安装Nodejs2.1、创建安装目录2.2、上传安装包(无网络) or 直接下载(有网络)2.3、解压缩2.4、配置环境变量2.5、创建软连接2.6、更换镜像源2.7、验证是否安装成功 三、安装Vue四、卸载Nodejs 一、下载Nodejs Nodejs&#xff1a;https://nodejs.org/en/ …...

卸载软件最最最彻底的工具——Uninstall Tool

卸载软件最最最彻底的工具——Uninstall Tool Uninstall Tool 是一款功能强大的专业卸载工具。针对一些普通卸载不彻底的问题&#xff0c;它可以做到最优&#xff0c;比如Matlab等软件的卸载难的问题也可以较好地解决。 它比 Windows 自带的“添加/删除程序”功能快 3 倍&…...

2022年MathorCup大数据竞赛B题北京移动用户体验影响因素研究求解全过程文档及程序

2022年MathorCup高校数学建模挑战赛—大数据竞赛 B题 北京移动用户体验影响因素研究 原题再现&#xff1a; 移动通信技术飞速发展&#xff0c;给人们带来了极大便利&#xff0c;人们也越来越离不开移动通信技术带来的各种便捷。随着网络不断的建设&#xff0c;网络覆盖越来越…...

C#,《小白学程序》第二十课:大数的加法(BigInteger Add)

大数的&#xff08;加减乘除&#xff09;四则运算、阶乘运算。 乘法计算包括小学生算法、Karatsuba和Toom-Cook3算法。 重复了部分 19 课的代码。 1 文本格式 using System; using System.Linq; using System.Text; using System.Collections.Generic; /// <summary>…...

通用功能——git 攻略

摘要 本文主要介绍git常用命令的使用方法&#xff0c;同时介绍一些常见问题的处理方法&#xff0c;持续更新中… git命令通用选项 大多数git命令都适用的选项列表如下&#xff1a; -v, --verbose show hash and subject, give twice for upstream branch -q, --quie…...

LemMinX-Maven:帮助在eclipse中更方便地编辑maven的pom文件

LemMinX-Maven&#xff1a;https://github.com/eclipse/lemminx-maven LemMinX-Maven可以帮助我们在eclipse中更方便地编辑maven工程的pom.xml文件&#xff0c;例如补全、提示等。不用单独安装&#xff0c;因为在安装maven eclipse插件的时候已经自动安装了&#xff1a; 例…...

CAD与 PDM系统如何协同工作的?

在产品研发中&#xff0c;CAD&#xff08;计算机辅助设计&#xff09;和PDM&#xff08;产品数据管理&#xff09;是两个核心的工具&#xff0c;它们在产品从设计到制造的整个生命周期中发挥着重要的作用。虽然这两个工具在功能上有所不同&#xff0c;但它们在使用上却有着密切…...

vue-历史模式部署

项目部署 本项目采用nginx进行部署&#xff0c;历史模式的部署需要服务端的配合&#xff0c;本次采用nginx进行配合。 1 配置 const basePath process.env.VUE_APP_BASE_PATH; module.exports {publicPath: basePath #静态资源的路径 /ecology/ }2 创建路由 const createR…...

『Linux升级路』基础开发工具——make/Makefile

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;Linux &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、认识make/Makefile &#x1f4d2;1.1make/Makefile的优点 &#x1f4d2;…...

Python开发技能实战-如何在Visio中添加和删除任意连接点?

问题 在学习或者工作中&#xff0c;我们经常会借助Visio这个软件绘制流程图&#xff0c;在Visio中一般连接点是固定的&#xff0c;固定的连接点只能绘制一条连接线&#xff0c;如下图所示&#xff1a; 但有时候我们需要在两个方框之间绘制双向连接线&#xff0c;达到以下的效果…...

中科驭数受邀出席2023 ODCC冬季全会,共谋开放数据中心创新发展

近日&#xff0c;2023年开放数据中心委员会&#xff08;简称“ODCC”&#xff09;冬季全会在宁夏银川成功召开&#xff0c;中科驭数作为ODCC的新成员单位&#xff0c;受邀出席本次重要会议。 ▲ 中科驭数正式加入ODCC开放数据中心委员会 开放数据中心委员会是在中国通信标准化…...

Leetcode—907.子数组的最小值之和【中等】

2023每日刷题&#xff08;四十二&#xff09; Leetcode—907.子数组的最小值之和 算法思想 参考自y神思想 实现代码 class Solution { public:int sumSubarrayMins(vector<int>& arr) {long long ans 0;const int mod 1e97;int n arr.size();stack<int>…...

下载文件并重命名

//下载文件并重命名 // 无需数字化归档模版下载 function nodigitalMeth(){ let filenameunescape("/projectapp/ghsjy/template/noNeedDigital.docx")//原文件为英文名字 downloadFileRename(filename,"无需成果数据汇交模版") } // 需要数字化归档模版下…...

中小企业福音:Qwen3-14B私有化部署全流程,轻松搞定智能客服与文档处理

中小企业福音&#xff1a;Qwen3-14B私有化部署全流程&#xff0c;轻松搞定智能客服与文档处理 1. 为什么选择Qwen3-14B 对于中小企业来说&#xff0c;部署AI模型往往面临两难选择&#xff1a;公有云API担心数据安全&#xff0c;自研模型又缺乏技术实力。Qwen3-14B正好填补了这…...

Simple Live:跨平台直播聚合终极指南,告别多App切换烦恼

Simple Live&#xff1a;跨平台直播聚合终极指南&#xff0c;告别多App切换烦恼 【免费下载链接】dart_simple_live 简简单单的看直播 项目地址: https://gitcode.com/GitHub_Trending/da/dart_simple_live 还在为看直播需要安装多个App而烦恼吗&#xff1f;Simple Live…...

Kiro IDE + AIClient-2-API 实现Openclaw或者Claude code使用Claude Opus 4.6模型

前言&#xff1a;在AI辅助编程领域&#xff0c;Claude Opus 4.6 凭借强大的代码理解、生成和调试能力&#xff0c;成为很多开发者的首选模型。但直接使用 Anthropic 官方 API 不仅计费昂贵&#xff0c;额度也容易受限。本文将详细讲解如何通过「Kiro IDE AIClient-2-API Clau…...

突破硬件限制的开源游戏串流方案:Sunshine跨设备游戏体验指南

突破硬件限制的开源游戏串流方案&#xff1a;Sunshine跨设备游戏体验指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 当你拥有一台高性能游戏PC&#xff0c;却只能在固定位置享…...

7步效率革命:设计批量处理驱动的智能工作流

7步效率革命&#xff1a;设计批量处理驱动的智能工作流 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 副标题&#xff1a;告别重复劳动的设计自动化方案 在现代设计工作流中&…...

**发散创新:Go语言中分片(Slice)的高级用法与实战技巧**在Go语言编程中,**slice(分片)** 是最常用

发散创新&#xff1a;Go语言中分片&#xff08;Slice&#xff09;的高级用法与实战技巧 在Go语言编程中&#xff0c;slice&#xff08;分片&#xff09; 是最常用、最灵活的数据结构之一。它不仅是数组的“智能包装器”&#xff0c;更是高效内存管理和性能优化的核心工具。本文…...

零基础入门Speech Seaco Paraformer:一键部署中文语音识别Web界面

零基础入门Speech Seaco Paraformer&#xff1a;一键部署中文语音识别Web界面 1. 语音识别技术简介 语音识别技术&#xff08;Automatic Speech Recognition, ASR&#xff09;正在改变我们与设备交互的方式。想象一下&#xff0c;你只需要对着电脑说话&#xff0c;它就能自动…...

双馈风力发电机DFIG滑模控制SMC MATLAB/Simulink仿真模型(成品) 1、采用...

双馈风力发电机DFIG滑模控制SMC MATLAB/Simulink仿真模型&#xff08;成品&#xff09; 1、采用非线性控制滑模控制策略 2、采用PI调节器为外环滑模控制器SMC作为内环控制&#xff0c;跟传统的双PI环相比&#xff0c;功率的很随性更好&#xff08;创新点&#xff09;双馈风机滑…...

Krita智能选区插件:AI驱动的图像分割解决方案

Krita智能选区插件&#xff1a;AI驱动的图像分割解决方案 【免费下载链接】krita-vision-tools Krita plugin which adds selection tools to mask objects with a single click, or by drawing a bounding box. 项目地址: https://gitcode.com/gh_mirrors/kr/krita-vision-t…...

【VirtualBox】Vbox 7.2.6 不让安装在其他盘?这篇保姆级权限修复指南让你 D 盘起飞

在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。 而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。 【VirtualBox】Vbox 7.2.6 不让安装在其他盘?这篇保姆级权限修复指南让你 D 盘起飞…...