首先圖片為什么 會變形
圖片變形是因為 ctx.drawImage() 繪畫圖片的時候 給死了寬和高,所以不同尺寸的圖片會因為 自己寫死的寬高 而拉伸或者壓縮,因此圖片才會變形。
我的解決方案
重要屬性 ctx.clip() 從原始畫布中剪切任意形狀和尺寸
之前畫用戶圓形頭像用到了clip裁剪。
了解到 clip 可以裁剪,嘗試 把我當前的 圖片等比例的放大或者縮小 直到撐滿我的裁剪區域,那樣我的圖片不就不會變形了。
什么? 你問我怎么等比例放大縮小?
小學數學知識 ~ _ ~ 圖片寬 / 圖片高 = x / y
上代碼
- ctx: 畫布的上下文環境
- img: 需要繪制的圖片
- imageAttributes: 圖片的屬性 用來獲取圖片的寬和高 (這里要說一下 開始我是在 下面方法中去獲取圖片的寬高但是返回的數據慢 所以只能一開始就拿到 要渲染圖片的屬性,然后再開始 初始化canvas去渲染)
- x: 繪制圖片的x坐標
- y:繪制圖片的y坐標
- boxWidth:裁剪區域的寬
- boxHeight:裁剪區域的高
// 圖片變形解決方案 img:繪畫的圖片 imageAttributes:得到圖片屬性 看情況可能是個數組,可以是對象 x y:圖片的坐標 boxWidth:裁剪區域的寬 boxHeight:裁剪區域的高 preventPictureDistortion(ctx,img,imageAttributes, x, y, boxWidth,boxHeight){ let {width,height} = imageAttributes console.log(width,height,'圖片的實際寬高') let imgScale = width / height // 圖片的寬高比 console.log(imgScale,'計算的圖片寬高比') let imgW,imgH // 計算后得到圖片的寬高 let offsetW,offsetH // 繪圖時需要偏移的坐標 是用來 讓圖片居中的 就是截取中間部分 不是從 0 0 開始截取 imgH = boxHeight;imgW = imgScale * imgH;offsetW = (imgW-boxWidth) / 2;offsetH=0 // 開始計算圖片寬高 以及偏移坐標 if(imgW < boxWidth){imgW = boxWidth;imgH = imgW / imgScale; offsetH = (imgH-boxHeight) / 2; offsetW = 0} // 開始繪制 容納圖片的裁剪區域 ctx.save() ctx.beginPath() this.roundedRectangle(ctx, x, y, boxWidth, boxHeight, uni.upx2px(12),'#fff') // 這個方法是用來繪制圓角矩形的 百度來的 ctx.clip() ctx.drawImage(img, x-offsetW, y-offsetH,imgW, imgH) ctx.restore() }
繪制圓角矩形的方法
- ctx: 畫布的上下文環境
- x: 繪制圓角矩形的x坐標
- y:繪制圓角矩形的y坐標
- width: 繪制矩形的寬
- height:繪制矩形的高
- r:繪制矩形的 圓角
- color:矩形的 背景顏色
// 畫圓角矩形方法 roundedRectangle(ctx, x, y, width, height, r,color){ ctx.beginPath(); ctx.moveTo(x + r, y); ctx.fillStyle = color;//矩形填充顏色 ctx.lineTo(x + width - r, y); ctx.arc(x + width - r, y + r, r, Math.PI*1.5, Math.PI*2); ctx.lineTo(x + width, y + height - r); ctx.arc(x + width - r, y + height - r, r, 0, Math.PI*0.5); ctx.lineTo(x + r, y + height); ctx.arc(x + r, y + height - r, r, Math.PI*0.5, Math.PI); ctx.lineTo(x, y + r); ctx.arc(x + r, y + r, r, Math.PI, Math.PI*1.5); ctx.fill(); }