【Java AWT 图形界面编程】使用鼠标滚轮缩放 Canvas 画布中绘制的背景图像 ( 绘制超大图像 + 鼠标拖动 + 鼠标滚轮缩放 + 以当前鼠标指针位置为缩放中心 示例 )

这篇具有很好参考价值的文章主要介绍了【Java AWT 图形界面编程】使用鼠标滚轮缩放 Canvas 画布中绘制的背景图像 ( 绘制超大图像 + 鼠标拖动 + 鼠标滚轮缩放 + 以当前鼠标指针位置为缩放中心 示例 )。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。





一、鼠标滚轮缩放的中心点设置为当前鼠标中心点 - 要点分析



鼠标指针指向界面中的 Canvas 画布某个位置 , Canvas 画布中绘制着一张超大图片 , 以该位置为中心 , 滑动鼠标滚轮时进行缩放 ;

使用鼠标滚轮缩放后 , 在 Canvas 中绘制的图片的尺寸肯定是放大或者缩小了 , 尺寸发生了改变 ;

图片缩放时 , 鼠标指针指向一个位置 , 该位置对应着一个当前 Canvas 画布中的 x, y 坐标 , 同时可以计算出当前位置对应的图片中的 水平方向的比例 和 垂直方向的比例 ;

在缩放后的图片中 , 只要保证鼠标指针指向相同的 x, y 坐标时 , 该位置对应的 水平方向的比例 和 垂直方向的比例 仍然保持不变 , 那就需要移动图片的位置 ;

  • 如果放大图片就需要将图片往左上方移动 ;
  • 如果缩小图片就需要将图片往右下方移动 ;

此时可以分析出 , 如果要实现 鼠标滚轮缩放的中心点设置为当前鼠标中心点 , 需要进行下面两个步骤的操作 :

  • 保存当前鼠标指针指向的位置 , 以及鼠标指针指向位置对应图片中坐标位置的比例 ;
  • 鼠标指针指向的位置不变 , 指向图片坐标比例不变 , 图片尺寸发生了改变 , 重新计算当前图片的放置位置 , 并设置图片位置 ;

这样图片缩放时 , 始终可以保证鼠标指向的部位保持位置不变 ;


1、保存当前鼠标指针指向的位置


首先 , 在类中定义如下成员字段 ,

  • pointer_x 和 pointer_y 记录的是鼠标指针指向的界面中 Camvas 画布中的坐标位置 ;
  • pointer_ratio_x 和 pointer_ratio_y 记录的是 鼠标指针指向位置对应图片中坐标位置的比例 ;
    public double pointer_ratio_x;
    public double pointer_ratio_y;

    public int pointer_x;
    public int pointer_y;

然后 , 在鼠标缩放之前 , 保存当前的鼠标位置及比例 ;

  • 在鼠标滚轮事件 MouseWheelEvent 中 , 可以直接通过调用 e.getX(), e.getY() 获取到当前 鼠标指针 在 Canvas 画布的坐标 ;
  • 根据该 Canvas 中的坐标 , 以及画布的偏移 , 可以计算出该坐标对应图片中的坐标位置 ;
        // 计算画布
        double canvasX = x - offsetX;
        double canvasY = y - offsetY;
  • 计算出当前的图片大小 ;
        // 计算图片大小
        double imageWidth = image.getWidth(null) * scale;  // 缩放后的图像宽度
        double imageHeight = image.getHeight(null) * scale;  // 缩放后的图像高度
  • 有了鼠标指针在图片中的位置 , 图片的尺寸 , 就可以计算出鼠标指针在图片中的比例 ;
        // 计算比例
        pointer_ratio_x = canvasX / imageWidth ;
        pointer_ratio_y = canvasY / imageHeight ;

完整代码示例 :

    /**
     * 记录滚轮缩放时鼠标指针状态
     */
    public void save(int x, int y){
        // 记录鼠标坐标
        pointer_x = x;
        pointer_y = y;

        // 计算画布
        double canvasX = x - offsetX;
        double canvasY = y - offsetY;

        // 计算图片大小
        double imageWidth = image.getWidth(null) * scale;  // 缩放后的图像宽度
        double imageHeight = image.getHeight(null) * scale;  // 缩放后的图像高度

        // 计算比例
        pointer_ratio_x = canvasX / imageWidth ;
        pointer_ratio_y = canvasY / imageHeight ;
    }

2、根据鼠标指针指向的位置以及比例重新计算图片位置


在鼠标滚轮缩放完成后 , 再根据鼠标指针指向的位置和比例 , 结合图片缩放后的尺寸 , 重新计算画布偏移的位置 , 以达到鼠标指向的图片元素位置基本保持不变的目的 ;

    /**
     * 计算新的比例
     */
    public void restore(){
        // 缩放后的尺寸
        double imageWidth = image.getWidth(null) * scale;  // 缩放后的图像宽度
        double imageHeight = image.getHeight(null) * scale;  // 缩放后的图像高度

        // 计算整张画布宽度
        double canvasX = imageWidth * pointer_ratio_x;
        double canvasY = imageHeight * pointer_ratio_y;

        // 计算画布偏移
        offsetX = (int) (pointer_x - canvasX);
        offsetY = (int) (pointer_y - canvasY);
    }




二、绘制超大图像 + 鼠标拖动 + 鼠标滚轮缩放 + 以当前鼠标指针位置为缩放中心 示例



在 【Java AWT 图形界面编程】Canvas 中绘制超大图片 ( 使用鼠标拖动查看全图 | 设置 JFrame 窗口自动关闭 | 获取并绘制图片 | 鼠标拖动计算位移 | 画布偏移 ) 博客中 , 绘制了超大图像 , 可以使用鼠标拖动 ;

在 【Java AWT 图形界面编程】使用鼠标滚轮放大缩小 Canvas 画布 ( 鼠标滚轮事件监听器 MouseWheelListener ) 博客中 , 新增鼠标滚轮缩放画布示例 , 但是使用鼠标拖动时 , 拖动的效果也随之缩放, 如 缩小画布后 , 移动鼠标 , 移动距离对应的缩放效果也随之缩小 ;

在 【Java AWT 图形界面编程】使用鼠标滚轮放大缩小 Canvas 画布中绘制的背景图像 ( 鼠标滚轮事件监听器 MouseWheelListener | Canvas 中绘制图像并设置图像大小 ) 博客中 , 使用缩放背景图像的方式 , 实现缩放效果 , 并同时福袋鼠标指针拖拽效果 ;

本博客中实现的案例 , 在上面的基础上 , 添加了鼠标滚轮缩放的中心点设置为当前鼠标中心点 ;


1、代码示例


import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

public class LargeCanvas extends JPanel {

    // 鼠标按下时的坐标 以及 更新后的坐标
    private int startX, startY;

    // 当前的位置偏移
    private int offsetX = 0, offsetY = 0;

    // 缩放比例,默认为 1.0
    private double scale = 1.0;

    private Image image;

    public double pointer_ratio_x;
    public double pointer_ratio_y;

    public int pointer_x;
    public int pointer_y;

    public LargeCanvas() {
        // 画布大小设置为 800 x 600
        // 绘制的图片是 2K 大小的图片
        setPreferredSize(new Dimension(800, 600));

        // 添加鼠标滚轮监听器
        addMouseWheelListener(new MouseWheelListener() {
            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                // 保存当前的鼠标位置及比例
                save(e.getX(), e.getY());
                int notches = e.getWheelRotation();
                if (notches < 0) {
                    // 滚轮向上,放大画布
                    scale *= 1.1;
                } else {
                    // 滚轮向下,缩小画布
                    scale /= 1.1;
                }
                // 基于鼠标位置和比例, 计算最新的偏移
                restore();
                repaint();  // 重新绘制画布
            }
        });

        // 为组件设置鼠标监听事件
        addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                // 记录鼠标按下时的坐标
                startX = e.getX();
                startY = e.getY();
            }
        });

        // 添加鼠标动作监听
        addMouseMotionListener(new MouseAdapter() {
            // 鼠标拖动事件
            public void mouseDragged(MouseEvent e) {
                // 统计本次鼠标移动的相对值
                int dx = e.getX() - startX;
                int dy = e.getY() - startY;

                // 偏移量累加
                offsetX += dx;
                offsetY += dy;

                // 重新绘图
                repaint();

                // 记录当前拖动后的位置
                startX += dx;
                startY += dy;
            }
        });
    }

    /**
     * 记录滚轮缩放时鼠标指针状态
     */
    public void save(int x, int y){
        // 记录鼠标坐标
        pointer_x = x;
        pointer_y = y;

        // 计算画布
        double canvasX = x - offsetX;
        double canvasY = y - offsetY;

        // 计算图片大小
        double imageWidth = image.getWidth(null) * scale;  // 缩放后的图像宽度
        double imageHeight = image.getHeight(null) * scale;  // 缩放后的图像高度

        // 计算比例
        pointer_ratio_x = canvasX / imageWidth ;
        pointer_ratio_y = canvasY / imageHeight ;
    }

    /**
     * 计算新的比例
     */
    public void restore(){
        // 缩放后的尺寸
        double imageWidth = image.getWidth(null) * scale;  // 缩放后的图像宽度
        double imageHeight = image.getHeight(null) * scale;  // 缩放后的图像高度

        // 计算整张画布宽度
        double canvasX = imageWidth * pointer_ratio_x;
        double canvasY = imageHeight * pointer_ratio_y;

        // 计算画布偏移
        offsetX = (int) (pointer_x - canvasX);
        offsetY = (int) (pointer_y - canvasY);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        // 画布进行整体偏移
        Graphics2D g2 = (Graphics2D)g;

        // 缩放画布
        //g2.scale(scale, scale);

        // 拖动画布
        g2.translate(offsetX, offsetY);

        // 获取图片
        this.image = Toolkit.getDefaultToolkit().getImage("image.jpg");

        // 绘制图形
        //g2.drawImage(image, 0, 0, this);

        // 绘制图像
        int imageWidth = (int) (image.getWidth(null) * scale);  // 缩放后的图像宽度
        int imageHeight = (int) (image.getHeight(null) * scale);  // 缩放后的图像高度
        g2.drawImage(image, 0, 0, imageWidth, imageHeight, null);
    }

    public static void main(String[] args) {
        // 创建 JFrame 窗口
        JFrame frame = new JFrame("Large Canvas");

        // 设置窗口关闭行为 点击右上角关闭按钮 关闭窗口并退出应用
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 创建画布
        LargeCanvas canvas = new LargeCanvas();

        // 将画布放入滚动布局
        JScrollPane scrollPane = new JScrollPane(canvas);

        // 将滚动布局放入窗口
        frame.getContentPane().add(scrollPane);

        // 窗口自适应
        frame.pack();

        // 窗口设置可见
        frame.setVisible(true);
    }
}

2、执行效果


执行后 , 将图像中船头的 H 标识放置在界面中心 ;
canvas中心缩放,Java AWT 图形界面编程,java,开发语言,AWT,Swing,Canvas,原力计划
将鼠标指针放在 H 位置 , 缩放 , 发现此时缩放 , 就是以当前鼠标指针为中心进行的缩放 ;

canvas中心缩放,Java AWT 图形界面编程,java,开发语言,AWT,Swing,Canvas,原力计划文章来源地址https://www.toymoban.com/news/detail-556426.html

到了这里,关于【Java AWT 图形界面编程】使用鼠标滚轮缩放 Canvas 画布中绘制的背景图像 ( 绘制超大图像 + 鼠标拖动 + 鼠标滚轮缩放 + 以当前鼠标指针位置为缩放中心 示例 )的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • canvas实现鼠标滚轮滚动缩放画布

    canvas实现鼠标滚轮滚动缩放画布效果

    2024年02月04日
    浏览(49)
  • Cesium 鼠标滚轮事件获取地图缩放等级

    Cesium 监听鼠标滚轮,滚轮每次滚动获取当前地图瓦片等级。 灵感来自:cesium获取当前地图瓦片缩放级别_右弦GISer的博客-CSDN博客_cesium 获取缩放级别 实际使用时体验并不好,最后使用监听高度的方法。

    2024年02月11日
    浏览(57)
  • 243:vue+Openlayers 更改鼠标滚轮缩放地图大小,每次缩放小一点

    第243个 点击查看专栏目录 本示例的目的是介绍如何在vue+openlayers项目中设置鼠标滚轮缩放地图大小,每次滑动一格滚轮,设定的值非默认值1。具体的设置方法,参考源代码。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果 示例效果

    2024年02月09日
    浏览(94)
  • Proe 5.0鼠标滚轮无法缩放的解决方法

    鼠标中键(也就是滚轮)在软件里起“确认”功能,滚轮上下滑动可以进行缩放,没反应的话解决办法如下: 1.win+i打开设置界面  2.在设备选项中选择鼠标按键,将悬停在·非活动窗口滚动选项关闭  3.然后就可以进行缩放了  4.按住滚轮可以旋转零件 shift+滚轮按住不放还可

    2024年02月12日
    浏览(103)
  • vue 拖动、缩放容器组件,支持移动端双指缩放和PC端鼠标滚轮缩放

    本组件基于CSS的transform实现。移动端监听touch事件(单指移动,双指移动+缩放),PC端监听mouse事件(移动)和滚动事件wheel(缩放),更新transform的translateX/translateY/scale值,从而实现缩放、移动。由于transform不会产生重排,因此不节流也可以有很好的性能,用户体验就像德芙

    2024年02月03日
    浏览(54)
  • Canvas鼠标滚轮缩放以及画布拖动(图文并茂版)

    本文会带大家认识Canvas中常用的坐标变换方法 translate 和 scale,并结合这两个方法,实现鼠标滚轮缩放以及画布拖动功能。 Canvas 绘图的缩放以及画布拖动主要通过 CanvasRenderingContext2D 提供的 translate 和 scale 两个方法实现的,先来认识下这两个方法。 translate 方法 语法: trans

    2023年04月09日
    浏览(52)
  • js 以鼠标滚轮位置为中心缩放、放大以及边界判断

    项目需求为页面上实现拖拽节点和可以在页面中通过滑动滚轮来缩放节点显示(以鼠标位置为缩放中心点)从而放大到可以看到详细的信息,节点有10000个。特此记录下实现细节 初始化变量 为节点绑定拖拽事件,拖拽事件的边界使用 Math 进行判断,比起 if 判断更加清晰快捷

    2024年02月11日
    浏览(54)
  • Echarts map3D 禁止鼠标滚轮缩放

    Echarts type为map3D 在使用时发现会存在鼠标滚轮缩放的情况 zoomSensitivity属性本质上是是否开启map3D的缩放和平移 所以也可以禁止鼠标滚轮缩放的情况 禁用这个属性就可以实现map3D 禁止鼠标滚轮缩放的需求了

    2024年02月15日
    浏览(51)
  • Fabric.js+vue 实现鼠标滚轮缩放画布+移动画布

    话不多说 直接贴代码 一、实现鼠标滚轮缩放画布 使用说明,我的canvas画布定义为 canvas,替他均不用额外设置变量。canvas = new fabric.Canvas(\\\'editorCanvas\\\', {... 二、实现鼠标按下变抓手,并可移动画布中内容 使用说明:data中定义panning: false,用来标记鼠标按下状态(是否鼠标按下)

    2024年02月09日
    浏览(55)
  • unity3D 鼠标滚轮实现物体的大小缩放

    鼠标滚轮响应函数是Input.GetAxis(\\\"Mouse ScrollWheel\\\"),函数返回值类型是float,向前滚是返回正数,向后滚是返回负数,且鼠标滚轮滑动单次函数返回值为0.1 利用返回值修改模型transform.localscale,实现模型缩放 鼠标滚轮一直向后滚,会看见模型逐渐变小,当变到很小到消失的时候,

    2024年02月08日
    浏览(81)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包