前端canvas项目实战——简历制作网站(二)——右侧属性栏(颜色)
目录
- 前言
- 一、效果展示
- 二、实现步骤
-
- 1. 实现一个自定义的选色板
- 2. 创建属性工厂,为每个对象定制属性
- 3. 为canvas对象注册监听器,点击不同对象时更新属性列表
- 三、Show u the code
- 后记
前言
上一篇博文中,我们实现了左侧工具栏,通过点击工具栏,我们可以自由得在画布中添加想要的对象。
这篇博文是《前端canvas项目实战——简历制作网站》付费专栏系列博文的第二篇——右侧属性栏(颜色),主要的内容有:
- 初步实现右侧属性栏,使用户可以修改画布中选中的对象的边框和填充颜色。
如有需要,可以:
- 点击这里,返回上一篇《前端canvas项目实战——简历制作网站(一)——左侧工具栏》
- 点击这里,前往下一篇《前端canvas项目实战——简历制作网站(三)——右侧属性栏(线条宽度&样式)》
一、效果展示
-
动手体验
CodeSandbox会自动对代码的进行编译,并提供地址以供体验代码效果
由于CSDN的链接跳转有问题,会导致页面无法工作,请复制以下链接在浏览器打开:
https://srgi02.csb.app/
-
动态效果演示
- 本节之后,我们的简历能做成什么样子
我们可以修改画布背景色、图形、线条和文字的颜色了。
二、实现步骤
知道了这节我们要实现的功能,接下来就开始实现。为了便于理解,我将代码拆分为4个部分进行讲解。
1. 实现一个自定义的选色板
从上述的动态图中可以看到,我们通过一个选色板来选择为画布中的对象索要设置的颜色。这里我们讲相关的代码写到一个palette.js文件中。
import paletteIcon from "../images/palette.svg";
import "./index.css";
import https://blog.csdn.net/Mr_Megamind/article/details/{ ChromePicker } from "react-color";
import React, https://blog.csdn.net/Mr_Megamind/article/details/{ useState } from "react";
import https://blog.csdn.net/Mr_Megamind/article/details/{ Dropdown, Space } from "antd";
import transparentIcon from "../images/transparent.svg";
const _parseHex2Rgb = (hex) => https://blog.csdn.net/Mr_Megamind/article/details/{
return https://blog.csdn.net/Mr_Megamind/article/details/{
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) => https://blog.csdn.net/Mr_Megamind/article/details/{
let https://blog.csdn.net/Mr_Megamind/article/details/{ handleChange, initColor } = props;
let [color, setColor] = useState(https://blog.csdn.net/Mr_Megamind/article/details/{
rgb: https://blog.csdn.net/Mr_Megamind/article/details/{ ...initColor.rgb, a: 1 },
hex: initColor.hex,
});
function _handleChange(color, isCommonColor) https://blog.csdn.net/Mr_Megamind/article/details/{
if (color.hex === "") https://blog.csdn.net/Mr_Megamind/article/details/{
color.hex = "#FFFFFF";
color.rgb = https://blog.csdn.net/Mr_Megamind/article/details/{ r: 255, g: 255, b: 255, a: 0 };
}
if (!color.hasOwnProperty("rgb") && color.hex) https://blog.csdn.net/Mr_Megamind/article/details/{
color.rgb = _parseHex2Rgb(color.hex);
}
setColor(color);
handleChange && handleChange(color.hex);
}
return (
<ChromePicker width="100%" color=https://blog.csdn.net/Mr_Megamind/article/details/{color.hex} onChange=https://blog.csdn.net/Mr_Megamind/article/details/{(color) => _handleChange(color)}/>
);
};
const CustomePalette = (props) => https://blog.csdn.net/Mr_Megamind/article/details/{
let https://blog.csdn.net/Mr_Megamind/article/details/{ title, color, handleChange } = props;
if ("" === color || "transparent" === color) https://blog.csdn.net/Mr_Megamind/article/details/{
color = "#FFFFFF";
}
const overlay = (
<ColorPicker initColor=https://blog.csdn.net/Mr_Megamind/article/details/{https://blog.csdn.net/Mr_Megamind/article/details/{ hex: color, rgb: _parseHex2Rgb(color) }}
handleChange=https://blog.csdn.net/Mr_Megamind/article/details/{(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 (
https://blog.csdn.net/Mr_Megamind/article/details/{title}
<Dropdown dropdownRender=https://blog.csdn.net/Mr_Megamind/article/details/{() => overlay} overlayClassName="overlay"
overlayStyle=https://blog.csdn.net/Mr_Megamind/article/details/{https://blog.csdn.net/Mr_Megamind/article/details/{ boxShadow: overlayShadow }} trigger="click" placement="bottom">
https://blog.csdn.net/Mr_Megamind/article/details/{ backgroundColor: color }} />
<img alt="选色盘" src=https://blog.csdn.net/Mr_Megamind/article/details/{paletteIcon} className="palette-icon" />
);
};
export https://blog.csdn.net/Mr_Megamind/article/details/{ 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 https://blog.csdn.net/Mr_Megamind/article/details/{ Palette } from "../../components/palette";
import https://blog.csdn.net/Mr_Megamind/article/details/{ Actions as actions } from "../../modules/actions";
import https://blog.csdn.net/Mr_Megamind/article/details/{ connect } from "react-redux";
import ObjectAPI from "../../apis/objectAPI";
const ObjectProps = (props) => https://blog.csdn.net/Mr_Megamind/article/details/{
let https://blog.csdn.net/Mr_Megamind/article/details/{ canvas, activeObject, activeObjectProperties } = props;
let https://blog.csdn.net/Mr_Megamind/article/details/{ stroke, fill } = activeObjectProperties;
function handleChange(key, newValue) https://blog.csdn.net/Mr_Megamind/article/details/{
ObjectAPI.updateProperty(activeObject, key, newValue);
}
// 1. 封装自定义的选色盘,实现描边和填充两种选色器
const StrokeWrapper = (props) => https://blog.csdn.net/Mr_Megamind/article/details/{
return (
props.key}>
<Palette title="描边" color=https://blog.csdn.net/Mr_Megamind/article/details/{stroke} handleChange=https://blog.csdn.net/Mr_Megamind/article/details/{(value) => handleChange("stroke", value)} />
);
};
const FillWrapper = (props) => https://blog.csdn.net/Mr_Megamind/article/details/{
return (
props.key}>
<Palette title="填充" color=https://blog.csdn.net/Mr_Megamind/article/details/{fill} handleChange=https://blog.csdn.net/Mr_Megamind/article/details/{(value) => handleChange("fill", value)} />
);
};
const wrapperNameEntityMap = https://blog.csdn.net/Mr_Megamind/article/details/{
StrokeWrapper: StrokeWrapper,
FillWrapper: FillWrapper
};
// 2. 分别为不同的对象类型定制属性组
const propertyWrapperMap = https://blog.csdn.net/Mr_Megamind/article/details/{
rect: ["StrokeWrapper", "FillWrapper"],
circle: ["StrokeWrapper", "FillWrapper"],
textbox: ["FillWrapper"],
line: ["StrokeWrapper"]
};
function handleClick() https://blog.csdn.net/Mr_Megamind/article/details/{
canvas.discardActiveObject();
canvas.renderAll();
handleClearActiveObject();
}
// 3. 绘制对象的属性组
return (
https://blog.csdn.net/Mr_Megamind/article/details/{ paddingLeft: "1.5rem" }}>
对象属性
handleClick}>
画布
https://blog.csdn.net/Mr_Megamind/article/details/{propertyWrapperMap[type].map((item, index) => https://blog.csdn.net/Mr_Megamind/article/details/{
let wrapperEntity = wrapperNameEntityMap[item];
return wrapperEntity(https://blog.csdn.net/Mr_Megamind/article/details/{ key: type + "-" + index });
})}
);
};
const mapStateToProps = (state) => https://blog.csdn.net/Mr_Megamind/article/details/{
return https://blog.csdn.net/Mr_Megamind/article/details/{
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) https://blog.csdn.net/Mr_Megamind/article/details/{
// 初次选中对象时的监听器
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) => https://blog.csdn.net/Mr_Megamind/article/details/{
// 从中央数据仓库中清除画布中选中的对象
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的样式编辑能力做更多的扩展。
如有需要,可以:
- 点击这里,返回上一篇《前端canvas项目实战——简历制作网站(一)——左侧工具栏》
- 点击这里,前往下一篇《前端canvas项目实战——简历制作网站(三)——右侧属性栏(线条宽度&样式)》
本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://www.net2asp.com/5a61edc354.html
