javascript他爹说了,当初第一个版本就是花了一个星期搞出来的。人家是个lisp爱好者,但是用户喜欢C语言,所以搞出了这么个东西。很多现在说是坑的东西,其实都是他为了赶deadline随便弄出来的,没空细想。
成都创新互联专注为客户提供全方位的互联网综合服务,包含不限于成都做网站、成都网站设计、成都外贸网站建设、西充网络推广、微信小程序、西充网络营销、西充企业策划、西充品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;成都创新互联为所有大学生创业者提供西充建站搭建服务,24小时服务热线:13518219792,官方网址:www.cdcxhl.com
后来流行了,想改也晚了。web程序员喜欢说,我们就是要快,哈哈哈哈哈哈,做基础设施怎么能求快呢,害人害己啊。
众所周知,canvas的api繁杂,对一般的前端er来说不太友好,加上平时一般也不会自己手写canvas,所以一般开发者对canvas的涉猎可能并不太深(我看红宝书的时候canvas是直接跳过的)。而当需要使用canvas开发一些定制化的需求时,echarts,antv系列,可能就无法满足了,这个时候或许fabric会是一个比较好的选择,fabric提供一种类似面向对象的方法来编写canvas,比原生稍微方便一些(然鹅官方文档太难看懂了)
近期的一个项目中,有这么一个需求:拖拽缩放元素并且进行连线,本来我第一反应是用antv/g6去实现的,但是需要对拖拽的元素缩放并且拖拽的容器需要放文字和图表,如果使用g6的话,缩放容器,里面的内容改变不太利索(实际是我对g6不太熟),另一个重要的问题是g6元素里面放图表的话只能放g2(而且需要单独安装插件)并且不支持诸如tooltip等等功能,简单来说只能用个阉割版的(示例: )。因此我最初想的是使用 vue-grid-layout ( github 文档 )进行拖拽与缩放,画线使用canvas。这样做的好处是第三方组件已经把拖拽和缩放功能全都封装好了,dom元素嵌入echarts和文本缩放也相当方便(vue-echarts的autoresize,文本使用flex布局加overflow:auto),当然画线又是一个大问题,关键点就是线要和拖拽的元素接上,简而言之就是坐标计算了。考虑到画布里面还要放图(拖拽的元素连线到图上)以及要实现连线的时候鼠标移动需要不停的重绘线,最终在同事的推荐下决定使用fabric.js来实现canvas部分。然后就发现这东西用起来一言难尽...
1.官方文档
就算你英语很好看他的文档也会很别扭的,建议直接看 官方DEMO 找自己要的,不懂的百度谷歌,最后把查找文档作为补充以及检查是否有新版api和网上的古早文章不同。
2.在vue中使用
目前只能这样用
3.绘制本地图片有问题
我尝试过 fabric.Image.fromURL('xxx/xxx.png',function(){}) 以及 new Image().src 这两种发现貌似都不能放本地图片地址(类似 @/assets/... 这种),可能是我使用的方式不对,最后只剩下一种方法可用了:
这种方法首先需要在页面上放一个隐藏的img元素,结果一开始fabric还读不到只能通过 onload 事件来获取,但这样会导致画布重绘时无法执行onload,最后一个绘制图片被我写成这样了
sendToBack 方法是为了确保在后面画线的时候线能在图的上面一层显示(貌似fabric是按照先后绘制顺序排层级的,先绘制的层级最高,于是我们需要将图的层级降到最低)
可能是页面结构太复杂的缘故,上面的方法有小概率执行时图片还没加载好,导致最后画布里面其它内容都出来了结果最重要的图没了,最终我搞出来的解决办法是,在img标签上直接绑定load事件,执行load时将组件内设置的状态修改,并监听这个状态的变化来执行图片渲染到canvas画布的过程。
画图(画线除了selectable其它类似,因为我的项目需要选中线)
因为我需要点击线的时候弹出删除菜单,所以不能在初始化的时候直接 skipTargetFind: true ,我要做的是去除选中的样式和大部分功能,保留选中时能获取到选中对象,一旦这个属性设为true则会取消所有选中样式和功能,不需要在canvas对象里面再单独配置了。
第二,计算三次贝塞尔曲线的控制点,这里面用了向量运算...
网上找的检测屏幕缩放比例的方法(可以检测到系统分辨率改变)
然后在初始化fabric对象时需要重新计算宽高(canvasLayout为画布上一级的父元素)
pageZoom主要在拖动元素时计算元素与线的连接点坐标用到了,这个系统里面只要vue-grid-layout元素有改变,我就要重新计算线的起点并重绘线,通过这种办法实现了dom元素和canvas元素的绑定,听起来很low的样子,不过最后功能是都实现了。
参考文章(还有些讲fabric的api的文章找不到了...)
fabric视频教程(我还没看过,可能有些内容存在过时)
在leetcode上刷题的时候踩的坑,题目是这样的
简单思考了一下,用最简单的双循环就可以解决问题,于是习惯性用forEach遍历了两次
结果发现函数返回值是undefined
百度了一下,发现是因为forEach多次执行回调函数,回调函数中使用return没法直接终止forEach,只能终止单次的回调。所以return语句在forEach内部是无法跳出循环的。
解决方案:
1.方案一:js针对数组操作的另外两个方法some()与every()
2.方案二:for/while语句老实循环
总结原因还是对forEach方法理解不够到位