js前端開發(fā)—canvas篇—2D上下文(未完待續(xù))

參考資料

《Javascript高級層序設(shè)計》(第3版)

前言

本人菜鳥坟募,入IT只為當(dāng)鼓勵師背亥。本編文章旨在總結(jié)《Javascript高級層序設(shè)計(第3版)》一書中第15章canvas的一些api拨扶。第(一)篇只總結(jié)2D上下文糊余。

一焊唬、<canvan>元素

出處:HTML5坟岔。
用途:設(shè)定一個區(qū)域,通過JS動態(tài)地在區(qū)域上繪制圖形独令。
組成:由幾組API構(gòu)成端朵,可分為 2D上下文(基本繪圖能力) 和 3D上下文(WebGL)。

兼容性

  • 瀏覽器:IE9+燃箭、Firefox1.5+冲呢、Safari2+、Opera9+招狸、Chrome敬拓、IOS版Safari、Android版WebKit裙戏。
  • 操作系統(tǒng):Windows XP因缺少必要的繪圖程序乘凸,不管用什么瀏覽器都不支持。

二累榜、基本用法

1. 建立區(qū)域

要使用<canvas>元素营勤,必須設(shè)置width和height屬性,指定可以繪圖的區(qū)域大小壹罚。設(shè)置完后葛作,如果瀏覽器兼容<canvas>標(biāo)簽,則建立的區(qū)域應(yīng)是空白的猖凛;否則赂蠢,會顯示其中的文本:A drawing of something。

<canvas id="drawing" width="200" height="200">A drawing of something</canvas>

2. 取得繪圖上下文(<canvas>元素的DOM對象)

要在這塊畫布上繪圖辨泳,需要取得繪圖上下文虱岂。繪圖上下文也就是取得相應(yīng)<canvas>元素的DOM對象玖院。

// 取得DOM對象呻疹,也為canvas對象
var drawing = document.getElementById("drawing");

3. 取得2D上下文對象 getContext("2d")

只取得DOM對象還不行先舷,還要調(diào)用<canvas>DOM對象擁有的 getContext(param) 方法。其中傳入?yún)?shù)為一個字符串俩功,因為本篇文章總結(jié)的是2D上下文(平面)绍傲,故傳入"2d",獲得2D上下文對象耍共。后面一切關(guān)于繪圖的方法和屬性烫饼,其實都是圍繞著2D上下文對象開展的,也就是代碼示例中的context试读。

method param return
getContext(param) 上下文對象的類型杠纵,有如下選擇:</br>"2d"(2d上下文)</br>"3d"(3d上下文) 上下文對象

在調(diào)用該方法之前,為了保證程序的健壯性钩骇,最好加入檢測代碼比藻。

// 確定瀏覽器支持<canvas>元素
if(drawing.getContext) {
    // 取得2D上下文對象
    var context = drawing.getContext("2d");
    // 更多代碼
}

4. 導(dǎo)出在<canvas>元素上繪制的圖像

當(dāng)在<canvas>元素上繪制完圖像后,可以調(diào)用DOM對象的 toDataURL(param) 方法倘屹,將該圖像導(dǎo)出成為一張圖片银亲,傳入?yún)?shù)為欲導(dǎo)出圖片的MIME類型,例如:image/png纽匙、image/jpeg 等等务蝠。擁有該方法的對象是<canvas>元素的DOM對象,并不是2d上下文對象context烛缔,兩者要區(qū)分開來馏段。

method param return compatibility
toDataURL(param) 圖像的MIME類型格式,有如下選擇:</br>"image/jpeg"(Firefox和Opera默認(rèn))</br>"image/png"(其他默認(rèn)) 圖像的數(shù)據(jù)URI IE9+践瓷、Firefox3.5+ 院喜、Opera10
var drawing = document.getElementById("drawing");

// 確定瀏覽器支持<canvas>元素
if(drawing.getContext) {
    // 取得圖像的數(shù)據(jù)URI
    var imgURI = drawing.toDataURI("image/png");
   
    // 顯示圖像
    var image = document.createElement("img");
    image.src = imgURI;
    document.body.appendChild(image);
}

三、2D上下文 context

(0, 0)為<canvas>元素所占區(qū)域的原點坐標(biāo)晕翠,x向右遞增喷舀,y向下遞增

1. 填充和描邊

attribute value effect
fillStyle String類型:顏色名、十六進(jìn)制碼崖面、rgb等元咙,如"#0000ff" 設(shè)置填充顏色
strokeStyle String類型:顏色名、十六進(jìn)制碼巫员、rgb等庶香,如"red" 設(shè)置描邊顏色
var drawing = document.getElementById("drawing");

// 確定瀏覽器支持<canvas>元素
if(drawing.getContext) {
    var context = drawing.getContext("2d");
    // 以紅色描邊 
    context.strokeStyle = "red"; 
    // 以藍(lán)色填充 
    context.fillStyle = "#0000ff"; 
    // 繪制描邊矩形 
    context.strokeRect(10, 10, 50, 50); 
    // 繪制填充矩形 context.fillRect
    (65, 10, 50, 50);
}

2. 繪制矩形

2.1 填充矩形

method param effect
fillRect(param1,param2, param3,param4) param1:矩形的x坐標(biāo)</br>param2:矩形的y坐標(biāo)</br>param3:矩形的寬度</br>param4:矩形的高度 繪制填充矩形,默認(rèn)為黑色简识,可給fillStyle賦值改變其填充顏色
// 填充
var drawing = document.getElementById("drawing");

// 確定瀏覽器支持<canvas>元素
if(drawing.getContext) { 
    var context = drawing.getContext("2d");
    // 以紅色填充
    context.fillStyle = "#ff0000";
    // 繪制填充矩形
    context.fillRect(10, 10, 50, 50);
    // 以半透明的藍(lán)色填充
    context.fillStyle = "rgba(0, 0, 255, 0.5)";
    // 繪制填充矩形
    context.fillRect(30, 30, 50, 50);
 }

2.2 描邊矩形

method param effect
strokeRect(param1, param2, param3, param4) param1:矩形的x坐標(biāo)</br>param2:矩形的y坐標(biāo)</br>param3:矩形的寬度</br>param4:矩形的高度 繪制描邊矩形赶掖,默認(rèn)為黑色感猛,可給strokeStyle賦值改變其邊框顏色
// 描邊
var drawing = document.getElementById("drawing");

// 確定瀏覽器支持<canvas>元素
if(drawing.getContext) {
    var context = drawing.getContext("2d");
    // 以紅色描邊 
    context.strokeStyle = "#ff0000"; 
    // 繪制描邊矩形 
    context.strokeRect(10, 10, 50, 50); 
    // 以藍(lán)色描邊 
    context.strokeStyle = "rgba(0, 0, 255, 0.5)"; 
    // 繪制描邊矩形 context.strokeRect(30, 30, 50, 50); 
}

2.3 清除矩形

method param effect
clearRect(param1, param2, param3, param4) param1:矩形的x坐標(biāo)</br>param2:矩形的y坐標(biāo)</br>param3:矩形的寬度</br>param4:矩形的高度 清除一塊矩形區(qū)域
// 清除矩形區(qū)域 
var drawing = document.getElementById("drawing");  

// 確定瀏覽器支持<canvas>元素 
if(drawing.getContext) { 
      var context = drawing.getContext("2d"); 
      // 繪制紅色矩形 
      context.fillStyle = "#ff0000"; 
      context.fillRect(10, 10, 50, 50);

      // 繪制半透明的藍(lán)色矩形 
      context.fillStyle = "rgba(0, 0, 255, 0.5)"; 
      context.fillRect(30, 30, 50, 50); 

      // 在兩個矩形重疊的地方清楚一個小矩形 
      context.clearRect(40, 40, 10, 10); 
}

3. 繪制路徑

3.1 創(chuàng)建路徑

method param effect
arc(x,y,radius,startAngle,counterclockwise) (x, y):圓心的坐標(biāo)</br>radius:弧線半徑</br>startAngle:起始角度</br>endAngle:結(jié)束角度</br>counterclockwise:角度的方向(true:逆時針方向,false:順時針方向 給定圓心(x,y)和半徑radius奢赂、起始和結(jié)束的角度陪白、方向,繪制一條弧線
arcTo(x1,y1,x2,y2,radius) (x1, y1):需穿過的點的坐標(biāo)</br>(x2, y2):終點坐標(biāo)</br>radius:以給定的半徑穿過(x1, y1) 從上一點繪制一條弧線膳灶,到(x2,y2)為止咱士,并且以給定的半徑穿過(x1, y1)
bezierCurveTo(c1x,c1y,c2x,c2y,x,y) (c1x,c1y):控制點</br>(c2x,c2y):另一個控制點</br>(x, y):終點坐標(biāo) 從上一點繪制一條弧線,到(x,y)為止轧钓,并且以(c1x,c1y)和(c2x,c2y)為控制點
lineTo(x,y) (x,y):終點坐標(biāo) 從上一點開始繪制一條直線序厉,到(x,y)為止
moveTo(x,y) (x,y):繪圖游標(biāo)移動到的點的坐標(biāo) 將繪圖游標(biāo)移動到(x,y),不畫線
quadraticCurveTo(cx,cy,x,y) (cx,cy):控制點</br>(x,y):終點坐標(biāo) 從上一點開始繪制一條二次曲線毕箍,到(x,y)為止弛房,并且以(cx,cy)為控制點
rect(x,y,width,height) (x,y):起點坐標(biāo)</br>width:矩形的寬</br>height:矩形的高 從點(x,y)開始繪制一個矩形,寬高分別為width和height而柑。這個方法繪制的是矩形路徑文捶,而不是strokeRect()和fillRect()所繪制的獨立形狀

3.2 處理路徑

method param effect
beginPath() null 開始創(chuàng)建路徑
closePath() null 關(guān)閉路徑,回到起點
fill() null 用fillStyle來填充路徑
stroke() null 用strokeStyle來對路徑描邊
clip() null 在路徑上創(chuàng)建一個剪切區(qū)域

3.2.1 用上面某些方法描繪一個時鐘

 var drawing = document.getElementById("drawing");  

// 確定瀏覽器支持<canvas>元素 
if(drawing.getContext) { 
    var context = drawing.getContext("2d");  

    // 開始路徑 
    context.beginPath();  

    // 繪制外圓 
    context.arc(100, 100, 99, 0, 2*Math.PI, false);

    // 繪制內(nèi)圓 
   context.moveTo(194, 100); 
   context.arc(100, 100, 94, 0, 2*Math.PI, false);  

  // 繪制分針
  context.moveTo(100, 100);
  context.lineTo(100, 15);  

  // 繪制時針
  context.moveTo(100, 100); 
  context.lineTo(35, 100);  

  // 為路徑描邊 
  context.stroke(); 
}

3.2.2 用fill()方法填充路徑

var drawing = document.getElementById("drawing");

// 確定瀏覽器支持<canvas>元素 
if(drawing.getContext) {  
    var context = drawing.getContext("2d");  

    // 開始路徑 
    context.beginPath();  

    // 繪制圓 
    context.arc(100, 100, 99, 0, 2*Math.PI, false);  

    // 填充路徑 
    context.fill();
}

3.2.3 當(dāng)路徑不閉合時fill()方法無效

var drawing = document.getElementById("drawing"); 

// 確定瀏覽器支持<canvas>元素 
if(drawing.getContext) { 
    var context = drawing.getContext("2d"); 

    // 繪制一條對角線 
    context.moveTo(0, 0); 
    context.lineTo(200, 200); 

    // 填充路徑 
    context.fill(); 
}

3.3 判斷路徑點

method param effect
isPointInPath(x,y) (x,y):某一任意點的坐標(biāo) 在路徑被關(guān)閉前確定判斷畫布上的點(x,y)是否在路徑上

4. 繪制文本

4.1 2d上下文的文本屬性

attribute value effect
font String類型媒咳,如"bold 14px Arial" 字體粗細(xì)粹排、大小和樣式
textAlign String類型,有如下選擇:</br>"start"(x坐標(biāo)表示文本左端)伟葫,"center"(正中)恨搓,"end"(右端) 文本的水平對齊方式
textBaseline String類型,有如下選擇:</br>"top"(y坐標(biāo)表示文本頂端)筏养,"middle"(正中)斧抱,"bottom"(底端),"hanging"渐溶、"alphabetic"辉浦、"ideographic"(y坐標(biāo)指向特定基線坐標(biāo)) 文本的垂直對齊方式

其實,fillText()和strokeText()方法都可以接受第四個參數(shù)茎辐,表示文本的最大像素寬度宪郊,如果傳入字符串大于最大寬度,會收縮以適應(yīng)最大寬度拖陆。但這個可選參數(shù)尚未得到大多數(shù)瀏覽器的支持弛槐。

4.2 用fillText()繪制數(shù)字12

method param effect
fillText(string,x,y) string:要繪制的文本字符串</br>x:x坐標(biāo)可選的最大像素寬度</br>y:y坐標(biāo)可選的最大像素寬度 使用fillStyle屬性繪制文本
strokeText(string,x,y) string:要繪制的文本字符串</br>x:x坐標(biāo)可選的最大像素寬度</br>y:y坐標(biāo)可選的最大像素寬度 使用strokeStyle屬性為文本描邊
var drawing = document.getElementById("drawing");  

// 確定瀏覽器支持<canvas>元素
if(drawing.getContext) { 
    var context = drawing.getContext("2d");  

    // 開始路徑 
    context.beginPath();  

    // 繪制外圓 
    context.arc(100, 100, 99, 0, 2*Math.PI, false);  

    // 繪制內(nèi)圓 
    context.moveTo(194, 100); 
    context.arc(100, 100, 94, 0, 2*Math.PI, false);  

    // 繪制分針 
    context.moveTo(100, 100); 
    context.lineTo(100, 15);

    // 繪制時針 
    context.moveTo(100, 100); 
    context.lineTo(35, 100);  

    // 為路徑描邊 
    context.stroke();  

    // 繪制數(shù)字12 
    context.font = "bold 14px Arial"; 
    context.textAlign = "center"; 
    context.textBaseline = "middle"; 
    context.fillText("12", 100, 20); 
}

</br>

4.3 給定寬度的區(qū)域,找到文本合適的字體大小

method param return effect
mearsureText(string) string類型:要確定大小的文本字符串 object:返回一個對象依啰,該對象只有一個width屬性 獲得存有文本大小的對象
var fontSize = 100, 
      context.font = fontSize + "px Arial"; 
if (context.measureText) { 
    while(context.measureText("Hello world!").width > 140) { 
        fontSize--; 
        context.font = fontSize + "px Arial"; 
    } 
}  
context.fillText("Hello world!", 10, 10);
context.fillText("Font size is " + fontSize + "px", 10, 50);

上面的代碼從100像素的字體大小開始遞減乎串,最終會找到合適的字體大小,在一個140像素的矩形區(qū)域中繪制文本 Hello world!

5. 變換

5.1 用translate()方法變換原點位置

var drawing = document.getElementById("drawing");

// 確定瀏覽器支持<canvas>元素 
if (drawing.getContext) { 
    var context = drawing.getContext("2d");  
    
    // 開始路徑 
    context.beginPath(); 

    // 繪制外圓 
    context.arc(100, 100, 99, 0, 2 * Math.PI, false);  

    // 繪制內(nèi)圓 
    context.moveTo(194, 100); 
    context.arc(100, 100, 94, 0, 2 * Math.PI, false);  

    // 變換原點
    context.translate(100, 100);  

    // 繪制分針 
    context.moveTo(0,0); 
    context.lineTo(0, -85); 

    // 繪制時針 
    context.moveTo(0, 0); 
    context.lineTo(-65, 0); 

    // 繪制路徑 
    context.stroke(); 
}


可以看出結(jié)果與3.2.1的圖形相同速警,但把原點變換到時鐘表盤中心點(100, 100)后叹誉,在同一方向上繪制線條的數(shù)學(xué)計算就變得簡單起來了鸯两。

5.2 用rotate()方法旋轉(zhuǎn)表針

var drawing = document.getElementById("drawing");

// 確定瀏覽器支持<canvas>元素 
if (drawing.getContext) { 
    var context = drawing.getContext("2d");  
    
    // 開始路徑 
    context.beginPath(); 

    // 繪制外圓 
    context.arc(100, 100, 99, 0, 2 * Math.PI, false);  

    // 繪制內(nèi)圓 
    context.moveTo(194, 100); 
    context.arc(100, 100, 94, 0, 2 * Math.PI, false);  

    // 變換原點
    context.translate(100, 100);  

    // 繪制分針 
    context.moveTo(0,0); 
    context.lineTo(0, -85); 

    // 繪制時針 
    context.moveTo(0, 0); 
    context.lineTo(-65, 0); 

    // 旋轉(zhuǎn)表針,旋轉(zhuǎn)弧度值為1长豁,2π對應(yīng)360°钧唐,則1對應(yīng)(360/2π)°,約為57.30°
    context.rotate(1);

    // 繪制路徑 
    context.stroke(); 
}

圖中紅色的部分不存在匠襟,是我做給大家的提示和比較而已钝侠,用來指明不加最后一句代碼的指針原來的位置。


5.3 跟蹤上下文的狀態(tài)變化

棧:先進(jìn)后出酸舍。

method param effect
save() null 當(dāng)下所有設(shè)置都會進(jìn)入一個棧結(jié)構(gòu)
restore() null 在保存設(shè)置的棧結(jié)構(gòu)中向前返回一級
var drawing = document.getElementById("drawing");

// 確定瀏覽器支持<canvas>元素
if (drawing.getContext) {

    var context = drawing.getContext("2d");

    context.fillStyle = "#ff0000"; 
    context.save();  

    context.fillStyle = "#00ff00"; 
    context.translate(100, 100); 
    context.save();  

    context.fillStyle = "#0000ff"; 
    //從點(100,100)開始繪制藍(lán)色矩形  
    context.fillRect(0,0,100,200); 

    context.restore();  
    //從點(110,110)開始繪制綠色矩形  
    context.fillRect(10,10,100,200);

    context.restore(); 
    //從點(0, 0)開始繪制紅色矩形
    context.fillRect(0,0,100,200); 
}

6. 繪制圖像

把一幅圖像繪制到畫布上机错,可以使用drawImage()方法。

method param effect
drawImage(image,</br>tx,ty) image:要繪制的圖像</br>tx:目標(biāo)圖像的x坐標(biāo)</br>ty:目標(biāo)圖像的y坐標(biāo) 把圖像繪制到畫布上父腕,起點坐標(biāo)為(tx,ty)
drawImage(image,</br>tx,ty,twidth,theight) image:要繪制的圖像</br>tx:目標(biāo)圖像的x坐標(biāo)</br>ty:目標(biāo)圖像的y坐標(biāo)</br>twidth:目標(biāo)圖像的寬度</br>theight:目標(biāo)圖像的高度 把圖像繪制到畫布上,起點坐標(biāo)為(tx,ty),繪制到畫布上的圖像的寬度為twidth青瀑,高度為theight
drawImage(image,</br>sx,sy,swidth,sheight,</br>tx,ty,twidth,theight) image:要繪制的圖像</br>sx:源圖像的x坐標(biāo)</br>sy:源圖像的y坐標(biāo)</br>swidth:源圖像的寬度</br>sheight:源圖像的高度</br>tx:目標(biāo)圖像的x坐標(biāo)</br>ty:目標(biāo)圖像的y坐標(biāo)</br>twidth:目標(biāo)圖像的寬度</br>theight:目標(biāo)圖像的高度 先對源圖像做一些處理璧亮,該處理為:以(sx,sy)為起點截取寬度為swidth斥难,高度為sheight的新圖像枝嘶。處理后再把新圖像繪制到畫布上,起點坐標(biāo)為(tx,ty),繪制到畫布上的新圖像的寬度為twidth哑诊,高度為theight

7. 陰影

attribute value effect
shadowColor String類型:顏色名群扶、十六進(jìn)制碼、rgb等镀裤,如"#0000ff"竞阐,默認(rèn)為黑色 用CSS顏色格式表示的陰影顏色
shadowOffsetX Number類型,默認(rèn)為0 形狀或路徑x軸方向的陰影偏移量
shadowOffsetY Number類型暑劝,默認(rèn)為0 形狀或路徑y(tǒng)軸方向的陰影偏移量
shadowBlur Number類型骆莹,默認(rèn)為0,即不模糊 模糊的像素數(shù)

8. 漸變

method param return
createLinearGradient 起點的x坐標(biāo)</br>起點的y坐標(biāo)</br>終點的x坐標(biāo)</br>終點的y坐標(biāo) 返回CanvasGradient對象的實例

9. 模式

10. 使用圖像數(shù)據(jù)

11. 合成

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末担猛,一起剝皮案震驚了整個濱河市幕垦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌傅联,老刑警劉巖先改,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蒸走,居然都是意外死亡仇奶,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門载碌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來猜嘱,“玉大人衅枫,你說我怎么就攤上這事±柿妫” “怎么了弦撩?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長论皆。 經(jīng)常有香客問我益楼,道長,這世上最難降的妖魔是什么点晴? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任感凤,我火速辦了婚禮,結(jié)果婚禮上粒督,老公的妹妹穿的比我還像新娘陪竿。我一直安慰自己,他們只是感情好屠橄,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布族跛。 她就那樣靜靜地躺著,像睡著了一般锐墙。 火紅的嫁衣襯著肌膚如雪礁哄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天溪北,我揣著相機與錄音桐绒,去河邊找鬼。 笑死之拨,一個胖子當(dāng)著我的面吹牛茉继,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚀乔,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼馒疹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乙墙?” 一聲冷哼從身側(cè)響起颖变,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎听想,沒想到半個月后腥刹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡汉买,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年衔峰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡垫卤,死狀恐怖威彰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情穴肘,我是刑警寧澤歇盼,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站评抚,受9級特大地震影響豹缀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜慨代,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一邢笙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧侍匙,春花似錦氮惯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至江滨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間厌均,已是汗流浹背唬滑。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留棺弊,地道東北人晶密。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像模她,于是被迫代替她去往敵國和親稻艰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容