用微信这么多年,刚刚发现这个问题,上个图说一下:
Paste_Image.png
当聊天发送图片时,气泡右侧小三角里面显示的也是图片,这是怎么实现的呢,当然原生app实现起来很容易啦,
对于前端小伙伴,用css实现的办法我查了一些资料,结果不是很完美
下面给出一个canvas画出的气泡:
先把用到的canvas的路径方法列举一下:
beginPath()
起始一条路径,或重置当前路径。
moveTo()
把路径移动到画布中的指定点,不创建线条。
closePath()
创建从当前点回到起始点的路径。
lineTo()
添加一个新点,然后在画布中创建从该点到最后指定点的线条。
arcTo()
创建两切线之间的弧/曲线。
stroke()
绘制已定义的路径。
clip()
从原始画布剪切任意形状和尺寸的区域。
drawImage()
向画布上绘制图像、画布或视频。
Canvas并没有提供绘制圆角矩形的方法,但是通过观察,我们可以发现,其实我们可以将圆角矩形分为四段,可以通过使用arcTo来实现。
这里写图片描述
我们假设起点为x,y.绘制的矩形宽高为w,h.圆角的半径为r;所以将起点设置在(x+r,y)处,然后acrTo(x+w,y,x+w,y+h,r),对于终点,其实只要y值大于绿色点的都是可以的(这部分在绘制曲线部分已经详述)。此处我们将终点设为(x+w,y+h);这就是第一段曲线。第一段曲线绘制完毕之后,画笔落在了下图绿色点的位置。
这里写图片描述
现在再看下第二段曲线: 因此我们直接使用arcTo(x+w,y+h,x,y+h,r)绘制出第二个圆角,第二个曲线绘制完毕后,画笔落在了绿色点位置。
这里写图片描述
我们可以使用同样的方法来绘制第三个圆角。 acrTo(x,y+h,x,y,r)
这里写图片描述
第四个圆角arcTo(x,y,x+w,y):
这里写图片描述
这样,一个圆角矩形就完成了。为了方便使用,我们可以将绘制圆角矩形的方法封装在一个函数,或者加入到CanvasRenderingContext2D的原型中。
原文:http://blog.csdn.net/liuyan19891230/article/details/51259147
<!doctype html>
<html>
<head>
<title>QRCode</title>
<meta charset="utf-8">
<script type="text/javascript" src="http://files.cnblogs.com/webers/qrcode-light.js"></script>
<script type="text/javascript" src="http://files.cnblogs.com/webers/qrgen.js"></script>
</head>
<body>
<canvas id = "canvas" width="215px" height="80px">
您的浏览器不支持Canvas标签,请升级或更换浏览器
</canvas>
<script>
var canvas = document.querySelector("#canvas").getContext("2d");
// 画网格线作为标尺
// canvas.moveTo(0,0);
// canvas.lineTo(0,300);
// canvas.moveTo(50.5,0);
// canvas.lineTo(50.5,300);
// canvas.moveTo(100.5,0);
// canvas.lineTo(100.5,300);
// canvas.moveTo(150.5,0);
// canvas.lineTo(150.5,300);
// canvas.moveTo(200.5,0);
// canvas.lineTo(200.5,300);
// canvas.moveTo(250.5,0);
// canvas.lineTo(250.5,300);
// canvas.moveTo(300.5,0);
// canvas.lineTo(300.5,300);
// canvas.moveTo(0,0);
// canvas.lineTo(300,0);
// canvas.moveTo(0,50.5);
// canvas.lineTo(300,50.5);
// canvas.moveTo(0,100.5);
// canvas.lineTo(300,100.5);
// canvas.moveTo(0,150.5);
// canvas.lineTo(300,150.5);
// canvas.moveTo(0,200.5);
// canvas.lineTo(300,200.5);
// canvas.moveTo(0,250.5);
// canvas.lineTo(300,250.5);
// canvas.moveTo(0,300.5);
// canvas.lineTo(300,300.5);
// canvas.stroke();
/**
* x: 圆角矩形=>对应的矩形的左上角 x坐标
* y: 圆角矩形=>对应的矩形的左上角 y坐标
* w: 矩形的宽
* h: 矩形的高
* r: 圆角矩形的圆角半径
* minW: 矩形的最小宽度
* minH: 矩形的最小高度
* e: 三角形距离矩形的最远垂直距离
*
*/
CanvasRenderingContext2D.prototype.roundRect = function (x, y, minW, minH, r, e) {
var d = minH / 2 - r - e;
// 我觉得这两个if判断的不完全 还有minW minH都小于2r的情况
if (minW < 2 * r) {
r = minW / 2;
}
if (minH < 2 * r) {
r = minH / 2;
d = 0;
}
this.beginPath();
this.moveTo(x+r, y);
this.arcTo(x+minW, y, x+minW, y+minH, r);
this.arcTo(x+minW, y+minH, x, y+minH, r);
this.arcTo(x, y+minH, x, y, r);
this.lineTo(x, y+minH/2+e);
this.lineTo(x-e, y+minH/2);
this.lineTo(x, y+minH/2-e);
this.lineTo(x, y+r);
this.arcTo(x, y, x+minW, y, r);
this.closePath();
return this;
};
canvas.lineWidth = 2;
canvas.strokeStyle = "#ededed";
function draw () {
canvas.roundRect(15,0,200,80,10,15).clip();
canvas.drawImage(image, 0,0,300,300);
};
var image = new Image();
image.onload = draw;
image.src = './image/22.jpeg';
</script>
</body>
</html>
上面代码中image.onload = draw后面不能加()
image.onload = draw();
不要在draw后面加() 因为这是在给事件关联触发的方法
如果加() 会立刻引发这个方法的执行(这可能不是我们的本意)
onload的几种使用方式:
1、可以在Body 里面执行:
<body onload="load()">
</body>
<body onload="a();b();c();">
</body>
2、先定义好 在页面加载完成后使用:
image.onload = draw;
3、使用匿名函数: window.onload = function(){alert(321);
现在的效果:
Paste_Image.png
那么现在有一个问题:怎么把气泡的宽高还有图片的宽高设置成自适应呢?
......先慢慢研究下吧