HTML5-Canvas的基本功能

利用 Canvas 的 API,展示一些基本图形的绘制及操作方法,包括画线、画图、文字操作及图片操作等。(内含代码清单)

一、绘制基本图形

1.1 画线

简约版:

<!DOCTYPE HTML>
<html>
<body>
<canvas id="myCanvas" width="200" height="100">
你的浏览器不支持 HTML5
</canvas>

<script type="text/javascript">
var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d");

ctx.lineWidth = 10;
ctx.strokeStyle = "red";
ctx.beginPath();
ctx.moveTo(10,10);
ctx.lineTo(150,50);
ctx.stroke();

</script>
</body>
</html>

注释版:

<!DOCTYPE HTML>
<html>
<body>

/*在HTML中嵌入Canvas标签,如果浏览器不支持Canvas标签,那么浏览器会自动跳过Canvas标签,运行Canvas内部HTML代码*/
<canvas id="myCanvas" width="200" height="100">
你的浏览器不支持 HTML5
</canvas>

<script type="text/javascript">

    /*获取HTML中的Canvas标签*/
    var c=document.getElementById("myCanvas");
    /*返回一个用来绘制环境类型的环境,目前只支持2d环境*/ 
    var ctx=c.getContext("2d");
    /*线宽*/
    ctx.lineWidth = 10;
    /*笔画颜色,这里颜色值可以是英文字母、RGB值、十六进制颜色*/
    ctx.strokeStyle = "red";

    /*线帽有三种,分别是butt、round、square
    butt:默认。向线条的每个末端添加平直的边缘。
    round:向线条的每个末端添加圆形线帽。
    square:向线条的每个末端添加正方形线帽。*/
    ctx.lineCup="butt";
    /*创建一个新路径*/
    ctx.beginPath();
    /*画笔光标起始位置*/
    ctx.moveTo(10,10);
    /*画笔光标终止位置*/
    ctx.lineTo(150,50);
    /*开始绘制定义好的路径*/
    ctx.stroke();

</script>

</body>
</html>

1.2 画矩形

空心矩形:

<script type="text/javascript">
var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d");

ctx.lineWidth = 10;
ctx.strokeStyle = "red";
ctx.beginPath();
/*用strokeRect函数绘制矩形,四个参数:起点坐标x、起点坐标y、矩形长、矩形宽*/
ctx.strokeRect(10,10,70,40);

</script>

注:ctx.strokeRect(10,10,70,40);等价于ctx.rect(10,10,70,40);ctx.stroke();

实心矩形:

/*使用fillRect函数*/

<script type="text/javascript">
var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d");

ctx.fillStyle = "red";
ctx.beginPath();
/*用strokeRect函数绘制矩形,四个参数:起点坐标x、起点坐标y、矩形长、矩形宽*/
ctx.fillRect(10,10,70,40);

</script>

注:ctx.fillRect(10,10,70,40);等价于ctx.rect(10,10,70,40);ctx.fill();

1.3 画圆

圆其实就是360度的圆弧。在Canvas中,可使用arc函数来画一个圆弧。

空心圆:

<script type="text/javascript">
var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d");

ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.beginPath();
/*用arc函数绘制圆弧,六个参数:圆弧中心坐标x、圆弧中心坐标y、圆弧半径、起始角度、终止角度(要转化成弧度)、是否逆时针*/
ctx.arc(100,100,70,0,360*Math.PI/180,true);
ctx.stroke();
</script>

实心圆:

/*使用fill函数*/

<script type="text/javascript">
var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d");

ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.beginPath();
/*用arc函数绘制矩形,六个参数:圆弧中心坐标x、圆弧中心坐标y、圆弧半径、起始角度、终止角度(要转化成弧度)、是否逆时针*/
ctx.arc(100,100,70,0,360*Math.PI/180,true);
ctx.fill();
</script>

1.4 圆角矩形

Canvas中没有直接画圆角矩形的API,但是我么可以用arcTo函数完成圆角的绘制,然后结合直线绘制,就可以完成圆角矩形的绘制了。

绘制一个圆角:

<script type="text/javascript">
var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d");
ctx.beginPath();

ctx.moveTo(20,20);
ctx.lineTo(70,20);
/*用arcTo函数为当前的子路径添加一条圆弧。5个参数:P1坐标x、P1坐标y、P2坐标x、P2坐标y、圆弧半径*/
ctx.arcTo(120,30,120,70,50);
ctx.lineTo(120,120);
ctx.stroke();
</script>

绘制圆角矩形:

<script type="text/javascript">
var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d");
ctx.beginPath();

ctx.moveTo(40,20);
ctx.lineTo(100,20);
/*用arcTo函数为当前的子路径添加一条圆弧。5个参数:P1坐标x、P1坐标y、P2坐标x、P2坐标y、圆弧半径*/
ctx.arcTo(120,20,120,40,20);
ctx.lineTo(120,70);
ctx.arcTo(120,90,100,90,20);
ctx.lineTo(40,90);
ctx.arcTo(20,90,20,70,20);
ctx.lineTo(20,40);
ctx.arcTo(20,20,40,20,20);

ctx.stroke();
</script>

1.5 擦除Canvas画板

使用clearRect函数擦除一个矩形区域。他需要4个参数:起点坐标x、坐标y、擦除区域的长和宽。

绘制一个红色实心矩形,再擦除一个5050的小矩形:*

<canvas id="myCanvas" width="200" height="100">
你的浏览器不支持 HTML5
</canvas>

<script type="text/javascript">
var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d");

ctx.fillStyle = "red";
ctx.beginPath();

ctx.fillRect(10,10,200,100);
ctx.clearRect(30,30,50,50);

ctx.stroke();

</script>

二、绘制复杂图形

2.1 画曲线

二次贝塞尔曲线:

二次贝塞尔曲线有一个控制点,再Canvas中用quadraticCurveTo(cpx,cpy,x,y)函数绘制。cpx,cpy表示控制点的坐标,x,y表示终点坐标。

<script type="text/javascript">
var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d");

ctx.beginPath();

ctx.moveTo(100,100);
ctx.quadraticCurveTo(20,50,200,20);

ctx.stroke();
</script>
image

三次贝塞尔曲线:

二次、三次贝塞尔曲线的区别在于三次的有两个控制点。

<script type="text/javascript">
var c=document.getElementById("myCanvas"); 
var ctx=c.getContext("2d");

ctx.moveTo(68,130);
var cX1 = 20;
var cY1 = 10;
var cX2 = 268;
var cY2 = 10;
var endX = 268;
var endY = 170;
ctx.bezierCurveTo(cX1,cY1,cX2,cY2,endC,endY);

ctx.stroke();
</script>

2.2 利用clip在指定区域绘图

clip函数使用当前路径作为绘制操作的剪辑区域。可以理解为窗户,不论绘制了多大的图形,最后看到的图像只能由clip这扇窗来决定。

先画圆,使用clip,再画矩形,最后只能看到圆

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

ctx.arc(100,100,40,0,360*Math.PI/180,true);

ctx.clip();

ctx.beginPath();
//设定颜色
ctx.fillStyle="lightblue";
//绘制矩形
ctx.fillRect(0,0,300,150);
</script>

2.3 绘制自定义图形

结合各种方法,绘制特殊图形,例如:

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

ctx.beginPath(); 
ctx.moveTo(100, 150);   
ctx.bezierCurveTo(50, 100, 100, 0, 150, 50);   
ctx.bezierCurveTo(200, 0, 250, 100, 200, 150);  
ctx.bezierCurveTo(250, 200, 200, 300, 150, 250);  
ctx.bezierCurveTo( 100, 300, 50, 200,100, 150);    
ctx.closePath(); 

ctx.moveTo(100, 150);
ctx.lineTo(150, 50); 
ctx.lineTo(200, 150); 
ctx.lineTo(150, 250); 
ctx.lineTo(100, 150); 
ctx.lineWidth = 5;   
ctx.strokeStyle = "#ff0000";   

ctx.stroke();   
</script>
image

三、绘制文本

3.1 绘制文字

使用fillText绘制实心文字

fillText(text,x,y,max Width)函数,4各参数分别是:文本字符串、坐标x、坐标y、文本宽度。其中文本宽度可以省略,当其省略时,文本宽度会自动定为整个文本的宽度。

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

//设定文字大小和字体
ctx.font="30px Arial";
//描画文字
ctx.fillText("Hello World",100,50);

//或添加文本宽度参数:
//ctx.fillText("Hello World",100,50,50);

</script>

使用strokeText绘制空心文字:
strokeText与fillText用法相同,只是fillText为实心文字,strokeText为空心文字

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
//设定文字大小和字体
ctx.font="30px Arial";
//描画文字
ctx.strokeText("Hello World",100,50);
</script>

3.2 文字设置

3.2.1 文字大小

使用font参数:例如:ctx.font="50px Arial";

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

ctx.beginPath();
//设定文字大小为30px
ctx.font="30px Arial";
ctx.fillText("Hello World",100,50);

ctx.beginPath();
//设定文字大小为50px
ctx.font="50px Arial";
ctx.fillText("Hello World",100,150);

ctx.beginPath();
//设定文字大小为100px
ctx.font="70px Arial";
ctx.fillText("Hello World",100,250);
</script>
3.2.2 文字字体
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

ctx.beginPath();
//设定文字字体为Arial
ctx.font="30px Arial";
ctx.fillText("Hello World (Arial)",50,50);

ctx.beginPath();
//设定文字字体为Verdana
ctx.font="30px Verdana";
ctx.fillText("Hello World (Verdana)",50,100);

ctx.beginPath();
//设定文字字体为Times New Roman
ctx.font="30px Times New Roman";
ctx.fillText("Hello World (Times New Roman)",50,150);

ctx.beginPath();
//设定文字字体为Courier New
ctx.font="30px Courier New";
ctx.fillText("Hello World (Courier New)",50,200);

ctx.beginPath();
//设定文字字体为serif
ctx.font="30px serif";
ctx.fillText("Hello World (serif)",50,250);

ctx.beginPath();
//设定文字字体为sans-serif
ctx.font="30px sans-serif";
ctx.fillText("Hello World (sans-serif)",50,300);
</script>
image
3.2.3 文字粗体效果
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

ctx.beginPath();
//设定font-weight为normal
ctx.font='normal 30px Arial';
ctx.fillText("Hello World (normal)",50,50);

ctx.beginPath();
//设定font-weight为bold 
ctx.font='bold 30px Arial';
ctx.fillText("Hello World (bold)",50,90);

ctx.beginPath();
//设定font-weight为bolder
ctx.font='bolder 30px Arial';
ctx.fillText("Hello World (bolder)",50,130);

ctx.beginPath();
//设定font-weight为lighter
ctx.font='lighter 30px Arial';
ctx.fillText("Hello World (lighter)",50,170);

ctx.beginPath();
//设定font-weight为100
ctx.font='100 30px Arial';
ctx.fillText("Hello World (100)",50,210);

ctx.beginPath();
//设定font-weight为600
ctx.font='600 30px Arial';
ctx.fillText("Hello World (600)",50,250);

ctx.beginPath();
//设定font-weight为900
ctx.font='900 30px Arial';
ctx.fillText("Hello World (900)",50,290);
</script>
image
3.2.4 文字斜体效果
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

ctx.beginPath();
//设定font-weight为normal
ctx.font='normal 30px Arial';
ctx.fillText("Hello World (normal)",50,50);

ctx.beginPath();
//设定font-style为italic 
ctx.font='italic 30px Arial';
ctx.fillText("Hello World (italic)",50,90);

ctx.beginPath();
//设定font-style为oblique
ctx.font='oblique 30px Arial';
ctx.fillText("Hello World (oblique)",50,130);
</script>

3.3 文字的对齐效果

3.3.1 水平对齐
</canvas>
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

ctx.moveTo(160,0);
ctx.lineTo(160,300);
ctx.stroke();

ctx.beginPath();
ctx.textAlign='start';
ctx.font='30px Arial';
ctx.fillText("Hello World",160,50);

ctx.beginPath();
ctx.textAlign='end';
ctx.font='30px Arial';
ctx.fillText("Hello World",160,100);

ctx.beginPath();
ctx.textAlign='left';
ctx.font='30px Arial';
ctx.fillText("Hello World",160,150);

ctx.beginPath();
ctx.textAlign='center';
ctx.font='30px Arial';
ctx.fillText("Hello World",160,200);

ctx.beginPath();
ctx.textAlign='right';
ctx.font='30px Arial';
ctx.fillText("Hello World",160,250);
</script>
image
3.3.2 竖直对齐
<script type="text/javascript">
var c=document.getElementById('myCanvas');
var ctx=c.getContext('2d');

ctx.textBaseline='alphabetic';
ctx.font='30px Arial';
ctx.fillText('Hello World',50,50);
ctx.moveTo(0,50);
ctx.lineTo(250,50);
ctx.stroke();

ctx.textBaseline='bottom';
ctx.font='30px Arial';
ctx.fillText('Hello World',50,100);
ctx.moveTo(0,100);
ctx.lineTo(250,100);
ctx.stroke();

ctx.textBaseline='hanging';
ctx.font='30px Arial';
ctx.fillText('Hello World',50,150);
ctx.moveTo(0,150);
ctx.lineTo(250,150);
ctx.stroke();

ctx.textBaseline='ideographic';
ctx.font='30px Arial';
ctx.fillText('Hello World',50,200);
ctx.moveTo(0,200);
ctx.lineTo(250,200);
ctx.stroke();

ctx.textBaseline='middle';
ctx.font='30px Arial';
ctx.fillText('Hello World',50,250);
ctx.moveTo(0,250);
ctx.lineTo(250,250);
ctx.stroke();

ctx.textBaseline='top';
ctx.font='30px Arial';
ctx.fillText('Hello World',50,300);
ctx.moveTo(0,300);
ctx.lineTo(250,300);
ctx.stroke();
</script>
image

<label style="color:orange">四、图片操作

4.1 利用drawImage绘制图片

drawImage函数有3种函数原型,语法如下:

drawImages(image,dx, dy);
drawImages(image,dx, dy, dw, dh);
drawImages(image,sx, sy, sw, sh, dx, dy, dw, dh);

  • image是要绘制的对象,可以说HTMLImageRlement、HTML-CanvasElement或者HTMLVideoElement
  • dx、dy是image在Canvas中定位的坐标值
  • dw、dh表示image在Canvas中即将绘制区域(相对dx、dy坐标的偏移量)的宽度与高度值
  • sx、sy是image所要绘制的起始位置
  • sw、sh表示image所要绘制区域(相对sw、sy坐标的偏移量)的宽度与高度值

方式1:在Canvas中通过<img>标签的id取得图片数据

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8" />
</head>

<body>

img标签<br />
<img id="face" src="face.jpg" alt="The Face" width="240" height="240" /><br />
canvas画板<br />
<canvas id="myCanvas" width="500" height="350">
你的浏览器不支持HTML5
</canvas>

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

var img=document.getElementById("face");

img.onload = function(){    
   ctx.drawImage(img,10,10);   
};   

</script>
</body>
</html>

步骤1:在html中加入<img>标签

<img id="face" src="face.jpg" alt="The Face" width="240" height="240" /><br />

步骤2:在Canvas中通过<img>标签的id取得图片数据

var img=document.getElementById("face");

步骤3:用drawImage函数江图片绘制到画板上

ctx.drawImage(img,10,10);

方式2:在Canvas中通过 JavaScript 的 Image 对象来获取数据(个人推荐这种)

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8" />
</head>
<body>
<canvas id="myCanvas" width="500" height="350">
你的浏览器不支持HTML5
</canvas>

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

var image = new Image();    
image.src = "face.jpg";  

image.onload = function(){    
   ctx.drawImage(image,10,10);   
};    
</script>

</body>
</html>

步骤1:建立image对象

var image = new Image();

步骤2:通过设置scr属性,载入图片

image.src = "face.jpg";

步骤3:添加onload事件侦听,当图片载入完成时,将其绘制到画板

image.onload = function(){    
   ctx.drawImage(image,10,10);   
}; 

drawImage函数的3种函数原型的用法与区别:

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var image = new Image();    
image.src = "face.jpg";  
image.onload = function(){   
    
    /*从坐标(10,10)开始绘制整张图片*/ 
    ctx.drawImage(image,10,10);  

    /*从坐标(260,10)开始绘制整张图片到长100、宽100的矩形区域内*/
    ctx.drawImage(image,260,10,100,100); 

    /*截取图片从(50,50)到(100,100)的部分,从坐标(260,130开始绘制,放大长100,宽100的矩形区域内)*/
    ctx.drawImage(image,50,50,100,100,260,130,100,100);   
};    
</script>
image

4.2 利用getImageData和putImageData绘制图片(不推荐)

putImageData(imagedata,dx, dy, sx, sy, sw, sh)

  • imagedata为像素数据
  • dx、dy是绘制图片的定位坐标值
  • sx、sy是imagedata所要绘制图片的起始位置
  • sw、sh表示imagedata所要绘制区域(相对imagedata的sx、sy坐标的偏移量)的宽度与高度值

这里第四个参数及以后的所有参数都可以省略,如果省略则表示绘制整个imagedata。

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

var image = new Image();    
image.src = "face.jpg";  

image.onload = function(){    
    ctx.drawImage(image,10,10);  
    var imgData=ctx.getImageData(50,50,200,200);
    ctx.putImageData(imgData,10,260); 
    ctx.putImageData(imgData,200,260,50,50,100,100);
};    
</script>

步骤1:图片数据读取完成后,首先江图片数据绘制到Canvas画板上

ctx.drawImage(image,10,10);

步骤2:用getImageData函数从画板上取得像素数据

var imgData=ctx.getImageData(50,50,200,200);

步骤3:将取得的整个像素数据绘制到画板上

ctx.putImageData(imgData,10,260);

或将取得的整个像素数据的一部分绘制到画板上

ctx.putImageData(imgData,200,260,50,50,100,100);

image

注意:这种方法种使用了getImageData函数获取图片数据,这个函数在Google Chrome等浏览器中会涉及跨域问题,所以无法直接在浏览器种浏览。必须通过服务器来访问。当然,我么可以在本地服务器是浏览。

4.3 利用createImageData新建像素

createImageData函数有两种函数原型:

  1. 返回指定大小的imageData对象:

createImageData(sw, sh);

  1. 返回与指定对象相同大小的imageData对象

createImageData(imageData);

注意:通过createImageData返回的是一个空的imageData对象,必须要针对起像素进行复制才能显示到Canvas 画板上

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var image = new Image();    
image.src = "face.jpg";  
image.onload = function(){    
    ctx.drawImage(image,10,10);  
    var imgData=ctx.getImageData(50,50,200,200);
    
    var imgData01=ctx.createImageData(imgData);
    for (i=0; i<imgData01.width*imgData01.height*4;i+=4){
        imgData01.data[i+0]=255;
        imgData01.data[i+1]=0;
        imgData01.data[i+2]=0;
        imgData01.data[i+3]=255;
    }
    ctx.putImageData(imgData01,10,260); 
    
    var imgData02=ctx.createImageData(100,100);
    for (i=0; i<imgData02.width*imgData02.height*4;i+=4){
        imgData02.data[i+0]=255;
        imgData02.data[i+1]=0;
        imgData02.data[i+2]=0;
        imgData02.data[i+3]=155;
    }
    ctx.putImageData(imgData02,220,260); 
};    
</script>

代码解析:

  1. 图片数据读取完成后,首先将图片数据绘制到 Canvas 画板上。

    ctx.drawImage(image,10,10);

  2. 用 getImageData 函数从画板上取得像素数据。

    var imgData=ctx.getImageData(50,50,200,200);

  3. 使用 createImageData 返回与 imgData 相同大小的 ImageData 对象。

    var imgData01=ctx.createImageData(imgData);

  4. imgData01 进行赋值。

    for (i=0; i<imgData01.widthimgData01.height4;i+=4){
    imgData01.data[i+0]=255;
    imgData01.data[i+1]=0;
    imgData01.data[i+2]=0;
    imgData01.data[i+3]=255;
    }

  5. 利用 putImageData 将 imgData01 画到 Canvas 画板上。

    ctx.putImageData(imgData01,10,260);

  6. 使用 createImageData 返回一个大小为 100×100 的 ImageData 对象。

    var imgData02=ctx.createImageData(100,100);

  7. 对 imgData02 进行赋值。

    for (i=0; i<imgData02.widthimgData02.height4;i+=4){
    imgData02.data[i+0]=255;
    imgData02.data[i+1]=0;
    imgData02.data[i+2]=0;
    imgData02.data[i+3]=155;
    }

  8. 利用 putImageData 将 imgData02 画到 Canvas 画板上。

    ctx.putImageData(imgData02,220,260);

image

五、致谢

写这篇学习总结的时候是学校开学的前夕,实验室还没有人。早上我给自己泡了一杯茶,累了就去弹两首古琴曲子然后继续回来学。这篇总结写完的时候,太阳的余辉正撒在我的书桌上。我抬头望着窗外的云朵,好像忽然懂了《时光恋旅人》里主角父亲穿越时空一遍遍看书的感受了,哈哈哈,在时空隧道里,想来我一个人也可以相处的很愉快吧。

本文内容是我对张路斌老师《HTML5 Canvas 游戏开发实战》第二章的学习总结,感谢张路斌老师,也感谢阅读本文的你给我的鼓励!

也欢迎来我的网页踩踩哦,网页里阅读更轻松~网页入口在这哦

作为一个前端小白,如果学习笔记中有错误的地方,还请不吝指点,谢谢!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 验证浏览器是否支持 Your browser does not support HTML5 Canvas. f...
    shuaiutopia阅读 2,619评论 0 0
  • 线条样式 绘制直线,第五章知识简单回顾 lineWidth 设置或返回当前的线条宽度,单位为像素 lineCap ...
    Zd_silent阅读 470评论 0 0
  • 一、图形的组合方式 globalAlpha是一个介于0和1之间的值(包括0和1),用于指定所有绘制的透明度。默认值...
    空谷悠阅读 1,252评论 0 0
  • 第一章 HTML5 (2014年10月29日发布)新特性: 10个 (1)新的语义标签 (2)增强型表单 (3)视...
    fastwe阅读 940评论 0 1
  • 产生死锁的四个必要条件:(1) 互斥条件:一个资源每次只能被一个进程使用。(2) 请求与保持条件:一个进程因请求资...
    荷茗阅读 271评论 0 0