news 2026/6/13 16:15:49

Flutter 实现一个容器内部元素可平移、缩放和旋转等功能(九)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter 实现一个容器内部元素可平移、缩放和旋转等功能(九)

Flutter 实现一个容器内部元素可平移、缩放和旋转等功能(九)

Flutter: 3.35.7

今天的功能完成那基本功能就完成了,所以给出github链接:

https://github.com/yhtqw/FrontEndDemo/tree/main/flutter_demo/lib/pages/transform_use/widgets/multiple_transform

前面我们简单实现了图片元素和文本元素的新增,优先实现的功能,很多地方还可以优化。今天我来讨论一下文本元素的拖动缩放。

对于文本元素,文本元素的高度是由文本自身的样式来决定的,所以我们限制文本元素只能缩放宽度,高度自动计算。这样就会对缩放区域进行元素类型判断,如果是文本元素,那么只缩放宽度,高度自适应;如果是其他元素,则同上对宽度高度进行缩放。既然功能又区别,那么icon也要有区别,那么之前的元素操作区域得做出更改,新增这种特殊功能区分元素类型对应图标不一样的配置:

classResponseAreaModel{// 其他省略.../// 元素类型不同展示不同的操作iconfinalMap<String,String>?iconConfig;// 其他省略...}classConstantsConfig{// 其他省略...staticfinalList<ResponseAreaModel>baseAreaList=[// 其他省略...// 缩放ResponseAreaModel(areaWidth:20,areaHeight:20,xRatio:1,yRatio:1,status:ElementStatus.scale.value,icon:'assets/images/icon_scale.png',trigger:TriggerMethod.move,iconConfig:{ElementType.textType.type:'assets/images/icon_scale_text.png',},),// 其他省略...],// 其他省略...}// 其他省略...// 如果选中,则展示操作区域if(selected)...areaList.map((item)=>Positioned(top:elementItem.elementHeight*item.yRatio-item.areaHeight/2,left:elementItem.elementWidth*item.xRatio-item.areaWidth/2,child:Container(width:item.areaWidth,height:item.areaHeight,alignment:Alignment.center,decoration:BoxDecoration(color:Colors.blueAccent,borderRadius:BorderRadius.circular(item.areaWidth/2),),child:Image.asset(// 判断对应类型的图片是否单独存在item.iconConfig?[elementItem.type]??item.icon,width:item.areaWidth-ConstantsConfig.areaIconMargin,height:item.areaHeight-ConstantsConfig.areaIconMargin,fit:BoxFit.scaleDown,color:Colors.white,),),)),

运行效果:

这样我们就通过元素状态区分了特殊功能的图标展示,现在就是功能的实现了:

/// 处理元素缩放////// 通过移动点坐标[x]和[y]与按下的初始坐标,void_onScale({required double x,required double y}){if(_currentElement?.type==ElementType.textType.type){_onScaleText(x:x,y:y);}else{_onScaleBase(x:x,y:y);}}/// 抽取获取缩放需要的基础参数(double,double,double,double,double)_getScaleParams({required double x,required double y}){finaldouble oWidth=_temporary!.width;finaldouble oHeight=_temporary!.height;finaldouble oX=_temporary!.x;finaldouble oY=_temporary!.y;finaldouble resizeRatio=_calcResizeRatio(x:x,y:y);return(oWidth,oHeight,oX,oY,resizeRatio);}/// 处理非文本元素的缩放void_onScaleBase({required double x,required double y}){if(_currentElement==null||_temporary==null)return;final(oWidth,oHeight,oX,oY,resizeRatio)=_getScaleParams(x:x,y:y);double newW=oWidth*resizeRatio;double newH=oHeight*resizeRatio;finaldouble minSize=ConstantsConfig.minSize;// 以短边为基准来计算最小宽高if(oWidth<=oHeight&&newW<minSize){newW=minSize;newH=minSize*oHeight/oWidth;}elseif(oHeight<oWidth&&newH<minSize){newH=minSize;newW=minSize*oWidth/oHeight;}// 以长边为基准来计算最大宽高if(oWidth>=oHeight&&newW>=_transformWidth){newW=_transformWidth;newH=_transformWidth*oHeight/oWidth;}elseif(oHeight>oWidth&&newH>=_transformHeight){newH=_transformHeight;newW=_transformHeight*oWidth/oHeight;}if(newW==_currentElement?.elementWidth&&newH==_currentElement?.elementHeight){return;}_currentElement=_currentElement?.copyWith(elementWidth:newW,elementHeight:newH,x:oX-(newW-oWidth)/2,y:oY-(newH-oHeight)/2,);_onChange();}/// 文本元素的缩放void_onScaleText({required double x,required double y}){if(_currentElement==null||_temporary==null)return;final(oWidth,oHeight,oX,oY,resizeRatio)=_getScaleParams(x:x,y:y);double newW=oWidth*resizeRatio;finaldouble minSize=ConstantsConfig.minSize;// 以短边为基准来计算最小宽高if(oWidth<=oHeight&&newW<minSize){newW=minSize;}// 以长边为基准来计算最大宽高if(oWidth>=oHeight&&newW>=_transformWidth){newW=_transformWidth;}finalTextStylestyle=_getTextStyle(_currentElement!.textOptions!);final(tempWidth,tempHeight)=TransformUtils.calculateTextSize(text:_currentElement!.textOptions!.text,style:style,maxWidth:newW,);_currentElement=_currentElement?.copyWith(elementWidth:newW,elementHeight:tempHeight,x:oX-(newW-oWidth)/2,y:oY-(tempHeight-oHeight)/2,);_onChange();}

运行效果:

这样我们就实现了文本元素的拉伸效果。可以看到,随着功能的增加,可能就需要对之前的逻辑做更改,不过因为抽取了配置,很多地方就只需要加入少量的代码即可实现部分功能。

基础的功能差不多就完成了,接下来主功能就还有一个,那就是保存,我们不知道这个功能是否还存在编辑,如果不存在,直接将该结构转成图片返回即可,所以我们保存就直接将数据和图片都传递过去即可。一般这种大量数据存后端都是JSON字符串,所以我们直接转成json字符串存储:

Future<void>_onSave()async{if(_isLoading)return;_isLoading=true;if(_currentElement!=null){setState((){_currentElement=null;});}if(_currentElement==null){finalStringimagePath=await_getImagePath();finalList<Map<String,dynamic>>tempStringList=_elementList.map((item)=>ElementModel.toJson(item)).toList();widget.onSave(imgSrc:imagePath,data:jsonEncode(tempStringList));_isLoading=false;}else{_isLoading=false;_onSave();}}

运行效果:

这样我们就简单实现了图片的生成,并且将数据转换成JSON字符串传递给后端保存,后续后端返回这个字符串再还原就可以进行编辑。这样就简单实现了基础的功能,后续就实现辅助的功能。

感兴趣的也可以关注我的微信公众号【前端学习小营地】,不定时会分享一些小功能~

好了,今天的分享到此结束,感谢阅读~拜拜~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/12 17:29:44

AssetStudio 终极指南:Unity资源提取完整教程

AssetStudio 终极指南&#xff1a;Unity资源提取完整教程 【免费下载链接】AssetStudio AssetStudioMod - modified version of Perfares AssetStudio, mainly focused on UI optimization and some functionality enhancements. 项目地址: https://gitcode.com/gh_mirrors/a…

作者头像 李华
网站建设 2026/6/9 22:25:54

Leo编译器如何将高级语言转换为零知识证明电路?

Leo编译器如何将高级语言转换为零知识证明电路&#xff1f; 【免费下载链接】leo &#x1f981; The Leo Programming Language. A Programming Language for Formally Verified, Zero-Knowledge Applications 项目地址: https://gitcode.com/gh_mirrors/le/leo Leo编程…

作者头像 李华
网站建设 2026/6/12 18:46:54

YOLO模型推理请求激增?弹性伸缩GPU集群自动应对

YOLO模型推理请求激增&#xff1f;弹性伸缩GPU集群自动应对 在智能制造工厂的质检线上&#xff0c;清晨7:50&#xff0c;上千台摄像头同步启动。图像如潮水般涌向后端AI系统——下一秒&#xff0c;服务器警报拉响&#xff1a;GPU利用率飙升至98%&#xff0c;请求队列积压超过30…

作者头像 李华
网站建设 2026/6/13 1:59:06

springboot_ssm汽车销售系统

目录具体实现截图系统所用技术介绍写作提纲核心代码部分展示系统性能结论源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;具体实现截图 springboot_ssm汽车销售系统 系统所用技术介绍 本系统采取了一系列的设计原则&#xff0c;主…

作者头像 李华
网站建设 2026/6/11 5:11:51

一文说清Keil uVision5在STM32项目中的安装与配置

从零开始搭建STM32开发环境&#xff1a;Keil uVision5 安装与配置实战指南 你是不是也曾被“Keil安装完却找不到芯片”、“程序烧不进去”、“编译报错一堆头文件缺失”这些问题折磨得焦头烂额&#xff1f;明明只是想点亮一个LED&#xff0c;怎么搞得像在破解系统&#xff1f;…

作者头像 李华
网站建设 2026/6/12 18:57:10

手机整机测试标准完整指南:硬件质量检测终极教程

手机整机测试标准完整指南&#xff1a;硬件质量检测终极教程 【免费下载链接】手机整机测试标准资源下载 本资源提供了《手机整机测试标准》&#xff0c;这是一套全面、专业的手机硬件测试规范&#xff0c;广泛应用于手机制造和检测领域。文档详细规定了手机测试的基本流程和方…

作者头像 李华