首页 > 代码库 > 解决mxGraph放大/缩小在非IE浏览器下overlay图标位置不变化的问题

解决mxGraph放大/缩小在非IE浏览器下overlay图标位置不变化的问题

首先要创建一个工具栏,并为工具栏中的放大、缩小按钮定义事件。

<div id="toolbar" style="float:left;margin-top:5px;margin-left: 5px;line-height: 35px;">
     <img src=http://www.mamicode.com/"src/images/zoomin.gif" action="zoomIn" title="放大" width="16" height="16" />>
var canvas=ylEditor.ylCanvas;//ylEditor.ylCanvas是我定义的一个mxGraph实例的全局对象。
var toolbar= $('#toolbar');
toolbar.find('img').css( {
    'margin-right' : '5px',
    'cursor' : 'pointer'
}).click(function() {
    switch ($(this).attr('action')) {
        case 'zoomIn':
            canvas.zoomIn();
            break;
        case 'zoomOut':
            canvas.zoomOut();
            break;
    }
});

下面是一个创建overlay的方法,这个方法中为图形创建了3个overlay图标,在图形的左上角一个,右上角两个。

ylCommon.createOverlay = function (cell) {
    var canvas=ylEditor.ylCanvas;
    var img, point, align = 'left', title;
    var iconSize = 16;
    
    img = '../../images/icon-unlock.png';
    title = '已解锁-点击锁定';
    point = new mxPoint(cell.geometry.width - 15, 10);
    var overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');

    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
    
    img = '../../images/icon-diagram.png';
    title = '辐射图';
    point = new mxPoint(cell.geometry.width - 35, 10);
    overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');
    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
    
    img = 'src/images/properties.gif';
    title = '属性';
    point = new mxPoint(27, 10);
    overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');
    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
}

执行以上代码,在IE下正常,在火狐和谷歌浏览器下显示不正常,overlay图标位置没有发生改变。主要原因是因为调用zoomIn()和zoomOut()方法之后画布显示比例发生了变化,而overlay的坐标是固定的。那么只要对overlay坐标也根据这个比例来创建是不是就解决问题了呢?好,下面就来改造创建overlay的这个方法。

ylCommon.createOverlay = function (cell) {
    var canvas=ylEditor.ylCanvas;
    var img, point, align = 'left', title;
    var iconSize = 16;
    var scale=canvas.getView().getScale();//获取当前画布的显示比例,把坐标的x,y都乘以这个比例
    img = '../../images/icon-unlock.png';
    title = '已解锁-点击锁定';
    point = new mxPoint((cell.geometry.width - 15)*scale, 10*scale);
    var overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');

    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
    
    img = '../../images/icon-diagram.png';
    title = '辐射图';
    point = new mxPoint((cell.geometry.width - 35)*scale, 10*scale);
    overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');
    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
    
    img = 'src/images/properties.gif';
    title = '属性';
    point = new mxPoint(27*scale, 10*scale);
    overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');
    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
}

改造完成,问题是否解决了呢?经过验证,并没有解决,这是为什么呢?可能是因为这个方法只是针对创建overlay的时候生效,在执行放大缩小的时候,并不会再重新创建overlay。我想当然的认为mxGraph会根据这个比例来重新渲染overlay。好吧,那我就在执行放大缩小之后,再重新创建一下overlay的好了。

定义一个重新创建overlay的方法。

ylCommon.resetOverlay=function(){
    var scale=ylEditor.ylCanvas.getView().getScale();
    var oldSelectCells=ylEditor.ylCanvas.getSelectionCells();//获取当前选中的图形
    if(!mxClient.IS_IE){
        ylEditor.ylCanvas.selectAll();
        var cells=ylEditor.ylCanvas.getSelectionCells();
        ylEditor.ylCanvas.clearSelection();
        ylEditor.ylCanvas.setSelectionCells(oldSelectCells);//重新选中
        ylEditor.ylModel.beginUpdate();
        for(var i=0;i<cells.length;i++){
            ylEditor.ylCanvas.clearCellOverlays(cells[i]);//移除overlay
            ylCommon.createOverlay(cells[i]);//重新创建overlay
        }
        ylEditor.ylModel.endUpdate();
    }
}

然后在点击放大和缩小的时候调用一下这个方法。

toolbar.find('img').css( {
    'margin-right' : '5px',
    'cursor' : 'pointer'
}).click(function() {
    switch ($(this).attr('action')) {
        case 'zoomIn':
            canvas.zoomIn();
            ylCommon.resetOverlay();
            break;
        case 'zoomOut':
            canvas.zoomOut();
            ylCommon.resetOverlay();
            break;
    }
});
好了,问题终于解决了。