Matlab 虽然自带的 imshow 也支持鼠标滚轮放大缩小,鼠标左键拖动放大的图片调整视野,但是一旦把 menubar 给关了,就丢失了 zoom 和 pan 的功能,最离谱的是——zoom 和 pan 还只能开一个,开了 zoom 就不能开 pan。所以打算自己撸一个同时支持鼠标滚轮放大图片和左键拖动图片的功能。
实现方案
具体实现功能
- 鼠标滚轮放大/缩小图片
- 鼠标左键长按拖拽图片
- 鼠标左键双击恢复图片
鼠标滚轮放大图片
比较简单,监听 Figure 的鼠标滚轮事件 WindowScrollWheelFcn,根据滚动值 event.VerticalScrollCount 来判断滚动方向进行放大或缩小
1 | function im_zoom(self,~,event) |
鼠标拖拽图片
会复杂一点,
-
鼠标左键点击,ax.UserData.status 设置为’axes_paning’(默认情况为’idle’),并记录当前鼠标位置
1
2
3
4
5function im_pan_start(self)
self.ax.UserData.status = 'axes_paning';
self.ax.UserData.previous_point = self.ax.CurrentPoint;
set(self.fig,'Pointer','fleur'); % change mouse point
end -
监听鼠标移动事件,根据鼠标移动的位置,来更新 ax 的 XLim 和 YLim,实现平移效果为了只有鼠标按住左键才能拖动,只有 ax.UserData.status 为’axes_paning’时,才进行平移。
1
2
3
4
5
6
7
8
9
10
11
12
13function fig_motion(self,~,~)
currentPosition = self.ax.CurrentPoint;
x = currentPosition(1,1);
y = currentPosition(1,2);
if x >= self.ax.XLim(1) && x <= self.ax.XLim(2) && y >= self.ax.YLim(1) && y <= self.ax.YLim(2)
switch self.ax.UserData.status
case "axes_paning"
self.im_panning()
otherwise
return
end
end
end -
当鼠标左键抬起后,将 ax.UserData.status 设置为’idle’,使得 fig_motion 功能失效
1
2
3
4function im_pan_stop(self)
self.ax.UserData.status = 'idle';
set(self.fig,'Pointer','arrow'); % recover mouse point
end
鼠标左键双击恢复图片
-
载入图片时,记录 ax 原始的 XLim 和 YLim
1
2self.ax.XLim = self.ax.UserData.origin_xlim;
self.ax.YLim = self.ax.UserData.origin_ylim; -
左键双击时,恢复为原始的 XLim 和 YLim
1
2
3
4
5
6
7
8
9
10
11
12
13function fig_click(self,src,~)
set(self.fig,'Pointer','arrow');
switch src.SelectionType
case 'open' % Double Click
% Double Click to restore origin xlim and ylim
self.im_zoom_restore()
end
end
function im_zoom_restore(self)
self.ax.XLim = self.ax.UserData.origin_xlim;
self.ax.YLim = self.ax.UserData.origin_ylim;
end
全部代码
1 | classdef FigureManualZoom < handle |