永中dcs是一款在线预览各种办公文件的网络产品,我们可以只用一个浏览器就可以实现对word,ppt和excel等文件的在线浏览,在其中有一个在线手绘功能很有特色,让我们来探一探它的实现原理吧。

第一,简单的光标滑动中究竟发生了什么

当你啪的一声在屏幕上按下鼠标光标或者更直接的用手指头按住触摸屏,浏览器就会产生对应的触摸事件,输出类似于下面所示的信息

event = {

clientX:xxx,

clientY:yyy,

timeStamp:tttt,

...

}

每划过一段距离和一段时间,浏览器就会产生一个触碰或者光标事件,事件里面记录了点位的位置坐标,产生时间,相对位置,甚至通过一些手段,你可以从事件的深层信息里找到触碰的压力信息。

有了这些点了,我们想到把他们连起来,不就是现成的笔画了吗,但是在虚空中一划可是不会产生任何线条的,你需要一个载体把你的笔画记录下来,我们这边就使用canvas画布用来当我们的背景板。好,开始绘制,

ctx.beginPath();

ctx.moveTo(x1, y1);

ctx.lineTo(x2, y2);

ctx.stroke();

从记录下的第一个点开始,移动到下一个点,然后连线,一道笔迹就这样完成了。

二、从初步实现到看起来像

但是说实在,这样子画出来的东西真的有人会觉得是可以拿来代替手写的签名笔迹嘛,我的笔锋呢,我的粗细变化呢,我的笔划转折曲线呢,有人可能会把字写成粗细从头到尾全一样,没有曲线只有各种突变的直线首尾相连的样式吗? 用电脑绘制来模拟笔迹最大的问题,线条缺乏转折过度和粗细变化,尖锐的折角和完全一样粗细的线条肯定不是我们最终追求的。

在纸上,我们控制线条的粗细无非就是减轻我们下笔的力道和提高运笔的速度,那么在浏览器屏幕上我们也是同样的操作。每个点位都记录下了轨迹的产生时间,两个点之间的时间差和距离差拿到手,我们就知道这一道笔划究竟是重运笔还是轻轻划过。具体的笔划粗细可以由自己的需求出发设定,总得原则就是快的细,慢的粗,当然,如果再讲究一点,每段线条之间的粗细还存在过渡效果,你可以保存一下上一段线条的粗细,然后按照比例添加到下一段线条的线宽中。

var distance = Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))

var time = timeStamp2 - timeStamp1

var width = lastWidth*1/3 + maxWidth*distance/time*2/3

线条的转折变化就不是前后两点能搞定的了,得引入再前面一个点,三个点的位置变化计算出笔迹的转折曲度,这里我们使用二阶贝塞尔曲线进行轨迹拟合,你要再愿意,再引入一个记录点用三阶贝塞尔曲线拟合也可以,但是大部分人在浏览器屏幕上的书写没有精细到这种程度,不需要做这么复杂的操作。

这里我分享一下我个人操作的一个小技巧,在笔迹的初始点和第二点绘制的时候,由于没有前一个点做曲线拟合,这一段可以用粗细不变的练线代替,可以歪打正着的产生一种书写顿笔的效果。

三、使用场景结合

在永中dcs这个产品中,我们可以直接在线预览各种word、ppt之类的办公文件,省去了我们还要特意安装各种办公软件的困扰,一个浏览器,就能比较完美的在线预览我们的办公文件,这个时候,如果还能写写画画,给我们的文档在线添加一些手绘笔记就太好了。

不需要安装其他复杂的程序插件,直接在我们的转换预览页面里添加一个透明的书写板,然后就可以写出效果很好的手写笔记了,真是简单又方便,写完的笔迹可以当一张很简单的图片插入到在线预览的原文档里,又省去了用户安装专业办公软件的麻烦。

永中dcs实现浏览器上面的手绘效果的更多相关文章

  1. 永中DCS文档转换服务其它产品对比

    一.利用DCOM配置直接操作Office文件 作用:读取文件内容,导出Html文件 优势:免费 劣势:1.服务器上必须安装Office软件 2.配置麻烦,正如微软所说,读取Office不是这么干的. ...

  2. 永中DCS再添喜讯:顺利签约海信集团

    近日,永中DCS与海信集团一起携手,共创文档在线预览新篇章.出于对永中DCS文档在线预览产品的品质与服务的信赖,海信集团选择永中DCS为其提供文档在线预览技术支持,助力移动化办公(EHR系统)发展,提 ...

  3. Python——图像手绘效果

    1.图像的RGB色彩模式 PIL PIL, Python Image Library PIL库是一个具有强大图像处理能力的第三方库 在命令行下的安装方法: pip install pillow fro ...

  4. 使用numpy和PIL实现图像的手绘效果

    输入 输出 代码如下 图像的手绘效果的实现 from PIL import Image import numpy as np a = np.array(Image.open("index.j ...

  5. 在Eclipse中设置Java类上面的注释(包含作者、日期等)

    希望在Eclipse中,让Java类上面的注释像下面这样,改如何设置呢? 在Eclipse中,点击菜单中的Window-->Preferences,打开如下窗口:

  6. Html设置问题(设置浏览器上面的图标,移动设备上面页面保存为图标)

    最近开发了一个新的项目,项目完成之后:要求把页面在移动设备上面保存为图标,通过图标直接进入系统入口(这样看着就想APP一样):刚开始通过百度直接设置了,发现有两个问题,第一.图标直接是页面的截图:第二 ...

  7. python中如何给散点图上面的特定点做标记

    今天想在散点图的某些特定的点外面画圆圈标记,从下面的文章找到一些灵感,只要在原来的散点图上面给指点添加相应的标志,设置其透明度就可以实现该想法. 顺便复习下散点图的用法. 大家平时为了直观地显示数据的 ...

  8. eclipse上修改js后,浏览器上还是出现原来效果的解决方法

    废话不多说,直接上方法: 1.最简单的是清除浏览器缓存.2.换个浏览器试试.3.修改js文件名,换成别的名称,再引用.4.重启eclipse.5.重启电脑.

  9. Python中使用cutecharts实现简单的手绘风格的图表

    场景 效果 cutecharts的Github: https://github.com/chenjiandongx/cutecharts 注: 博客: https://blog.csdn.net/ba ...

随机推荐

  1. 进程和线程操作系统转载的Mark一下

    https://www.cnblogs.com/leisure_chn/p/10393707.html Linux的进程线程及调度 本文为宋宝华<Linux的进程.线程以及调度>学习笔记. ...

  2. Redis | 第8章 发布订阅与事务《Redis设计与实现》

    目录 前言 1. 发布订阅 1.1 频道的订阅与退订 1.2 模式的订阅与退订 1.3 发送消息 1.4 查看订阅消息 2. 事务 2.1 事务的实现 2.2 WATCH 命令的实现 2.3 事务的 ...

  3. 巩固javaweb第十七天

    巩固内容: 文本域 文本域主要用于输入多行文字,如果输入的文字比较多,则可以采用文本域. 文本域的基本格式如下: <textarea rows="行数" name=" ...

  4. 25. Linux下gdb调试

    1.什么是core文件?有问题的程序运行后,产生"段错误 (核心已转储)"时生成的具有堆栈信息和调试信息的文件. 编译时需要加 -g 选项使程序生成调试信息: gcc -g cor ...

  5. Learning Spark中文版--第五章--加载保存数据(2)

    SequenceFiles(序列文件)   SequenceFile是Hadoop的一种由键值对小文件组成的流行的格式.SequenceFIle有同步标记,Spark可以寻找标记点,然后与记录边界重新 ...

  6. 大数据学习day32-----spark12-----1. sparkstreaming(1.1简介,1.2 sparkstreaming入门程序(统计单词个数,updateStageByKey的用法,1.3 SparkStreaming整合Kafka,1.4 SparkStreaming获取KafkaRDD的偏移量,并将偏移量写入kafka中)

    1. Spark Streaming 1.1 简介(来源:spark官网介绍) Spark Streaming是Spark Core API的扩展,其是支持可伸缩.高吞吐量.容错的实时数据流处理.Sp ...

  7. 关于mysql自动备份的小方法

    目前流行几种备份方式:逻辑备份.物理备份.双机热备份.备份脚本的编写等,本文分别从这些方面总结了MySQL自动备份策略的经验和技巧,一起来看看. 目前流行几种备份方式: 一.逻辑备份:使用mysql自 ...

  8. 队列——Java实现

    1 package struct; 2 3 interface IQueue{ 4 //入队列 5 void add(Object obj); 6 //出队列 7 Object remove(); 8 ...

  9. C++ friend详解

    私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行.这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦. C++ 是 ...

  10. 【C/C++】链表/ListNode/数据结构

    vector的操作 添加元素: 向尾部添加一个元素 vector<int> a; a.push_back(1); 向尾部添加多个元素 -向尾部添加x个同样的元素: a.insert(a.e ...