当前位置: 首页 > news >正文

wpf canvas 移动 缩放

前端

<Canvas x:Name="imageCanvas" Background="Transparent"MouseLeftButtonDown="ImageCanvas_MouseLeftButtonDown"MouseMove="ImageCanvas_MouseMove"MouseLeftButtonUp="ImageCanvas_MouseLeftButtonUp"MouseWheel="ImageCanvas_MouseWheel"ClipToBounds="True"><Image x:Name="imgAnswer" Stretch="Uniform" Source="{Binding Answer.ImgContent}" Visibility="{Binding Answer.ImgContentVisibility}"><Image.RenderTransform><MatrixTransform x:Name="imageTransform"/></Image.RenderTransform></Image>
</Canvas>

后台逻辑

    // 状态变量private Point _lastMousePosition;private bool _isDragging = false;private Matrix _matrix = Matrix.Identity;// 触摸状态private Point? _lastTouchPoint1 = null;private Point? _lastTouchPoint2 = null;// 缩放限制private const double MIN_SCALE = 0.1;private const double MAX_SCALE = 10.0;private void ImageCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){if (imgAnswer.Visibility != Visibility.Visible || imgAnswer.Source == null)return;_isDragging = true;_lastMousePosition = e.GetPosition(imageCanvas);imageCanvas.CaptureMouse();imgAnswer.Cursor = Cursors.Hand;e.Handled = true;}private void ImageCanvas_MouseMove(object sender, MouseEventArgs e){if (!_isDragging || e.LeftButton != MouseButtonState.Pressed)return;if (imgAnswer.Visibility != Visibility.Visible || imgAnswer.Source == null)return;try{Point currentPosition = e.GetPosition(imageCanvas);double deltaX = currentPosition.X - _lastMousePosition.X;double deltaY = currentPosition.Y - _lastMousePosition.Y;_matrix.OffsetX += deltaX;_matrix.OffsetY += deltaY;imageTransform.Matrix = _matrix;_lastMousePosition = currentPosition;e.Handled = true;}catch{// 忽略错误}}private double _currentScale = 1.0; // 当前缩放比例private void ImageCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e){_isDragging = false;imageCanvas.ReleaseMouseCapture();imgAnswer.Cursor = Cursors.Arrow;e.Handled = true;}private void ImageCanvas_MouseWheel(object sender, MouseWheelEventArgs e){// 计算缩放因子(滚轮向上放大,向下缩小)double scaleFactor = e.Delta > 0 ? 1.1 : 0.9;_currentScale *= scaleFactor;// 获取鼠标当前位置(作为缩放中心)Point center = e.GetPosition(imageCanvas);// 应用缩放变换到所有笔迹ApplyScaleToAllStrokes(scaleFactor, center);e.Handled = true;}// 应用缩放private void ApplyScaleToAllStrokes(double scaleFactor, Point center){// 创建缩放矩阵(以 center 为中心)_matrix.Translate(-center.X, -center.Y);  // 平移到原点_matrix.Scale(scaleFactor, scaleFactor);  // 缩放_matrix.Translate(center.X, center.Y);   // 平移回原中心// 应用变换到笔迹imageTransform.Matrix = _matrix;}
http://www.jsqmd.com/news/473350/

相关文章:

  • YOLO-V5目标检测实战:识别图片中物体位置,附完整代码示例
  • 【CVPR26-孙栩-北京大学】Conan:像侦探一样对多尺度视觉证据进行渐进式学习推理
  • 打破PDF笔记壁垒:Obsidian PDF Plus让文献管理效率提升300%的秘密
  • 2026 深度审计:ChatGPT Plus 国内充值封锁现状与“免密码”激活方案实测
  • translategemma-12b-it效果实测:技术文档扫描件翻译准确率惊人
  • Hotkey Detective:Windows热键冲突的智能诊断解决方案
  • Ostrakon-VL-8B MySQL数据可视化:将图片分析结果转化为商业洞察
  • 南北阁 Nanbeige 4.1-3B Streamlit定制:支持暗色模式与字体大小调节
  • LangGraph实战:AI从此‘过目不忘’——知识库+记忆宫殿实现持续学习,拒绝信息丢失!
  • 文墨共鸣作品展示:当政务文件遇见水墨风AI的惊艳分析效果
  • 5-4分析活动投票情况
  • 当Android Studio遇上AI:用快马解决图片处理中的内存优化难题
  • WAN2.2文生视频零基础教程:5分钟用中文提示词生成你的第一个AI视频
  • Z-Image-GGUF模型推理性能测试:不同GPU配置下的速度对比
  • 使用Yi-Coder-1.5B进行Node.js环境配置
  • 快马平台五分钟速成:用clowdbot快速搭建你的第一个聊天机器人原型
  • SD3.5 FP8镜像问题解决:常见部署错误与解决方法汇总
  • 立创 OPEN HMI 人机交互模块硬件调试与Linux驱动适配实战
  • Qwen3模型LaTeX文档智能辅助:从黑板报到学术排版
  • 【常见错误】1、Java并发工具类四大坑:从ThreadLocal到ConcurrentHashMap,你踩过几个?
  • 即梦LoRA多版本生成效果展示:动态热切换系统实测,惊艳图片一键生成
  • 零基础高效抖音评论采集工具:从数据获取到Excel分析全流程指南
  • 嵌入式设备可行吗?DeepSeek-R1低功耗部署探索
  • 立创开源ESP32迷你无人机:从PCB设计到飞控调参全流程实战指南
  • 3分钟解锁游戏素材:RPG Maker资源提取新方案
  • figmaCN插件:3分钟实现Figma全界面中文化的5大核心方案
  • 庐山派K230开发板PWM实战:从GPIO复用、蜂鸣器驱动到舵机控制
  • 3分钟掌握视频解析工具:抖音无水印视频高效提取完整方案
  • 全桥与半桥LLC谐振DC-DC变换器的设计与Simulink仿真,含开环与电压闭环仿真及电路参...
  • 网盘加速工具提升下载效率的全面指南