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

让别人做网站的步骤腾讯广告平台

让别人做网站的步骤,腾讯广告平台,专业的企业网站优化公司,wordpress摄影主题 lens本章响应小伙伴的反馈,除了算法自动画连接线(仍需优化完善),实现了可以手动绘制直线、折线连接线功能。 请大家动动小手,给我一个免费的 Star 吧~ 大家如果发现了 Bug,欢迎来提 Issue 哟~ github源码 gitee…

本章响应小伙伴的反馈,除了算法自动画连接线(仍需优化完善),实现了可以手动绘制直线、折线连接线功能。

请大家动动小手,给我一个免费的 Star 吧~

大家如果发现了 Bug,欢迎来提 Issue 哟~

github源码

gitee源码

示例地址

模式切换

在这里插入图片描述

前置工作

连接线 模式种类

// src/Render/types.ts
export enum LinkType {'auto' = 'auto','straight' = 'straight', // 直线'manual' = 'manual' // 手动折线
}

连接线 模式状态

// src/Render/draws/LinkDraw.ts// 连接线(临时)
export interface LinkDrawState {// 略linkType: Types.LinkType // 连接线类型linkManualing: boolean // 是否 正在操作拐点
}

连接线 模式切换方法

// src/Render/draws/LinkDraw.ts/*** 修改当前连接线类型* @param linkType Types.LinkType*/changeLinkType(linkType: Types.LinkType) {this.state.linkType = linkTypethis.render.config?.on?.linkTypeChange?.(this.state.linkType)}

连接线 模式切换按钮

<!-- src/App.vue --><button @click="onLinkTypeChange(Types.LinkType.auto)":disabled="currentLinkType === Types.LinkType.auto">连接线:自动</button>
<button @click="onLinkTypeChange(Types.LinkType.straight)":disabled="currentLinkType === Types.LinkType.straight">连接线:直线</button>
<button @click="onLinkTypeChange(Types.LinkType.manual)":disabled="currentLinkType === Types.LinkType.manual">连接线:手动</button>

连接线 模式切换事件

// src/App.vue
const currentLinkType = ref(Types.LinkType.auto)function onLinkTypeChange(linkType: Types.LinkType) {(render?.draws[Draws.LinkDraw.name] as Draws.LinkDraw).changeLinkType(linkType)
}

当前 连接对(pair) 记录当前 连接线 模式

// src/Render/draws/LinkDraw.tsexport class LinkDraw extends Types.BaseDraw implements Types.Draw {// 略override draw() {// 略// 连接点for (const point of points) {// 略// 非 选择中if (group && !group.getAttr('selected')) {// 略const anchor = this.render.layer.findOne(`#${point.id}`)if (anchor) {// 略circle.on('mouseup', () => {if (this.state.linkingLine) {// 略// 不同连接点if (line.circle.id() !== circle.id()) {// 略if (toGroup) {// 略if (fromPoint) {// 略if (toPoint) {if (Array.isArray(fromPoint.pairs)) {fromPoint.pairs = [...fromPoint.pairs,{// 略linkType: this.state.linkType // 记录 连接线 类型}]}// 略}}}}// 略}})// 略}}}}
}

直线

在这里插入图片描述

绘制直线相对简单,通过判断 连接对(pair)记录的 连接线 模式,从起点绘制一条 Line 到终点即可:

// src/Render/draws/LinkDraw.tsexport class LinkDraw extends Types.BaseDraw implements Types.Draw {// 略override draw() {// 略// 连接线for (const pair of pairs) {if (pair.linkType === Types.LinkType.manual) {// 略,手动折线} else if (pair.linkType === Types.LinkType.straight) {// 直线if (fromGroup && toGroup && fromPoint && toPoint) {const fromAnchor = fromGroup.findOne(`#${fromPoint.id}`)const toAnchor = toGroup.findOne(`#${toPoint.id}`)// 锚点信息const fromAnchorPos = this.getAnchorPos(fromAnchor)const toAnchorPos = this.getAnchorPos(toAnchor)const linkLine = new Konva.Line({name: 'link-line',// 用于删除连接线groupId: fromGroup.id(),pointId: fromPoint.id,pairId: pair.id,linkType: pair.linkType,points: _.flatten([[this.render.toStageValue(fromAnchorPos.x),this.render.toStageValue(fromAnchorPos.y)],[this.render.toStageValue(toAnchorPos.x), this.render.toStageValue(toAnchorPos.y)]]),stroke: 'red',strokeWidth: 2})this.group.add(linkLine)}} else {// 略,原算法画连接线逻辑}}}
}

折线

在这里插入图片描述

绘制折线,先人为定义 3 种“点”:
1、连接点,就是原来就有的。
2、拐点(待拐),蓝色的,从未拖动过的,一旦拖动,会新增拐点记录。
3、拐点(已拐),绿色的,已经拖动过的,依然可以拖动,但不会新增拐点记录。

在这里插入图片描述

请留意下方代码的注释,关键:

  • fromGroup 会记录 拐点 manualPoints。
  • 连接线 的绘制是从 起点 -> 拐点(们)-> 终点(linkPoints)。
  • 拐点正在拖动时,绘制临时的虚线 Line。
  • 分别处理 拐点(待拐)和 拐点(已拐)两种情况。

处理 拐点(待拐)和 拐点(已拐)主要区别是:

  • 处理 拐点(待拐),遍历 linkPoints 的时候,是成对遍历的。
  • 处理 拐点(已拐),遍历 linkPoints 的时候,是跳过 起点 和 终点 的。
  • 拖动 拐点(待拐),会新增拐点记录。
  • 拖动 拐点(已拐),不会新增拐点记录。
// src/Render/draws/LinkDraw.tsexport class LinkDraw extends Types.BaseDraw implements Types.Draw {// 略override draw() {// 略// 连接线for (const pair of pairs) {if (pair.linkType === Types.LinkType.manual) {// 手动折线if (fromGroup && toGroup && fromPoint && toPoint) {const fromAnchor = fromGroup.findOne(`#${fromPoint.id}`)const toAnchor = toGroup.findOne(`#${toPoint.id}`)// 锚点信息const fromAnchorPos = this.getAnchorPos(fromAnchor)const toAnchorPos = this.getAnchorPos(toAnchor)// 拐点(已拐)记录const manualPoints: Array<{ x: number; y: number }> = Array.isArray(fromGroup.getAttr('manualPoints'))? fromGroup.getAttr('manualPoints'): []// 连接点 + 拐点const linkPoints = [[this.render.toStageValue(fromAnchorPos.x),this.render.toStageValue(fromAnchorPos.y)],...manualPoints.map((o) => [o.x, o.y]),[this.render.toStageValue(toAnchorPos.x), this.render.toStageValue(toAnchorPos.y)]]// 连接线const linkLine = new Konva.Line({name: 'link-line',// 用于删除连接线groupId: fromGroup.id(),pointId: fromPoint.id,pairId: pair.id,linkType: pair.linkType,points: _.flatten(linkPoints),stroke: 'red',strokeWidth: 2})this.group.add(linkLine)// 正在拖动效果const manualingLine = new Konva.Line({stroke: '#ff0000',strokeWidth: 2,points: [],dash: [4, 4]})this.group.add(manualingLine)// 拐点// 拐点(待拐)for (let i = 0; i < linkPoints.length - 1; i++) {const circle = new Konva.Circle({id: nanoid(),pairId: pair.id,x: (linkPoints[i][0] + linkPoints[i + 1][0]) / 2,y: (linkPoints[i][1] + linkPoints[i + 1][1]) / 2,radius: this.render.toStageValue(this.render.bgSize / 2),stroke: 'rgba(0,0,255,0.1)',strokeWidth: this.render.toStageValue(1),name: 'link-manual-point',// opacity: 0,linkManualIndex: i // 当前拐点位置})// hover 效果circle.on('mouseenter', () => {circle.stroke('rgba(0,0,255,0.8)')document.body.style.cursor = 'pointer'})circle.on('mouseleave', () => {if (!circle.attrs.dragStart) {circle.stroke('rgba(0,0,255,0.1)')document.body.style.cursor = 'default'}})// 拐点操作circle.on('mousedown', () => {const pos = circle.getAbsolutePosition()// 记录操作开始状态circle.setAttrs({// 开始坐标dragStartX: pos.x,dragStartY: pos.y,// 正在操作dragStart: true})// 标记状态 - 正在操作拐点this.state.linkManualing = true})this.render.stage.on('mousemove', () => {if (circle.attrs.dragStart) {// 正在操作const pos = this.render.stage.getPointerPosition()if (pos) {// 磁贴const { pos: transformerPos } = this.render.attractTool.attract({x: pos.x,y: pos.y,width: 1,height: 1})// 移动拐点circle.setAbsolutePosition(transformerPos)// 正在拖动效果const tempPoints = [...linkPoints]tempPoints.splice(circle.attrs.linkManualIndex + 1, 0, [this.render.toStageValue(transformerPos.x - stageState.x),this.render.toStageValue(transformerPos.y - stageState.y)])manualingLine.points(_.flatten(tempPoints))}}})circle.on('mouseup', () => {const pos = circle.getAbsolutePosition()if (Math.abs(pos.x - circle.attrs.dragStartX) > this.option.size ||Math.abs(pos.y - circle.attrs.dragStartY) > this.option.size) {// 操作移动距离达到阈值// stage 状态const stageState = this.render.getStageState()// 记录(插入)拐点manualPoints.splice(circle.attrs.linkManualIndex, 0, {x: this.render.toStageValue(pos.x - stageState.x),y: this.render.toStageValue(pos.y - stageState.y)})fromGroup.setAttr('manualPoints', manualPoints)}// 操作结束circle.setAttrs({dragStart: false})// state 操作结束this.state.linkManualing = false// 销毁circle.destroy()manualingLine.destroy()// 更新历史this.render.updateHistory()// 重绘this.render.redraw()})this.group.add(circle)}// 拐点(已拐)for (let i = 1; i < linkPoints.length - 1; i++) {const circle = new Konva.Circle({id: nanoid(),pairId: pair.id,x: linkPoints[i][0],y: linkPoints[i][1],radius: this.render.toStageValue(this.render.bgSize / 2),stroke: 'rgba(0,100,0,0.1)',strokeWidth: this.render.toStageValue(1),name: 'link-manual-point',// opacity: 0,linkManualIndex: i // 当前拐点位置})// hover 效果circle.on('mouseenter', () => {circle.stroke('rgba(0,100,0,1)')document.body.style.cursor = 'pointer'})circle.on('mouseleave', () => {if (!circle.attrs.dragStart) {circle.stroke('rgba(0,100,0,0.1)')document.body.style.cursor = 'default'}})// 拐点操作circle.on('mousedown', () => {const pos = circle.getAbsolutePosition()// 记录操作开始状态circle.setAttrs({dragStartX: pos.x,dragStartY: pos.y,dragStart: true})// 标记状态 - 正在操作拐点this.state.linkManualing = true})this.render.stage.on('mousemove', () => {if (circle.attrs.dragStart) {// 正在操作const pos = this.render.stage.getPointerPosition()if (pos) {// 磁贴const { pos: transformerPos } = this.render.attractTool.attract({x: pos.x,y: pos.y,width: 1,height: 1})// 移动拐点circle.setAbsolutePosition(transformerPos)// 正在拖动效果const tempPoints = [...linkPoints]tempPoints[circle.attrs.linkManualIndex] = [this.render.toStageValue(transformerPos.x - stageState.x),this.render.toStageValue(transformerPos.y - stageState.y)]manualingLine.points(_.flatten(tempPoints))}}})circle.on('mouseup', () => {const pos = circle.getAbsolutePosition()if (Math.abs(pos.x - circle.attrs.dragStartX) > this.option.size ||Math.abs(pos.y - circle.attrs.dragStartY) > this.option.size) {// 操作移动距离达到阈值// stage 状态const stageState = this.render.getStageState()// 记录(更新)拐点manualPoints[circle.attrs.linkManualIndex - 1] = {x: this.render.toStageValue(pos.x - stageState.x),y: this.render.toStageValue(pos.y - stageState.y)}fromGroup.setAttr('manualPoints', manualPoints)}// 操作结束circle.setAttrs({dragStart: false})// state 操作结束this.state.linkManualing = false// 销毁circle.destroy()manualingLine.destroy()// 更新历史this.render.updateHistory()// 重绘this.render.redraw()})this.group.add(circle)}}} else if (pair.linkType === Types.LinkType.straight) {// 略,直线} else {// 略,原算法画连接线逻辑}}}
}

最后,关于 linkManualing 状态,会用在 2 个地方,避免和其它交互产生冲突:

// src/Render/handlers/DragHandlers.ts// 略export class DragHandlers implements Types.Handler {// 略  handlers = {stage: {mousedown: (e: Konva.KonvaEventObject<GlobalEventHandlersEventMap['mousedown']>) => {// 拐点操作中,防止异常拖动if (!(this.render.draws[Draws.LinkDraw.name] as Draws.LinkDraw).state.linkManualing) {// 略}},// 略}}
}
// src/Render/tools/LinkTool.ts// 略
export class LinkTool {// 略pointsVisible(visible: boolean, group?: Konva.Group) {// 略// 拐点操作中,此处不重绘if (!(this.render.draws[Draws.LinkDraw.name] as Draws.LinkDraw).state.linkManualing) {// 重绘this.render.redraw()}}// 略
}

Done!

More Stars please!勾勾手指~

源码

gitee源码

示例地址

http://www.dt0577.cn/news/32041.html

相关文章:

  • 做一个属于自己的网站免费的短视频app大全下载
  • 网站开发 天津深圳网站开发公司
  • 京东网站建设吗推广普通话活动方案
  • 做菠菜网站代理犯法吗网站的收录情况怎么查
  • 抚州网站制作太原百度关键词优化
  • 常州商城网站制作公司外贸营销型网站建设公司
  • 关于一学一做的短视频网站google广告投放
  • 企业网站的设计要求有哪些淘宝优化标题都是用什么软件
  • 哪些网站可以做代理商济南seo怎么优化
  • wordpress 转 app无忧seo
  • 做购物网站哪个cms好用百度搜索推广采取
  • 金泉网做网站百度怎么推广自己的店铺
  • 个体户可以做企业网站宝鸡seo
  • 多用户商城(c2c)网站制作方案网站运营工作的基本内容
  • 南通医院网站建设方案简述影响关键词优化的因素
  • 单位网站建设规划哈尔滨seo和网络推广
  • app下载汅api免费安卓全国seo搜索排名优化公司
  • 网站建设开发五行属性全媒体广告策划营销
  • 徐州睢宁建设网站百度竞价排名什么意思
  • 做公众号时图片的网站上海公司网站seo
  • 宾馆网站建设方案福建百度开户
  • 湖南微信网站公司简介新浪博客seo
  • 如何让做树洞网站企业文化ppt
  • 网站开发备案最近新闻
  • wordpress站点地图优化今天最火的新闻头条
  • wordpress 段落seo优化教程
  • 做网站能挣钱不百度信息流优化
  • 专业的网站建设网络seo公司排行
  • 主要网站维护软件关于网站推广
  • cms网站制作企业网站建设服务