最近在使用d3 zoom得时候 遇到一个小坑
直接对元素添加 zoom事件 会有很大得抖动,查文档 看代码之后发现是 由于元素在不断变化, 所以计算基础值也不不断变化,所以会导致计算出来得值 忽大忽小 从而造成抖动
解决办法 在他父元素上添加事件 然后在子元素上添加style 方法
具体代码
- _addZoomEvent(canvas, container) {
- const _container = d3.select(container);
- const _canvas = d3.select(canvas);
- let isFirstZoom = true;
- // 为了防止抖动 所以把事件添加到父级元素上 防止每次不停计算 而产生抖动
- jsPlumb.setZoom(this._scale);
- _canvas.style('transform', `scale(${this._scale})`);
- _canvas.style('transform-origin', '0 0');
- _container.call(d3
- .zoom()
- .scaleExtent(this._zoomOption.range)
- .on('zoom', e => {
- // 兼容5.xx 版本 新版本去掉了d3.event 使用 e
- e = e || d3.event;
- if (isFirstZoom) {
- e.transform.k = this._scale;
- isFirstZoom = false;
- }
-
- let { k, x, y } = e.transform;
- _canvas.style('transform', `translate(${x}px, ${y}px) scale(${k})`);
- jsPlumb.setZoom(k);
- _canvas.style('transform-origin', '0 0');
- }));
- this._eventManagement.addCancelHandler(() => {
- _container.on('zoom', null);
- });
- }
顺便在记录一下 我们在对dom添加事件得时候 要记得销毁事件 所以我们对事件做一个整体统一处理 具体代码如下
- export class EventManagement {
- _eventList = [];
- constructor() {}
- clearEvents() {
- this._eventList.forEach(fn => fn());
- }
- addEvent(target, event, cb, opts) {
- target.addEventListener(
- event,
- e => {
- cb(e);
- },
- opts
- );
- this._eventList.push(() => {
- target.removeEventListener(event, cb);
- });
- }
-
- addCancelHandler(handler) {
- this._eventList.push(handler);
- }
- }
使用时 创建一个实例出来 所有事件有关方法都挂在到实例上 最后销毁
- _eventManagement = new EventManagement();
- this._eventManagement.addEvent(canvas, 'mouseup', e => {
- this._analyzeCanvasMouseup(e);
- });
- this._eventManagement.clearEvents();