主机参考:VPS测评参考推荐/专注分享VPS服务器优惠信息!若您是商家可以在本站进行投稿,查看详情!此外我们还提供软文收录、PayPal代付、广告赞助等服务,查看详情! |
我们发布的部分优惠活动文章可能存在时效性,购买时建议在本站搜索商家名称可查看相关文章充分了解该商家!若非中文页面可使用Edge浏览器同步翻译!PayPal代付/收录合作 |
小程序开发教程专栏介绍用画布写一张图片。
推荐(免费):小程序开发教程
应用演示
截图
要求
既然是小应用,希望最终产品有适用场景,有价值。
需求来源
这种应用需求的灵感来源于以往的工作和生活中,经常在不经意间得到同事的漂亮照片。这时候我们就想把这张照片做成表情包。一般会在图片上添加一个有趣的交流工具(表情包)。
根据上述需求进行需求分解分析,可以整理出需要应用的功能。
用户需要上传图片,添加文本,调整样式,旋转和缩放。此外,我们希望插入一些地图,可以旋转和缩放。用户可以将图片导出到相册中。
https://github.com/luosijie/f github仓库...
如果你喜欢我的项目,请给我一颗星鼓励我。这个应用程序是用一个小程序开发的。
框架:mpx使用技术:小程序的画布状态管理
从 # 39;导入{ createStore };@ mpxjs/core # 39;const store = CreateStore({ state:{ cavas:null,//cnavas实例ctx: null,// canvas上下文实例元素:[],// canvas元素activeIndex: null,//当前编辑模式下的元素索引: # 39;背景 # 39;,//当前编辑模式:背景、文字、贴纸字体样式:{//文字默认样式为不透明度:1、fill style: # 39;#000000',stroke style: # 39;#000000'} }、突变:{ setCanvas (state,data) { state.canvas = data }、setCtx (state,data) { state.ctx = data }、setElements (state,data) { state.elements = data }、set mode(state . mode = data }、setActiveIndex (state,data) { state.activeIndex = data }、setFontStyle (state,{ key,data }){ state . font style[key]= data }、//添加文本Add text(state){ const size = 50 const请输入文本 # 39;const text = { type: # 39;正文 # 39;,data: string,scale: 1,size,left: 100,top: 100,rotate: 0,opacity:state . font style . opacity,fill style:state . font style . fill style,stroke style } state . elements . push(text)state . active index = state . elements . length -1 },//添加地图addsticker (state,data){ state . elements . push(data)state . active index = state . elements . length -1 },//删除当前选中的Delete
//初始化canvas asyncinitcanvas(){ const query = this . createselectquery()query . select( # 39;#画布 # 39;) .字段({ node: true,size: true })。exec(async RES = gt;{ const canvas = res[0]。node const CTX = canvas . get context( # 39;2d # 39)store . commit( # 39;setCanvas # 39,canvas)store . commit( # 39;setCtx # 39,ctx)等待此。loadimage( # 39;/images/icon -rotate . png # 39;).然后(res = gt{ this . image . rotate = RES })canvas . width = RES[0]。width * this . dprccanvas . height = RES[0]。height * this . DPR CTX . scale(this . DPR,this.dpr) this.drawgrid ()}}画图
/* * *画图* @ param { Object } ele canvas element */Draw image(ele){ this . CTX . save()const width = ele . width const height = ele . height const centex = ele . left+ele . width/2 const centerY = ele . top+ele . height/2。this . CTX . translate(centex,centery)this . CTX . rotate(ele . rotate)this . CTX . draw image(ele . data,ele . left -centex,ele.top-centery,width,height) this.ctx.restore()
/* * * Draw text * @ param { Object } ele canvas element */Draw text(ele){ this . CTX . save()const width = ele . size * ele . data . length const height = ele . size const centerX = ele . left+width/2 const centerY = ele . top+height/2 this . CTX . translate(centex,centerY)this . CTX . rotate(ele . rotate)this . CTX . font = ` $ { ele . size } px bold sans -serif ` this . CTX . global alphatop # 39console . log( # 39;draw -text # 39;,ele) this.ctx.filltext (ele.data,ele . left -centex,ele . top -centery)this . CTX . stroke text(ele . data,ele . left -centex,ele . top -centery)this . CTX . restore
init controller(ele){ const cs = this . convert 2 controller size(ele)this . CTX . save()this . CTX . stroke style = # 39;# eee # 39this . CTX . translate(cs . centex,cs . centery)this . CTX . rotate(cs . rotate)//绘制虚线边框this.ctx.setLineDash([10,5],5)this . CTX . strokerect(cs . left -cs . centex,cs.top-cs.centery,cs.width,cs . height)//绘制控制点-旋转this . CTX . Draw image(this . image . rotate,cs . left+cs . width -10-cs . centerx,
//画布渲染函数render canvas(){ this . CTX . clear rect(0,0,this.ctx.canvas.width,this . CTX . canvas . height)this . draw grid()console . log( # 39;draw -背景 # 39;,this . background)if(this . background)this . draw image(this . background)for(设I = 0;我 ltthis . elements . length;++){ constele = this . elements[I]//渲染背景if(ele . type = = = # 39;背景 # 39;){ this . draw image(ele)} if(ele . type = = = # 39;贴纸 # 39;){this.drawImage(ele)} //渲染文本if(ele . type = = # 39;正文 # 39;){this.drawText(ele)} //选择元素添加控件元素if(this . active index = = I){ this . init controller(ele)} }事件监控。
移动
//移动事件绑定函数handleMove(e){ console . log( # 39;鼠标-移动 # 39;,e)如果(e . touches . length gt;1)返回常数x = e.touches[0]。x常数y = e.touches[0]。y const dx = this.startTouches[0]。x ^ -x const dy = this . start touches[0]。y -y const elements = this . elements . slice()elements[this . active index | | 0]。left = this . start selected . left -dx元素[this.activeIndex || 0]。top = this . start selected . top -dy store . commit( # 39;setElements # 39,elements)} rotate//旋转绑定函数handle rotate(e){ console . log( # 39;handleRotate # 39)const start = this . start touches[0]const end = e . touches[0]const center = { x:this . start selected . centerx,y:this . start selected . centery } const start length = math . sqrt((center . x -start . x)* * 小编(center . y -start . y)* * 2)const end length = math . sqrt((center . x -end . x)* * 小编(center . y -end . y)* * 2)const radian = this . convern正文 # 39;){ selected . left = this . start selected . centrx -this . start selected . size * this . start selected . data . length * scale/2 selected . top = this . start selected . centery -this . start selected . size * scale/2 selected . size = this . start selected . size * scale } if(selected . type = = = = # 39;贴纸 # 39;){ selected . left = this . start selected . centrx -this . start selected . width * scale/2 selected . top = this . start selected . centery -this . start selected . height * scale/2 selected . width = this . start selected . width * scale selected . height = this . start selected . height * scale } store . # 39;setElements # 39,elements)}缩放//缩放事件绑定函数handle scale(e){ if(e . touches . length!== 2 || this.mode!== '背景 # 39;)返回const start length = math . sqrt((this . start touches[0])。x - this.startTouches[1]。x) ** 2 + (this.startTouches[0])。y ^ -this . start touches[1]。y)* * 2)const endLength = math . sqrt((e . touches[0])。x - e.touches[1]。x) ** 2 + (e.touches[0]。y ^ -e . touches[1]。y)* * 2)const scale = end length/start length const elements = this . elements . slice()const selected = elements[this . active index | | 0]selected . left = this . start selected . width * scale/2 selected . top = this . start selected . centery -this . start selected . height * scale/2 selected . width = this . start selected . height * scale//elements[this . active index | | 0]。scale = this . start selected . scale * scale store . commit( # 39;setElements # 39,elements)}导出图片export() {if(!store . state . elements . length){ wx . show toast({ title: # 39;添加东西然后导出 # 39;,图标: # 39;无 # 39;})return } wx . show modal({ title: # 39;提示 # 39;,内容: # 39;将图片保存到您的手机相册 # 39;,success(RES){ if(RES . confirm){ console . log( # 39;export -画布 # 39;,store . state . CTX)const canvas = store . state . canvas wx . canvastotempfilepath({ x:0,y: 0,width: canvas.width,height: canvas.height,canvas,complete(RES){ if(RES . errmsg = = = # 39;canvasToTempFilePath:ok # 39;){ wx . saveimagetophotosalbum({ file path:RES . tempfile path,success(RES){ wx . show toast({ title: # 39;图像保存成功 # 39;,图标: # 39;无 # 39;} } } } } } } } } } } } }以上是使用小程序canvas编写简单图片应用的细节。更多请关注主机参考其他相关文章!
这几篇文章你可能也喜欢:
- 微信小程序开发中var that =this的基本用法
- 小程序瀑布流(小程序中瀑布流的实现)
- 小程序下拉刷新问题(如何解决小程序下拉刷新问题)
- 回想一下Android智能手机上的微信小程序白屏问题(手机上打开小程序时白屏)。
- 可以转发微信小程序给好友(微信小程序可以转发分享到朋友圈吗?)
本文由主机参考刊发,转载请注明:使用applet canvas编写一个简单的图片应用程序(js下载canvas图片) https://zhujicankao.com/81269.html
评论前必须登录!
注册