当前位置: 首页 > news >正文

龙岗网站建设流程古典风网站

龙岗网站建设流程,古典风网站,百度站长平台官网,江苏省建设工程竣工备案网站图形开发学院#xff5c;GraphAnyWhere 课程名称#xff1a;图形系统开发实战课程#xff1a;进阶篇(上)课程章节#xff1a;“图形交互操作:拾取”原文地址#xff1a;https://www.graphanywhere.com/graph/advanced/2-6.html 第六章 图形交互操作:拾取 \quad 在图形系统… 图形开发学院GraphAnyWhere 课程名称图形系统开发实战课程进阶篇(上)课程章节“图形交互操作:拾取”原文地址https://www.graphanywhere.com/graph/advanced/2-6.html 第六章 图形交互操作:拾取 \quad 在图形系统中拾取是指从屏幕上选择一个图形对象的过程。这个过程通常是通过鼠标或触摸屏等输入设备来实现的。当用户将鼠标移动到图形对象上时图形系统会检测到鼠标的位置然后根据鼠标位置计算该位置上的图形对象从而实现了拾取操作这个过程也称之为‘碰撞检测’。 \quad 由于 Canvas 不会保存绘制图形的信息一旦绘制完成用户在浏览器中得到的是一张图片用户在图片上点击时时不能直接获取到对应的图形对象所以在绘图时需要缓存已经绘制的图形对象碰撞检测有以下几种方案 内置API法通过Canvas渲染上下文对象内置的 API实现拾取图形几何法通过几何运算判断鼠标点击位置附近的对象实现拾取图形取色法通过获取点击位置的颜色值实现图形拾取 1 内置API法 \quad Canvas 渲染上下文对象提供了 isPointInPath() 可以判断一个坐标点是否在路径内, 提供了 isPointInStroke() 判断一个坐标点是否在描边的边上。 \quad 我们在 图形系统开发实战课程-基础篇 中曾经讲述了Canvas路径的用法路径可完成各种常见基本几何图形和贝塞尔曲线的绘制下图是 anyGraph内置的一些点的类型。 \quad 上面这些点类型均是通过路径绘制出来的从这张图可以看出通过路径我们不仅仅可以绘制常见的几何图形如三角形、矩形、圆形、多边形还可以绘制诸如黑桃、红桃、梅花、花朵等复杂的带有曲线的图形。 \quad 如今 Canvas 渲染上下文对象更是提供了 isPointInPath() 可以判断一个坐标点是否在路径内, 提供了 isPointInStroke() 判断一个坐标点是否在描边的边上。利用这两个API我们可以实现几乎所有类型的图形对象拾取。 \quad 下面这个示例是在上一篇文章 图形交互图形交互操作:平移和缩放 中的示例基础上做出了一些改变在 redraw() 方法中增加了 point参数该参数为鼠标当前的位置。当鼠标移动到某个方块内的时候即 isPointInPath()返回true该方块将会显示为红颜色当鼠标移动到某个方块边缘的时候即 isPointInStroke()返回true该方块将会显示为黄颜色。 运行效果如下图所示 \quad 这个示例中采用了 Canvas 渲染上下文对象提供的 isPointInPath() 和 isPointInStroke() 方法判断点是否在路径中或边框之上。其源代码如下 // 绘图 function redraw(point) {// 清除已有内容ctx.clearRect(0, 0, canvas.width, canvas.height);// 绘制七巧板tangram.forEach(shape {// 坐标转换let pixel [];shape.coords.forEach(coord {pixel.push(convert(coord, graphExtent, canvasExtent));})// 定义路径ctx.beginPath();for (let i 0, ii pixel.length; i ii; i 1) {if (i 0) {ctx.moveTo(pixel[i][0], pixel[i][1]);} else {ctx.lineTo(pixel[i][0], pixel[i][1]);}}ctx.closePath();// 定义渲染颜色值let fillColor shape.style.fillColor;let strokeColor shape.style.color; // 如果Point参数为空则无需进行碰撞检测if (point ! null point.length 2) {// 判断点是否在路径内 如果在路径内则将颜色改为红色if (ctx.isPointInPath(point[0], point[1])) {fillColor red;strokeColor red} // 判断点是否在路径的描边线上 如果在路径内则将颜色改为金色else {if (ctx.isPointInStroke(point[0], point[1])) {fillColor gold;strokeColor gold;}}}// 绘制ctx.save();ctx.strokeStyle strokeColor;ctx.fillStyle fillColor;ctx.fill();ctx.stroke();ctx.restore();}) }使用该方法需要注意: 我们在 第四章 图形基本形状 讲述的图形对象类型包括点、线、多边形、图像、文本、圆等其中文本类型和图像类型无法通过该方法判断是否与点碰撞。如果点存在大小时该方法仅能判断其中心是否在路径内而无法判断点的边缘是否在路境内。在使用 isPointInPath(x, y) 和 isPointInStroke(x, y) 方法判断点是否在路径中或边框之上的时候这个点(x,y)坐标是指画布中的像素坐标。如果 画布在绘制路径之前进行了变形操作参数依旧需传入画布变形前的像素坐标值。 2 几何法 \quad 几何法是指根据点的位置采用几何算法判断该位置是否存在图形对象。我们在 第四章 图形基本形状 讲述的图形对象类型包括点、线、矩形、多边形、图像、文本、圆等等。使用几何法进行判断时需要分别对这些类型进行判断。 2.1 点与点 判断规则 \quad 判断点与点是否相交最简单的判断方法是两个点的坐标是否相等如果相等则判断这两个点相交而实际绘图的点是有大小的而且由于浮点误差方面的原因不能简单判断点与点是否相等而因改为计算点与点之间的距离如果这个距离小于容差值则判断这两个点相交。 实现代码 /*** 判断点与点是否碰撞* param {Point} p1 {x, y}* param {Point} p2 {x, y}* param {float} buffer * returns boolean*/ function pointPoint(point1, point2, buffer) {if (buffer undefined) {buffer 0.1;}if (CoordUtil.dist([point1.x, point1.y], [point2.x, point2.y]) buffer) {return true;}return false; }运行效果 2.2 点与圆 判断规则 \quad 判断点与圆是否相交的规则和判断点与点是否相交的规则类似通过计算点与圆心之间的距离如果距离小于等于圆的半径则判断点在圆内否则判断点不在圆内。 实现代码 /*** 判断点与圆是否碰撞* param {Point} p {x, y}* param {Circle} c {cx, cy, radius}* returns boolean*/ function pointCircle(point, circle) {if (CoordUtil.dist([point.x, point.y], [circle.cx, circle.cy]) circle.radius) {return true;}return false; };运行效果 2.3 点与线 判断规则 \quad 判断点与线是否相交的规则 分别计算点与线的两个端点之间的距离如果距离之和等于线的长度则可判定点与线相交。 实现代码 /*** 判断点与线段是否碰撞* param {*} point {x, y}* param {*} line {x1, y1, x2, y2}* param {*} buffer 容差* returns boolean*/ function pointLine(point, line, buffer) {if (buffer undefined) {buffer 0.1;}// 计算点与线段的两个端点之间的距离let d1 Coordinate.dist([point.x, point.y], [line.x1, line.y1]);let d2 Coordinate.dist([point.x, point.y], [line.x2, line.y2]);// 计算线段长度let lineLen Coordinate.dist([line.x1, line.y1], [line.x2, line.y2]);// 如果点与线段的两个端点之间的距离之和等于线的长度则可判定点与线相交if (d1 d2 lineLen - buffer d1 d2 lineLen buffer) {return true;}return false; }运行效果 折线通常包含了多个线段点与折线是否相交的判断规则是以 点与线段是否相交为基础逐一判断点与每段线的关系。点只要与其中任何一段线相交即可判段点与折线相交。 2.4 点与矩形 判断规则 \quad 判断点与矩形是否相交的规则当点的X坐标大于等于矩形的起点X坐标小于等于矩形的起点X坐标加上矩形宽度且点的Y坐标大于等于矩形的起点Y坐标小于等于矩形的起点Y坐标加上矩形高度时判断点在矩形内否则判断点不在矩形内。 实现代码 /*** 判断点与矩形是否碰撞* param {*} point {x, y}* param {*} rect {x, y, width, height}* returns boolean*/ function pointRect(point, rect) {if (point.x rect.x point.x rect.x rect.width // X坐标大于等于矩形的起点X坐标小于等于矩形的起点X坐标加上矩形宽度point.y rect.y point.y rect.y rect.height) { // Y坐标大于等于矩形的起点Y坐标小于等于矩形的起点Y坐标加上矩形高度return true;}return false; }运行效果 2.5 点与文本 判断规则 \quad 文本绘制的结果是一个矩形区域因此其判断点与文本是否相交的方法与矩形一样。需要注意的是在绘制文本的时候 水平对齐方式 和 垂直对齐方式 对文本的绘制位置有很大影响。下面的代码可计算绘制文本时的矩形位置和大小 /*** 返回对象边界* param {Boolean} useCoord 为true时返回坐标Bound为false时返回屏幕像素Bound* returns {Extent} extent*/ getBBox(useCoord true) {let coord useCoord false ? this.getPixel() : this.getCoord();// 矢量字体才考虑宽度和高度对BBOX的影响let width this._renderWidth; // 渲染文本时记录的文本宽度可通过ctx.measureText(this.text).width获取let height this._renderHeight; // 通常为字体大小// 根据字体水平对齐方式确定文本的bboxlet left, top;if (this.style.textAlign center || this.style.textAlign middle) {left coord[0][0] - width / 2;} else if (this.style.textAlign right) {left coord[0][0] - width;} else {left coord[0][0]}// 属性值有 top(文本块的顶部), hanging(悬挂基线), middle(文本块的中间), alphabetic(标准的字母基线), ideographic(表意字基线), bottom(文本块的底部)if (this.style.textBaseline middle) {top coord[0][1] - height / 2;} else if (this.style.textBaseline bottom || this.style.textBaseline ideographic) {top coord[0][1] - height;} else if (this.style.textBaseline alphabetic) {top coord[0][1] - height;;} else { // top, hangingtop coord[0][1];}return [left, top, left width, top height]; } 运行效果 2.6 点与图像 判断规则 \quad 图像绘制的结果是也一个矩形区域因此其判断点与文本是否相交的方法与矩形一样且其Bounding Box的计算较为简单这里就不展开叙述了。 2.7 点与多边形 \quad 判断点与多边形是否相交的规则是判断这个点和多边形每条边的位置关系。在一个多条边围成的区域点在一条边的右侧这个点可能在多边形内部也可能在外部。但是如果判断完点和每一条边的左右关系如果在右边的边是奇数个那么点就在内部如果是偶数那么点就在外部。通过这个规则就可以判断点是否包含在多边形内。 来源https://blog.csdn.net/tom_221x/article/details/51861129 \quad 那么如何判断一个点和一条边的位置关系 这里需要用到一个向量叉积公式。比如点(x, y)与线 (x1, y1) (x2, y2) 的位置关系。我们先求出两个向量 (x - x1, y - y1) 和 (x2 - x1, y2 - y1)。对这两个向量做叉积的结果是 (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1) 如果结果是0那么点在线上。如果结果大于0点在线的右边。如果结果小于0点在线的左边。 利用这个公式我们就能判断点是否在多边形的内部还是外部。 实现代码 /*** 判断点与多边形是否碰撞* param {*} point {x, y}* param {*} polygon [[x,y],[x,y],[x,y]]* returns */ function pointPoly(point, polygon) {let collision false;// 遍历多边形的每一条边let next 0;for (let current 0; current polygon.length; current) {// 当前顶点let vc polygon[current];// 下一个顶点next (current polygon.length - 1 ? 0 : current 1);let vn polygon[next]; // 判断一个点和一条边(vc,vn)的位置关系, 如果两个检查都为 true则切换到其相反的值if ((vc[1] point.y vn[1] point.y) || (vc[1] point.y vn[1] point.y)) {// 求出两个向量(x - x1, y - y1) 和 (x2 - x1, y2 - y1), // 并对两个向量做叉积的 (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)if ((point.x - vc[0]) (point.y - vc[1]) * (vn[0] - vc[0]) / (vn[1] - vc[1])) {// 如果结果为零: 表示点在线上// 如果结果为正: 表示点在线的右边// 如果结果为负: 表示点在线的左边collision !collision;}}}return collision; }运行效果 点与多边形是否相交的几何判断方法很重要2.4节中讲述了点与矩形的判断方法那种方法在矩形旋转后就无法判断了。而对于旋转的矩形可将计算矩形旋转后各个角的坐标值然后将其转换为多边形采用点与多边形是否相交的办法进行判断。 3. 取色法 \quad 取色法的核心思想是在绘制图像的同时在另一个Canvas中绘制一份与当前图形中各个对象坐标位置和大小均相同且使用独一无二颜色绘制的图形缓存图形同时还需保存一份图形颜色与图形对象的对照表。利用 Canvas 渲染上下文对象提供的像素操作API在进行拾取操作时从缓存图形中根据点的位置获取相应的颜色信息并从颜色对照表中取出对应的图形对象。 \quad 下图展示了取色法的核心思想图形的左侧是要绘制的图形图形的右侧是缓存的图形这份缓存图形中中的对象位置和大小和原图完全一样而颜色却是随机产生的独一无二的颜色。使用 Canvas 渲染上下文对象的 ctx.getImageData(x, y, 1, 1) 方法可取的指定位置那个像素的颜色最后通过颜色与图形对象对照表即可取得拾取的对象。 \quad ctx.getImageData() 返回的数据中包含了 data 属性该属性属于Uint8ClampedArray类型存储了像素数据每个像素包含了4个byte的值分别是该像素对应的红绿蓝和透明值(r,g,b,a)。下图显示了imageData中data的数组结构每个像素均占了data数组中的4个元素第一个像素存储在data数组的0至3个元素第二个像素存储在data数组的4至7个元素。 \quad 我们这里仅拾取了1个像素值因此该数组仅包含4个元素。拾取指定位置颜色的代码如下所示 /*** 获取图形中指定位置的颜色值* param {Array} point * returns color*/ function getColor(point) {if (this._hitContext) {let imageData this._hitContext.getImageData(point[0], point[1], 1, 1);if (imageData.data[0] 0 imageData.data[1] 0 imageData.data[2] 0 imageData.data[3] 0) {return null;} else {return new Color(imageData.data[0], imageData.data[1], imageData.data[2], imageData.data[3]).toHex();}} else {return null;} }\quad 对于常见的几何图形使用这个思路直接在缓存的图形中绘制即可。对于文本和图像则需要将其转换为矩形通过矩形的方式绘制在缓存的图形中。下图演示了使用 取色法 从一张包含了各类图形对象的图形中拾取对象的效果。 4. 方案比较 4.1 内置API法 优点 开发简单识别率高 缺点 拾取效率低拾取的时候定义路径导致拾取效率低无法拾取非路径绘制的图形例如文本和图像无法实现根据矩形或多边形进行拾取 4.2 几何法 优点 扩展性强识别率高 缺点 开发复杂需针对各种类型的图形分别实现其算法拾取效率一般 4.3 取色法 优点 开发简单拾取效率高 缺点 渲染开销加倍每次图形渲染时间为内置API法或几何法的两倍当图形重叠时仅能识别到最上层的图形对象无法实现根据矩形或多边形进行拾取 5. anyGraph 的实现 anyGraph 实现了 几何法 和 取色法 两种图形对象的拾取方案。 5.1 取色法 Graph 对象在初始化时可通过 hitGetColor 选项指定是否启用‘取色法拾取方案’。 该参数的缺省值为 false。 下面这段代码启用了‘取色法拾取方案’。 // graph对象 let graph new Graph({target: graphWrapper,hitGetColor: true });下面这段代码演示了取色法的碰撞检测 // 取色法进行碰撞检测 function _collideCheck(coord) {// 显示颜色值let hitColor graph.getRenderer().getColor(coord);if (hitColor) {if (graph.viewGeomList.has(hitColor)) {let clone graph.viewGeomList.get(hitColor).clone();// 在浮动层突出显示拾取的对象clone.setStyle({ fillColor: gold, color: gold });overLayer.getSource().add(clone);return true;}}return false; }5.2 几何法 \quad anyGraph 图形基本形状类 Geometry对象提供了 contain(point)方法各子类均已实现了该方法通过该方法可判断图形对象与点的位置关系。 \quad 下面这段代码演示了几何法的碰撞检测 // 逐一与数据层中的对象进行碰撞检测 function _collideCheck(coord) {let datas layer.getSource().getData();for (let i 0, len datas.length; i len; i) {if (datas[i].contain([coord[0], coord[1]])) {let clone datas[i].clone();clone.setStyle({ fillColor: #FF2020, color: #FF2020, lineWidth:4 });overLayer.getSource().add(clone);return true;}}return false; }\quad “图形系统实战开发-进阶篇 第六章 图形交互操作: 拾取” 的内容讲解到这里就结束了如果觉得对你有帮助有收获可以关注我们的官方账号持续关注更多精彩内容。 相关资料 ▶ 系列教程及代码资料https://GraphAnyWhere.com ▶ 图形系统开发实战课程进阶篇上——前言 ▶ 图形系统开发实战课程进阶篇上——1.基础知识 ▶ 图形系统开发实战课程进阶篇上——2.图形管理类Graph ▶ 图形系统开发实战课程进阶篇上——3.图层类Layer ▶ 图形系统开发实战课程进阶篇上——4.图形基本形状 ▶ 图形系统开发实战课程进阶篇上——5.图形交互操作:平移和缩放 作者信息 作者 图形开发学院 CSDN https://blog.csdn.net/2301_81340430?typeblog 官网https://graphanywhere.com
http://www.zqtcl.cn/news/440184/

相关文章:

  • 怎么在悉尼做网站dede做手机网站
  • 企业网站模板免费下载品牌建设专家库推荐表
  • 辽宁智能网站建设推荐网络营销推广方案创意
  • 安阳做一个网站多少钱东营做网站公司
  • 深圳市罗湖网站建设百度自助建站官网
  • 网站开发安装环境网站建设销售话术
  • 网站权重网站栏目划分的原则
  • 国际网站建设的目的我的百度账号登录
  • 温州网站设计定制博客和网站的区别
  • 益阳建设网站wordpress加载图片慢
  • 网站官网阜新网站开发公司
  • 适合做网站的图片印刷公司网站模板
  • 南昌哪家网站建设最好网站建设的方法有
  • 东莞做网站 动点官网百度开户流程
  • 中力建设网站怎么做自己的门户网站
  • 做的网站必须放做音乐网站的目地
  • 网站备案下来以后怎么做网页万网创始人张向东
  • 怎么做网站官方电话品牌营销策划十大要点
  • 上海自适应网站深圳网络推广外包
  • 网站的建设模式是指什么时候开始外网视频网站做泥声控
  • 免费在线观看电影电视剧网站网站建设公司哪家好 在线磐石网络
  • 域名是建网站之前申请吗怎么查看网站开发语言
  • 网站建设业务的延伸性查企业信息查询平台官网免费
  • 网站如何制作的渭南网站建设推广
  • 网站的ico怎么做简单房地产网站
  • 做室内设计通常上的网站关键词挖掘查询工具爱站网
  • 大理住房和城乡建设部网站为食堂写个网站建设
  • 做网站要icp备案吗软件定制开发 报价
  • 外国网站上做雅思考试dw做网站的导航栏
  • 公司网站建设的作用网站建设网上商城心得体会