Skip to content

lin2006yuo/graph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

72 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

郁金香 demo


时间轴 Timeline


选择框 demo

基本版本 demo
拖拽版本 demo

矩阵变换


Jelly Effect

ball demo
粘体 demo


流程图

preview
发育中...(2021.1.10 太监了)
bg
zoom - done
drag - done
menu - done
node

  1. 创建 - done
  2. 拖拽 - done
  3. 缩放 - done

mark

GraphCanvas(canvas, graph)

  • graph.attachCanvas 将 graph 和 graphcanvas 关联
  • setCanvas 导入 canvas 对象
  • bindEvent
  • startRending
  • draw *requestAnimation 持续绘制
  • ds.computeVisibleArea 计算可视区域
  • drawBackCanvas *网格
  • drawFrontCanvase
  1. beginPath 清除 path

缩放 demo

使用 ctx.dragImage(canvas, 0, 0), 具体流程:

  1. 根据滚轮事件调整 scale 大小
  2. 设置 canvas 的 scale ctx.scale(scale, scale), 设置 canvastranslate(offsetX, offsetY)
  3. 绘制ctx.dragImage(canvas, 0, 0)

ctx.save

注意在绘制前需要ctx.save()存储当前状态,绘制后再重置ctx.restore()。因为scale的变化都是基于初始状态,也就是scale = 1,如果不重置,那么下一次scale变化就是基于上一次的scale变化,会导致scale过快的情况。
举例: scale变化情况为 1 -> 1.1. -> 1.2 -> 1.3 -> 1.4,第一次scale后的大小为1 * 1.1,第二次scale的大小正确应该为1 * 1.2,如果不重置当前状态,那么第二次scale大小为1.1 * 1.2

scale-origin

canvas 缩放原点 scale-origin 默认为左上角(0,0),在缩放的时候需要转换原点,canvas 没有提供 api,可通过 translate 实现。
eg: 设起始点为 a1(x, y), 缩放比为 n, 则缩放后的点为 a2(nx, ny)
可知: x 轴偏移值为x - nx,y 轴偏移的位置值为y- ny,(先缩放再偏移,原因比较复杂)由于做了缩放,实际上求出来的偏移值是经过缩放的,所以需要再除以 n
最终解: x -> (x - nx)/n = x/n - x
y -> (y - ny)/n = y/n -y

拖拽 demo

拖拽两种实现方式

  1. 记录点击时坐标 a1(x1, y1),移动后的坐标 a2(x2, y2), 得出偏移值(x2 - x1, y2 - y1), 将元素坐标设置为���移值
let offset = [0, 0]
let down_mouse = [x1, y1]
let cur_mouse = [x2, y2]

let delta = [x2 - x1, y2 - y1]

offset[0] = delta[0]
offset[1] = delta[1]
  1. 上一次移动时的坐标 a1(x1, y1), 移动后的坐标 a2(x2, y2), 得出偏移值(x2 - x1, y2 - y1), 将元素坐标累加偏移值
let offset = [0, 0]
let last_mouse = [x1, y1]
let cur_mouse = [x2, y2]

let delta = [x2 - x1, y2 - y1]
// 刷新上次移动时的坐标
last_mouse[0] = cur_mouse[0]
last_mouse[1] = cur_mouse[1]
// 累加, 因为偏移值是根据上一次状态
offset[0] += delta[0]
offset[1] += delta[1]

拖拽对象

  1. 元素
    方法1、方法2
  2. 画布
    拖拽画布通过translate方法实现,由于translate的转换原点translate-origin固定为canvas左上角(0,0),如果用方法1实现拖拽,第二次拖拽会出现不符合预期的结果❌demo,原因是第二次拖拽转换原点应该为上一次translate的值, 但在这里转换原点始终为(0,0),第二次拖拽转换原点应该为上一次translate的值。
    ∴画布拖拽使用方法2,demo

坐标系 demo

  1. 拖拽
    拖拽方法二的位移差除以scale再累加
let offset = [0, 0]
let last_mouse = [x1, y1]
let cur_mouse = [x2, y2]

let delta = [x2 - x1, y2 - y1]
// 刷新上次移动时的坐标
last_mouse[0] = cur_mouse[0]
last_mouse[1] = cur_mouse[1]
// 累加, 因为偏移值是根据上一次状态
// delta除以scale再做累加
offset[0] += delta[0] / scale
offset[1] += delta[1] / scale

// draw
ctx.scale(scale, scale)
ctx.translate(offset[0], offset[1])
  1. 缩放
    前后两次缩放的值除以scale再减translate,然后做差累加
let _scale = 1
function pos(pos) {
    let out = [0,0]
    out[0] = pos[0] / _scale - translate[0]
    out[1] = pos[1] / _scale - translate[1]
    return out
}

old_local = pos([x, y])
_scale = new_scale
new_local = pos([x, y])
let delta = [
    new_local[0] - old_local[0], 
    new_local[1] - old_local[1]
]
offset[0] += delta[0]
offset[1] += delta[1]

// draw
ctx.scale(scale, scale)
ctx.translate(offset[0], offset[1])

阻止右键默认菜单

mouseup contextmenu mousedown 配合使用

root.addEventListener(
    "mouseup",
    function (e) {
        e.preventDefault();
        return true;
    },
    true
);
root.addEventListener(
    "contextmenu",
    function (e) {
        // e.button === 2右键
        if (e.button !== 2) {
            return false;
        }
        e.preventDefault();
        return false;
    },
    true
);

root.addEventListener(
    "mousedown",
    function (e) {
        if (e.button === 2) {
            that.close();
            e.preventDefault();
            return true;
        }
    },
    true
);

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors