东莞网站快速排名提升,sem竞价外包公司,单页优化到首页,wordpress 添加meta目录 前言一、效果展示二、实现步骤1. 实现一个自定义的选色板2. 创建属性工厂#xff0c;为每个对象定制属性3. 为canvas对象注册监听器#xff0c;点击不同对象时更新属性列表 三、Show u the code后记 前言
上一篇博文中#xff0c;我们实现了左侧工具栏#xff0c;通过… 目录 前言一、效果展示二、实现步骤1. 实现一个自定义的选色板2. 创建属性工厂为每个对象定制属性3. 为canvas对象注册监听器点击不同对象时更新属性列表 三、Show u the code后记 前言
上一篇博文中我们实现了左侧工具栏通过点击工具栏我们可以自由得在画布中添加想要的对象。
这篇博文是《前端canvas项目实战——简历制作网站》付费专栏系列博文的第二篇——右侧属性栏(颜色)主要的内容有
初步实现右侧属性栏使用户可以修改画布中选中的对象的边框和填充颜色。 一、效果展示 动手体验 CodeSandbox会自动对代码的进行编译并提供地址以供体验代码效果 由于CSDN的链接跳转有问题会导致页面无法工作请复制以下链接在浏览器打开 https://srgi02.csb.app/ 动态效果演示 本节之后我们的简历能做成什么样子 我们可以修改画布背景色、图形、线条和文字的颜色了。 二、实现步骤
知道了这节我们要实现的功能接下来就开始实现。为了便于理解我将代码拆分为4个部分进行讲解。
1. 实现一个自定义的选色板
从上述的动态图中可以看到我们通过一个选色板来选择为画布中的对象索要设置的颜色。这里我们讲相关的代码写到一个palette.js文件中。
import paletteIcon from ../images/palette.svg;
import ./index.css;
import { ChromePicker } from react-color;
import React, { useState } from react;
import { Dropdown, Space } from antd;
import transparentIcon from ../images/transparent.svg;const _parseHex2Rgb (hex) {return {r: parseInt(hex.substring(1, 3), 16),g: parseInt(hex.substring(3, 5), 16),b: parseInt(hex.substring(5, 7), 16),a: 1,};
};let ColorPicker (props) {let { handleChange, initColor } props;let [color, setColor] useState({rgb: { ...initColor.rgb, a: 1 },hex: initColor.hex,});function _handleChange(color, isCommonColor) {if (color.hex ) {color.hex #FFFFFF;color.rgb { r: 255, g: 255, b: 255, a: 0 };}if (!color.hasOwnProperty(rgb) color.hex) {color.rgb _parseHex2Rgb(color.hex);}setColor(color);handleChange handleChange(color.hex);}return (ChromePicker width100% color{color.hex} onChange{(color) _handleChange(color)}/);
};const CustomePalette (props) {let { title, color, handleChange } props;if ( color || transparent color) {color #FFFFFF;}const overlay (ColorPicker initColor{{ hex: color, rgb: _parseHex2Rgb(color) }}handleChange{(value) handleChange(value)} /);const overlayShadow 0 3px 6px -4px rgb(0 0 0 / 12%), 0 6px 16px 0 rgb(0 0 0 / 8%), 0 9px 28px 8px rgb(0 0 0 / 5%);return (div classNamepalettespan classNameproperty-title{title}/spanDropdown dropdownRender{() overlay} overlayClassNameoverlayoverlayStyle{{ boxShadow: overlayShadow }} triggerclick placementbottomdiv classNameproperty-containerdiv classNameproperty-color-bar style{{ backgroundColor: color }} /img alt选色盘 src{paletteIcon} classNamepalette-icon //div/Dropdown/div);
};export { Palette };代码很清晰分为3个部分
定义一个16进制色彩值到rgb色彩值的转换方法引入react-color库中的ChromePicker选色盘进行自定义封装。安装依赖需要在命令行执行npm install react-color 设定了宽度width设置了一个ReactHook(useState)监听选色盘上当前选中的颜色值变化监听了onChange事件当用户改变了选中的颜色值执行传入的handleChange方法 使用上述自定义封装的选色盘CustomePicker和antd库的DropDown下拉菜单组件封装一个选色模块。即初始时显示下图中的颜色条和选色盘icon点击后出现下拉菜单其中显示选色盘。 2. 创建属性工厂为每个对象定制属性
显而易见画布中不同的对象有不同的属性。如矩形和圆有描边和填充两种颜色属性而线条和文字只有填充这一种。
这里我们创建一个object-props.js
import { Palette } from ../../components/palette;
import { Actions as actions } from ../../modules/actions;
import { connect } from react-redux;
import ObjectAPI from ../../apis/objectAPI;const ObjectProps (props) {let { canvas, activeObject, activeObjectProperties } props;let { stroke, fill } activeObjectProperties;function handleChange(key, newValue) {ObjectAPI.updateProperty(activeObject, key, newValue);}// 1. 封装自定义的选色盘实现描边和填充两种选色器const StrokeWrapper (props) {return (div classNameproperty-row key{props.key}Palette title描边 color{stroke} handleChange{(value) handleChange(stroke, value)} //div);};const FillWrapper (props) {return (div classNameproperty-row key{props.key}Palette title填充 color{fill} handleChange{(value) handleChange(fill, value)} //div);};const wrapperNameEntityMap {StrokeWrapper: StrokeWrapper,FillWrapper: FillWrapper};// 2. 分别为不同的对象类型定制属性组const propertyWrapperMap {rect: [StrokeWrapper, FillWrapper],circle: [StrokeWrapper, FillWrapper],textbox: [FillWrapper],line: [StrokeWrapper]};function handleClick() {canvas.discardActiveObject();canvas.renderAll();handleClearActiveObject();}// 3. 绘制对象的属性组return (div classNameproperty-listdiv classNameproperty-list-headerdiv classNameproperty-list-header-tab activetrue style{{ paddingLeft: 1.5rem }}span对象属性/span/divdiv classNameproperty-list-header-tab onClick{handleClick}span画布/span/div/div{propertyWrapperMap[type].map((item, index) {let wrapperEntity wrapperNameEntityMap[item];return wrapperEntity({ key: type - index });})}/div);
};
const mapStateToProps (state) {return {canvas: state.canvas,activeObject: state.activeObject,activeObjectProperties: state.activeObjectProperties};
};export default connect(mapStateToProps, null)(ObjectProps);由上述代码可见属性工厂分为3个部分
使用上文中实现的自定义选色器实现描边和填充两种属性的操作模块分别为不同的对象类型定制属性列表将属性列表依次绘制出来
如下图选中矩形对象它的颜色属性有两个选中文字对象它的颜色属性就只有一个 选中矩形 选中文字 注意 其中使用了react-redux作为中央数据仓库篇幅所限不对其做深入的讲解你可以自行搜索也可以点击文章末尾CodeSandbox链接直接看代码学习。如确实需要讲解请在评论中留言需要的人数较多的话我会在react基础博文中新增一篇来介绍。 3. 为canvas对象注册监听器点击不同对象时更新属性列表
由上述动图可见我们点击画布中不同的对象时右侧的属性栏会立即更新为当前选中对象的属性。要实现这里我们需要给画布对象canvas注册一个监听器。 /*** 为画布添加监听器* param canvas 画布*/static addListeners(canvas) {// 初次选中对象时的监听器canvas.on(selection:created, () // 向中央数据仓库更新画布中选中的对象store.dispatch(actions.updateActiveObject(canvas.getActiveObject())););// 更新选中对象时的监听器canvas.on(selection:updated, () // 向中央数据仓库更新画布中选中的对象store.dispatch(actions.updateActiveObject(canvas.getActiveObject())););// 取消选中对象之前的监听器canvas.on(before:selection:cleared, (e) {// 从中央数据仓库中清除画布中选中的对象store.dispatch(actions.clearActiveObject);});}核心的代码很简洁这里我们为canvas添加了3个监听器下面分别介绍
selection:created选中被创建时这里我们向中央数据仓库更新画布中选中的对象selection:updated选中更新时这里的操作同上before:selection:cleared选中被清除之前这里我们从中央数据仓库中清除画布中选中的对象。 注意 这个方法可以写在任何地方在创建canvas之后调用addListener(canvas)即可。这里我们对中央数据仓库中activeObject的任何更新都会立即被属性工厂中监听到同时立即渲染当前所需的属性列表。 三、Show u the code
按照惯例本节的完整代码我也托管在了CodeSandbox中点击前往查看完整代码 后记
本文中我们注册了canvas的3种监听事件。除此之外它还有很多监听事件比如
after:render画布重绘后object:moving对象移动时object:rotating对象被旋转时object:added对象被添加到画布中后object:removed对象被从画布中移除后 …
更多的监听事件我们在后续博文中如有用到还会详细讲解。
本节中我们让用户可以在页面中随意修改各种对象的颜色。下一节中我们将会对线条Line的样式编辑能力做更多的扩展。