目录
前言
上一篇博文中,我们扩充了线条对象(fabric.Line)的属性列表,使用户可以为画布中选中的线条增加或修改端点样式(多种剪头、圆形、菱形等)。
这篇博文是《前端canvas项目实战——简历制作网站》付费专栏系列博文的第五篇——右侧属性栏(字体、字号、行间距),主要的内容有:
- 针对文本框(fabric.Textbox)对象: 扩充属性列表,使用户可以修改画布中选中的文本框的字体、字号和行间距。
- 在实现了整体更新文本框属性的基础上,还实现了仅更新用户选中的部分文字的样式。
如有需要,你可以:
- 点击这里,返回第一篇《前端canvas项目实战——简历制作网站(一)——左侧工具栏》
- 点击这里,返回上一篇《前端canvas项目实战——简历制作网站(四)——右侧属性栏(线条端点样式)》
- 点击这里,前往下一篇《前端canvas项目实战——简历制作网站(六)——加粗、斜体、下划线、删除线(上)》
一、效果展示
动手体验 CodeSandbox会自动对代码进行编译,并提供地址以供体验代码效果 由于CSDN的链接跳转有问题,会导致页面无法工作,请复制以下链接在浏览器打开: https://cy37vt.csb.app/
动态效果演示
本节之后,我们的简历能做成什么样子 我们可以修改字体、字号和行间距了
二、实现步骤
作为简历,其中包含最多的就是文字。因此,文字的各种样式至关重要,我们在本节初步实现字体、字号和行间距的编辑能力。
1. 优化代码,提取常量
当我们实现越来越多的编辑模块时,
object-props.js
文件越来越大。其中包含了很多我们为下拉菜单的菜单项设置的常量,这些常量不需要经常修改,但占据了很多行。为了避免这个文件过于庞大,以及做好
Modal
和
View
的分离,我们将这些数据拆分到一个
constants.js
常量文件中。
const fontFamilyOptions =[{key:"黑体",value:"SimHei",platform:"windows"},{key:"黑体",value:"STHeitiSC-Light",platform:"mac"},..."Times New Roman","Georgia",...];const fontSizeOptions =[{key:"初号",value:36},{key:"小初",value:31},...9,10,...];const lineHeightOptions =[0,2,4,...];export{ fontFamilyOptions, fontSizeOptions, lineHeightOptions };
我们将本节新增定义的
fontFamilyOptions
,
fontSizeOptions
和
lineHeightOptions
提取到了这个文件中,它们分别是字体、字号和行间距的可取值列表。
2. 实现3个编辑模块
这里的3个编辑模块的代码逻辑大同小异,且互相独立,各不影响。所以仅列出
fontFamily
字体属性编辑模块的实现。
import{ fontFamilyOptions }from"../../apis/constants";const isWindows = navigator.userAgent.toUpperCase().indexOf("WIN")!==-1;const isMac = navigator.userAgent.toUpperCase().indexOf("MAC")!==-1;constFontFamilyWrapper=(props)=>{constoptionFilter=(option)=>{return(!option.hasOwnProperty("key")||(option.platform ==="windows"&& isWindows)||(option.platform ==="mac"&& isMac));};const menuItems =useMemo(()=>{return fontFamilyOptions.filter(optionFilter).map((option, index)=>{let _key = option, _value = option;if(option.hasOwnProperty("key")){
_key = option.key;
_value = option.value;}return(<Option key={`font-family-${_key}`} value={_value} style={{fontFamily: _value }}>{_key}</Option>);});});return(<div className="property-row" key={props.key}><span className="property-title">字体</span><div className="property-container"><Select value={fontFamily} bordered={false} style={{width:"100%"}}
onChange={(value)=> canvasAPI.updateFontProperty("fontFamily", value)}>{menuItems}</Select></div></div>);};
由上述代码可见,共分为4个部分,下面分别讲解:
- 从常量文件
constants.js
中引入定义好的字体常量- 由于同样的字体在
Windows
和Mac
系统中的名称不同,而我们的项目目前没有后台的支持,所以暂且区分不同系统来实现字体。这里在后续章节中开始实现后台服务器时将会重构。- 组装下拉菜单的菜单项,这里与之前的章节类似。
- 绘制字体的下拉菜单,这里用户选择了不同的字体后,
onChange
事件调用canvasAPI.updateFontProperty
方法去更新整个文本框的字体,让每个字符都使用相同的字体。
3. 实现updateFontProperty方法
staticupdateFontProperty(key, newValue){let{ activeObject, canvas }= store.getState();
ObjectAPI.updateProperty(activeObject, key, newValue);
canvas.renderAll();}
这里的代码很简单,直接调用了
updateProperty
方法,去更新整个
Textbox
的
fontFamily
、
fontSize
和
lineHeight
等属性。
updateProperty
方法的实现在上一篇博文中有列出,这里不再赘述。如需回顾,可点击前往
4. 一个常见的用法:仅更新当前选中文字的样式
在目前的实现中,我们可以直接设置整个
Textbox
的属性,这样其中的所有字符都会设置为相同的属性。但有时,我们会选中其中的部分文字,然后单独更新它们的属性。 这个时候就需要更加细致的实现来区分两种情况。
首先确定目标,我们要实现的效果如下图所示:
**我们实现以下代码在一个
CanvasAPI.js
文件中:**
// 1. 判断是否对整个Textbox更新属性staticshouldUpdateTheWholeTextbox(object, key){return!object?.isEditing || key ==="lineHeight";}// 2. 更新Textbox的属性staticupdateFontProperty(key, newValue){let{ activeObject, canvas }= store.getState();if(this.shouldUpdateTheWholeTextbox(activeObject, key)){
CanvasAPI._updateFontPropertyForWholeObject(key, newValue);}else{
CanvasAPI._updateFontPropertyForSelection(key, newValue);}
canvas.renderAll();}// 3. 更新整个Textbox的属性static_updateFontPropertyForWholeObject(key, newValue){let{ activeObject }= store.getState();
ObjectAPI.updateProperty(activeObject, key, newValue);}// 4. 更新Textbox中当前选中的部分文字的属性static_updateFontPropertyForSelection(key, newValue){let{ activeObject, canvas }= store.getState();let style ={};
style[key]= newValue;
activeObject.setSelectionStyles(style);}
代码逻辑比较清晰,共分为4个方法,下面分别解析:
**1.
shouldUpdateTheWholeTextbox
方法:** 判断当前状态下,应该整体更新文本框的属性,还是仅更新选中的文字的属性。**逻辑上,处于非编辑态的文本框适用前者,否则适用后者。这里有一个特殊属性
lineHeight
行间距。根据定义,这个属性只能对整个文本框设置,不能仅对选中的文字设置。**
**2.updateFontProperty
方法:** 前文中实现过的方法,这里根据
shouldUpdateTheWholeTextbox
的返回值区分两种状态,调用不同的方法更新文本框属性。
**3._updateFontPropertyForWholeObject
方法:** 更新整个文本框的属性。
**4._updateFontPropertyForSelection
方法:** 仅更新文本框中当前选中的文字的属性。
三、Show u the code
按照惯例,本节的完整代码我也托管在了CodeSandbox中,点击前往,查看完整代码
后记
这篇博文中,我们实现了对文字的字体、字号和行间距的编辑。同时,根据我们日常的使用习惯,实现了对部分用户选中的文字的属性进行单独地编辑。
作为简历中占据最大部分空间的文字对象,本章的实现很大程度上实现了用户在制作简历时的核心需要。当然,这还远远不够。在下一篇博文中,我们将实现设置文字的加粗、斜体、删除线、下划线等能力。
如有需要,你可以:
- 点击这里,返回第一篇《前端canvas项目实战——简历制作网站(一)——左侧工具栏》
- 点击这里,返回上一篇《前端canvas项目实战——简历制作网站(四)——右侧属性栏(线条端点样式)》
- 点击这里,前往下一篇《前端canvas项目实战——简历制作网站(六)——加粗、斜体、下划线、删除线(上)》
版权归原作者 IMplementist 所有, 如有侵权,请联系我们删除。