AxeSlide软件项目梳理   canvas绘图系列知识点整理

我们创建一个类封装了所有鼠标需要处理的事件。

     export class MouseEventInfo {
el: HTMLElement;
onmouseDown: Function;
ondragMove: Function;
ondragUp: Function;
onmouseMove: Function;
onmouseUp: Function;
mouseWheel: Function;
onContextMenu: Function;
constructor(ele: any, mouseDown: Function, dragMove: Function, dragUp: Function, mouseMove: Function, mouseUp: Function, mouseWheel: Function, contexMenu: Function) {
this.el = ele;
this.onmouseDown = mouseDown || null;
this.ondragMove = dragMove || null;
this.ondragUp = dragUp || null;
this.onmouseMove = mouseMove || null;
this.onmouseUp = mouseUp || null;
this.mouseWheel = mouseWheel || null
this.onContextMenu = contexMenu;
}
}

MouseEventClass就是绑定事件的过程,我们这里只列出部分代码,未列出的事件绑定的部分同理。

     export class MouseEventClass {
x: number;
y: number;
down: boolean;
dragging: boolean;
scroll: boolean;
lastX: number;
lastY: number;
startX: number;
startY: number;
moveCount: number;
eventInfo: MouseEventInfo;
constructor(eInfo: MouseEventInfo) {
this.moveCount = 0;
this.x = 0;
this.y = 0;
this.lastX = 0;
this.lastY = 0;
this.startX = 0;
this.startY = 0;
this.down = false;
this.eventInfo = eInfo;
this.dragging = false;
this.scroll = false; var on = impressEvent.on;
var self = this;
if (this.eventInfo.el) {
on(this.eventInfo.el, "mousedown", function (e) {
if (e.button == 1 || e.button == 2) {
e.preventDefault();
return false;
}
self.mousedownHandler(e); });
(this.eventInfo.ondragMove || this.eventInfo.onmouseMove) && on(this.eventInfo.el, "mousemove", function (e) {
if (e.button == 1 || e.button == 2) {
e.preventDefault();
return false;
}
self.mousemoveHandler(e);
});
(this.eventInfo.ondragUp || this.eventInfo.onmouseUp) && on(this.eventInfo.el, "mouseup", function (e) {
if (e.button == 1 || e.button == 2) {
e.preventDefault();
return false;
}
self.mouseupHandler(e);
});
this.eventInfo.mouseWheel && on(this.eventInfo.el, "mousewheel", function (e) {
if (e.button == 1 || e.button == 2) {
e.preventDefault();
return false;
}
self.mouseWheelHandler(e);
});
this.eventInfo.onContextMenu && on(this.eventInfo.el, "contextmenu", function (e) {
if (e.button == 1) {
e.preventDefault();
return false;
}
e.preventDefault();
self.contextMenuHandler(e);
})
};
} mousedownHandler = function (evt: MouseEvent) {
this.moveCount = 1;
this.down = true;
this.startX = evt.pageX;
this.startY = evt.pageY;
this.dragging = false;
this.eventInfo.el && this.eventInfo.onmouseDown && (this.eventInfo.onmouseDown({
evt: evt,
target: this.eventInfo.el,
mouseX: this.startX - leftWidth,
mouseY: this.startY - topHeight - topAnimaitonHeight,
buttonCode: evt.button
}));
this.lastX = evt.pageX;
this.lastY = evt.pageY;
};
mousemoveHandler = function (evt: MouseEvent) {
this.moveCount++;
this.x = evt.pageX;
this.y = evt.pageY;
if (this.down && (this.x - this.startX != 0 || this.y - this.startY != 0)) {
this.dragging = true;
}
if (this.dragging) {
this.eventInfo.ondragMove && this.eventInfo.ondragMove({
evt: evt,
isFirstMove: this.moveCount == 1 ? true : false,
mouseX: this.x - leftWidth,
mouseY: this.y - topHeight - topAnimaitonHeight,
downX: this.startX - leftWidth,
downY: this.startY - topHeight - topAnimaitonHeight,
lastX: this.lastX - leftWidth,
lastY: this.lastY - topHeight - topAnimaitonHeight,
noRoteDiffX: this.x - this.lastX,
noRoteDiffY: this.y - this.lastY,
totalX: this.x - this.startX,
totalY: this.y - this.startY
})
} else {
this.eventInfo.onmouseMove && this.eventInfo.onmouseMove({
evt: evt,
mouseX: this.x - leftWidth,
mouseY: this.y - topHeight - topAnimaitonHeight,
downX: this.startX - leftWidth,
downY: this.startY - topHeight - topAnimaitonHeight,
lastX: this.lastX - leftWidth,
lastY: this.lastY - topHeight - topAnimaitonHeight,
noRoteDiffX: this.x - this.lastX,
noRoteDiffY: this.y - this.lastY,
totalX: this.x - this.startX,
totalY: this.y - this.startY
})
}
this.lastX = evt.pageX;
this.lastY = evt.pageY;
};

如何使用上面我们创建的两个类呢

我们在使用的时候先将MouseEventInfo这个类初始化,然后再用MouseEventClass绑定事件。

this.mouseEventInfo = new Common.MouseEventInfo(document, this.mouseDown, this.dragMove, this.dragUp, this.mouseMove, this.mouseUp, this.mouseWheel, this.onContextMenu);

new Common.MouseEventClass(this.mouseEventInfo);

我们绑定事件的元素是document,操作软件的所有事件都会走我们绑定的以下函数:

当然最重要的操做画布的响应也依赖于我们的事件处理逻辑:

this.mouseDown:鼠标按下的事件处理逻辑,例如存储当前的鼠标值

this.dragMove:鼠标拖拽移动,例如移动某个元素或者移动画布

this.dragUp:鼠标松开(拖拽后松开鼠标),例如停止移动

this.mouseMove:鼠标移动(不是按住状态),例如让元素显示hover状态

this.mouseUp:鼠标松开(mousedown后马上松开),例如触发某个元素的编辑状态

this.mouseWheel:鼠标滚动,例如缩放画布

this.onContextMenu:鼠标点击右键,例如显示右键菜单

												

软件项目技术点(6)——结合鼠标操作绘制动态canvas画布的更多相关文章

  1. 软件项目技术点(1)——d3.interpolateZoom-在两个点之间平滑地缩放平移

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 软件参考d3的知识点 我们在软件中主要用到d3.js的核心函数d3.interpolateZoom - 在两个点之间平滑地缩放平移.请 ...

  2. 软件项目技术点(5)——在canvas上绘制动态网格线

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 grid类的实现 当鼠标在画布上缩放时,网格能跟着我的鼠标滚动而相应的有放大缩小的效果. 下面是具体实现的代码,draw函数里计算出大 ...

  3. 软件项目技术点(2)——Canvas之平移translate、旋转rotate、缩放scale

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 画布操作介绍 画布绘图的环境通过translate(),scale(),rotate(), setTransform()和transf ...

  4. 软件项目技术点(2)——Canvas之坐标系转换

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 默认坐标系与当前坐标系 canvas中的坐标是从左上角开始的,x轴沿着水平方向(按像素)向右延伸,y轴沿垂直方向向下延伸.左上角坐标为 ...

  5. 软件项目技术点(2)——Canvas之获取Canvas当前坐标系矩阵

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 前言 在我的另一篇博文 Canvas坐标系转换 中,我们知道了所有的平移缩放旋转操作都会影响到画布坐标系.那在我们对画布进行了一系列操 ...

  6. 软件项目技术点(1)——Tween算法及缓动效果

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 Tween算法及缓动效果 软件里在切换步序时需要有过渡动画效果,从当前位置的画面缓动到目标位置的画面.动画效果可重新查看文章系列第一篇 ...

  7. 软件项目技术点(7)——在canvas上绘制自定义图形

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 图形种类 目前我们软件可以绘制出来的形状有如下这几种,作为开发者我们一直想支持用户可以拖拽的类似word里面图形库,但目前还没有找到比 ...

  8. 软件项目技术点(9)——如何将gif动态图拆分绘制

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 背景介绍 我们的软件支持插入gif图片,并且展示在软件里是动态的,例如插入下面这张gif图. 在软件里显示的同样是这样的动态效果: 那 ...

  9. 软件项目技术点(8)—— canvas调用drawImage绘制图片

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 html5中标签canvas,函数drawImage(): 使用drawImage()方法绘制图像.绘图环境提供了该方法的三个不同版本 ...

随机推荐

  1. 2016级算法第五次上机-G.ModricWang的撒币游戏

    1062 ModricWang的撒币游戏 思路 此题为2017年ACM-ICPC亚洲区域赛乌鲁木齐赛区的A题,现场94个队中有38个队做出此题.在这里作为满分以外的题,是为了让大家看一下外面一些题的风 ...

  2. [转] Jenkins pipeline 中获取 exit code, stdout and stderr 返回值和输出

    [From] https://issues.jenkins-ci.org/browse/JENKINS-44930 其做法是,把stdout定向到一个文件,sh 配置 returnStatus: tr ...

  3. JobScheduler布置后台任务以及实现进程保活?

    1.简介 在Android 5.0 提供了一套新的 JobScheduler API,它允许您定义要在以后的某个时间或在指定的条件下(例如,当设备在充电时)异步运行的作业来优化电池寿命. https: ...

  4. 【python】Scrapy爬虫框架入门

    说明: 本文主要学习Scrapy框架入门,介绍如何使用Scrapy框架爬取页面信息. 项目案例:爬取腾讯招聘页面 https://hr.tencent.com/position.php?&st ...

  5. init_config_file.lua

    --[[ 读取限流配置 --]] --获取共享内存 local limit_req_store = ngx.shared.limit_req_store --初始化拒绝 URI 列表 reject_u ...

  6. String字符串排序1.8 lamda表达式以及1.7自定义排序

    // 1.8 public class text { public static void main(String[] args) { String s1 = "哈哈哈11,呵呵呵22,嘿嘿 ...

  7. Centos7修改主机名称、DNS、网卡信息

    1 hostnamectl set-hostname wangshuyi 2 vi /etc/hostname 3 vi /etc/resolv.conf 4 vi /etc/sysconfig/ne ...

  8. 安装Cloudera Manager集群时首次运行命令部署客户端设置失败的解决办法(图文详解)

    不多说,直接上干货! 问题详情 解决办法 (1) 时间同步检查下(尤其是这个) (2) 防火墙是否关闭 (3) cloudera-scm-server 和 cloudera-scm-agent 是否启 ...

  9. c++ 网络编程(七) LINUX下 socket编程 基于套接字的标准I/O函数使用 与 fopen,feof,fgets,fputs函数用法

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9614820.html 一.标准I/O 1,什么是标准I/O?其实是指C语言里的文件操作函数,如 ...

  10. c++ 网络编程(八) LINUX-epoll/windows-IOCP下 socket opoll函数用法 优于select方法的epoll 以及windows下IOCP 解决多进程服务端创建进程资源浪费问题

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9622548.html 锲子:关于并发服务器中的I/O复用实现方式,前面在网络编程系列四还是五来 ...