0


前端canvas项目实战——简历制作网站(一)——左侧工具栏

目录


前言

fabric

基础系列博文中,我们通过代码向画布

canvas

中添加矩形、圆形等对象。对于用户,我们不能指望他们可以理解代码,甚至编写代码去制作他的简历。你也许使用过PhotoShop或其他的绘图软件,这些软件中都是让用户点击各种图标来向画布中绘制对应的对象的。没有使用过也没关系,下文中有效果的预览图,也会教你一步一步实现它。

这篇博文是《前端canvas项目实战——简历制作网站》付费专栏系列博文的第一篇——左侧工具栏,主要的内容有:

  1. 实现工具栏,使用户可以通过点击鼠标在画布中添加想要的对象。

一、效果展示

  • 动手体验 CodeSandbox会自动对代码的进行编译,并提供地址以供体验代码效果由于CSDN的链接跳转有问题,会导致页面无法工作,请复制以下链接在浏览器打开: https://wvclr3.csb.app/
  • 动态效果演示在这里插入图片描述
  • 本节之后,我们的简历能做成什么样子请添加图片描述

二、实现步骤

在前面的博文HTML5画布框架fabricjs学习笔记(三)——自定义选择控制框样式中,我们通过

fabric.Object.prototype.xxx = ...;

的方式按照自己的喜好,对选择框的控制点样式做了一些定制化的修改。这篇博文的内容开始前,我们先对代码结构进行一点优化,避免

canvas-page.js

文件里写太多代码,不便于维护。

1. 拆分旧代码,优化项目结构

首先,我们把上述的代码拆分到一个

wrap-object.js

文件中,其含义即对

fabric.Object

类进行封装。

import{ fabric }from"fabric";import shortUUID from"short-uuid";import rotateControlIcon from"../images/rotate.svg";

fabric.Object.prototype.noScaleCache =false;// 修改控制点的样式
fabric.Object.prototype.transparentCorners =false;
fabric.Object.prototype.cornerColor ="white";
fabric.Object.prototype.borderColor ="dodgerblue";
fabric.Object.prototype.cornerStrokeColor ="gray";
fabric.Object.prototype.cornerSize =8;
fabric.Object.prototype.cornerStyle ="circle";
fabric.Object.prototype.strokeUniform =true;
fabric.Object.prototype.padding =10;/**
 * 覆盖fabric.Object的initialize方法,为对象添加id属性
 * @type {function(...[*]): fabric.Object.initialize}
 */
fabric.Object.prototype.initialize =(function(fn){returnfunction(...args){fn.call(this,...args);let{ id }= args;
    id ||=shortUUID().new();this.set("id", id);this.objectCaching =false;returnthis;};})(fabric.Object.prototype.initialize);constrenderIcon=(image, initialAngle)=>{let imageIcon = document.createElement("img");
  imageIcon.src = image;returnfunction(ctx, left, top, styleOverride, fabricObject){let size =this.cornerSize;
    ctx.save();
    ctx.translate(left, top);
    ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle + initialAngle));
    ctx.drawImage(imageIcon,-size /2,-size /2, size, size);
    ctx.restore();};};/**
 * 修改旋转控制按钮的样式
 * @type {Control}
 */
fabric.Object.prototype.controls.mtr =newfabric.Control({x:0,y:-0.5,offsetY:-20,cursorStyle:"pointer",actionName:"rotate",actionHandler: fabric.controlsUtils.rotationWithSnapping,cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,withConnection:false,render:renderIcon(rotateControlIcon,0),cornerSize:20});

显而易见,这里一共三部分:

  • 修改选择框线、控制点等的样式
  • 覆盖fabric.Objectinitialize方法,为对象添加id属性
  • 覆盖mtr中间顶部旋转控制点的样式

2. 左侧工具栏

左侧工具栏用于用户点击后,在画布中创建出其想要的基础图形。初步,我们先实现最基础的四种对象:

矩形

圆形

直线

文字输入框

这里创建一个

left-side-tools.js

,代码如下:

import"./index.css";import squareIcon from"../../images/square.svg";import circleIcon from"../../images/circle.svg";import lineIcon from"../../images/line.svg";import textIcon from"../../images/typeface.svg";import{ handleClickTool }from"./logics";constTool=(props)=>{let{ icon, handleClick }= props;return(<div className="left-side-tool" onClick={handleClick}><img className="left-side-tool-icon" src={icon} alt="Icon of tool"/></div>);};constLeftSideTools=(props)=>{let{ canvas }= props;return(<div className="left-side-tools-container"><Tool icon={squareIcon} handleClick={(e)=>handleClickTool(e,0, canvas)}/><Tool icon={circleIcon} handleClick={(e)=>handleClickTool(e,1, canvas)}/><Tool icon={lineIcon} handleClick={(e)=>handleClickTool(e,2, canvas)}/><Tool icon={textIcon} handleClick={(e)=>handleClickTool(e,3, canvas)}/></div>);};exportdefault LeftSideTools;

UI部分的实现比较简单,就是在页面左侧绘制四个

icon

,点击后调用

handleClickTool

方法去分别向画布中创建对应的对象。

为了提高UI和JS逻辑的维护性,

handleClickTool

放在同目录下的另一个文件

logics.js

中,其代码如下:

import{ fabric }from"fabric";consthandleClickTool=(e, func, canvas)=>{if(!canvas){return;}let newFabricObject;switch(func){case0:
      newFabricObject =newfabric.Rect();break;case1:
      newFabricObject =newfabric.Circle();break;case2:
      newFabricObject =newfabric.Line();break;case3:
      newFabricObject =newfabric.Textbox();break;default:throwRangeError(`Func ${func} not implemented!`);}if(newFabricObject){
    canvas.add(newFabricObject);
    canvas.renderAll();
    canvas.setActiveObject(newFabricObject);
    canvas.renderAll();}
  e.stopPropagation();
  e.preventDefault();};export{ handleClickTool };

其代码逻辑可大致分为3个部分:
1) 根据用户点击的不同

icon

传递过来的

func

创建不同对象的实例
2) 将上述实例通过

canvas.add

方法绘制到画布中
3) 避免

click

事件向父标签传播

3. 组合代码

在新的

canvas-page.js

中,我们将上述的代码“组装”,实现本节所要达到的功能,其代码如下:

import"./index.css";import"../wrap-fabric/wrap-object";import"../wrap-fabric/wrap-rect";import"../wrap-fabric/wrap-circle";import"../wrap-fabric/wrap-line";import"../wrap-fabric/wrap-text";import{ fabric }from"fabric";import React,{ useEffect, useState }from"react";import LeftSideTools from"./left-side-tools";constCanvasPage=(props)=>{const[canvas, setCanvas]=useState(null);useEffect(()=>{let canvas =newfabric.Canvas("canvas");setCanvas(canvas);},[]);return(<div className="content-container"><LeftSideTools canvas={canvas}/><canvas id="canvas" width="794px" height="1123px"/></div>);};exportdefault CanvasPage;

这里有几点需要解释说明:
1) 我们通过

#content-container

将刚刚实现的左侧工具栏

LeftSideTools

和画布

canvas

横向并排置于屏幕中
2) 画布的大小设为

width="794px" height="1123px"

,这是

1倍屏幕分辨率

A4

纸大小

210mm x 297mm

计算得到的像素值大小,具体的计算公式我们在晚些的博文中再谈
3) 我们在本节开头提到的

wrap-object.js

通过

import ../wrap-object

引入了进来,这样的代码拆分可以使UI和JS逻辑更便于阅读和维护


三、Show u the code

由于篇幅所限,尽数列出所有代码改动会导致博文冗长难读。本节完整的代码托管在CodeSandbox中,点击前往,查看完整代码


后记

本节之后,我们可以用现有的功能将简历做成什么样子,我将图片贴到了博文开头,为了读者可以快速理解通过这节的代码我们可以实现什么效果。

点击左侧工具栏,不同的对象会被绘制在画布左上角,我们通过拖拽、按下并拖拽

9

个控制点来改变该对象的

位置

旋转角度

这几个属性,以此实现上述“简历”的样式。

目前我们在页面上还不能改变对象的其他样式,如

边框颜色

填充颜色

等。下一节,我们通过

右侧属性栏

来实现这些需求。

标签: 前端 html5 react

本文转载自: https://blog.csdn.net/Mr_Megamind/article/details/122408354
版权归原作者 IMplementist 所有, 如有侵权,请联系我们删除。

“前端canvas项目实战——简历制作网站(一)——左侧工具栏”的评论:

还没有评论