實(shí)現(xiàn)動(dòng)畫(huà)方式深度解析(十) —— Core Animation之高級(jí)動(dòng)畫(huà)技巧 (七)

版本記錄

版本號(hào) 時(shí)間
V1.0 2017.09.23

前言

app中好的炫的動(dòng)畫(huà)可以讓用戶耳目一新,為產(chǎn)品增色不少,關(guān)于動(dòng)畫(huà)的實(shí)現(xiàn)我們可以用基本動(dòng)畫(huà)、關(guān)鍵幀動(dòng)畫(huà)、序列幀動(dòng)畫(huà)以及基于CoreGraphic的動(dòng)畫(huà)等等,接下來(lái)這幾篇我就介紹下我可以想到的幾種動(dòng)畫(huà)繪制方法。具體Demo示例已開(kāi)源到Github —— 刀客傳奇,感興趣的可以看我寫的另外幾篇。
1. 實(shí)現(xiàn)動(dòng)畫(huà)方式深度解析(一) —— 播放GIF動(dòng)畫(huà)(一)
2. 實(shí)現(xiàn)動(dòng)畫(huà)方式深度解析(二) —— 播放GIF動(dòng)畫(huà)之框架FLAnimatedImage的使用(二)
3. 實(shí)現(xiàn)動(dòng)畫(huà)方式深度解析(三) —— 播放序列幀動(dòng)畫(huà)(一)
4. 實(shí)現(xiàn)動(dòng)畫(huà)方式深度解析(四) —— QuartzCore框架(一)
5. 實(shí)現(xiàn)動(dòng)畫(huà)方式深度解析(五) —— QuartzCore框架之CoreAnimation(二)
6. 實(shí)現(xiàn)動(dòng)畫(huà)方式深度解析(六) —— Core Animation Basics(三)
7. 實(shí)現(xiàn)動(dòng)畫(huà)方式深度解析(七) —— Core Animation之Setting Up Layer Objects(四)
8. 實(shí)現(xiàn)動(dòng)畫(huà)方式深度解析(八) —— Core Animation之動(dòng)畫(huà)層內(nèi)容 (五)
9. 實(shí)現(xiàn)動(dòng)畫(huà)方式深度解析(九) —— Core Animation之構(gòu)建圖層層級(jí) (六)

Advanced Animation Tricks - 高級(jí)動(dòng)畫(huà)技巧

有很多方法可以配置基于屬性或關(guān)鍵幀的動(dòng)畫(huà),為您做更多的事情。 需要一起或順序執(zhí)行多個(gè)動(dòng)畫(huà)的應(yīng)用程序可以使用更高級(jí)的行為來(lái)同步這些動(dòng)畫(huà)的時(shí)間或?qū)⑺鼈冩溄釉谝黄稹?您還可以使用其他類型的動(dòng)畫(huà)對(duì)象來(lái)創(chuàng)建視覺(jué)轉(zhuǎn)換和其他有趣的動(dòng)畫(huà)效果。


Transition Animations Support Changes to Layer Visibility - 轉(zhuǎn)換動(dòng)畫(huà)支持更改層可見(jiàn)性

顧名思義,轉(zhuǎn)換動(dòng)畫(huà)對(duì)象為圖層創(chuàng)建動(dòng)畫(huà)視覺(jué)轉(zhuǎn)換。 過(guò)渡對(duì)象最常見(jiàn)的用途是以協(xié)調(diào)的方式動(dòng)畫(huà)化一層的外觀和另一層的消失。 與基于屬性的動(dòng)畫(huà)不同,動(dòng)畫(huà)更改圖層的一個(gè)屬性,轉(zhuǎn)換動(dòng)畫(huà)會(huì)操縱圖層的緩存圖像,以創(chuàng)建通過(guò)單獨(dú)更改屬性難度或不可能執(zhí)行的視覺(jué)效果。 轉(zhuǎn)換的標(biāo)準(zhǔn)類型可讓您執(zhí)行顯示,推送,移動(dòng)或交叉淡入淡出動(dòng)畫(huà)。 在OS X上,您還可以使用Core Image過(guò)濾器創(chuàng)建使用其他類型的效果(如擦除,卷曲,波紋或自定義效果)的轉(zhuǎn)換。

要執(zhí)行轉(zhuǎn)換動(dòng)畫(huà),您將創(chuàng)建一個(gè)CATransition對(duì)象并將其添加到轉(zhuǎn)換中涉及的層。 您可以使用轉(zhuǎn)換對(duì)象來(lái)指定要執(zhí)行的轉(zhuǎn)換類型以及轉(zhuǎn)換動(dòng)畫(huà)的起點(diǎn)和終點(diǎn)。 您也不需要使用整個(gè)轉(zhuǎn)換動(dòng)畫(huà)。 轉(zhuǎn)換對(duì)象允許您指定要在動(dòng)畫(huà)時(shí)使用的開(kāi)始和結(jié)束進(jìn)度值。 這些值可讓您在其中點(diǎn)進(jìn)行動(dòng)畫(huà)開(kāi)始或結(jié)束。

下面代碼顯示了用于在兩個(gè)視圖之間創(chuàng)建動(dòng)畫(huà)推送轉(zhuǎn)換的代碼。 在該示例中,myView1myView2都位于同一父視圖中的相同位置,但只有myView1當(dāng)前可見(jiàn)。 推送過(guò)渡會(huì)導(dǎo)致myView1向左滑動(dòng),并且漸隱,直到它隱藏,而myView2從右側(cè)滑入并變?yōu)榭梢?jiàn)。 更新兩個(gè)視圖的隱藏屬性可確保在動(dòng)畫(huà)結(jié)束時(shí)兩個(gè)視圖的可視性是正確的。

//Animating a transition between two views in iOS

CATransition* transition = [CATransition animation];
transition.startProgress = 0;
transition.endProgress = 1.0;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
transition.duration = 1.0;
 
// Add the transition animation to both layers
[myView1.layer addAnimation:transition forKey:@"transition"];
[myView2.layer addAnimation:transition forKey:@"transition"];
 
// Finally, change the visibility of the layers.
myView1.hidden = YES;
myView2.hidden = NO;

當(dāng)同一個(gè)轉(zhuǎn)換中涉及到兩個(gè)層時(shí),可以使用相同的轉(zhuǎn)換對(duì)象。 使用相同的轉(zhuǎn)換對(duì)象也簡(jiǎn)化了必須編寫的代碼。 但是,您可以使用不同的轉(zhuǎn)換對(duì)象,如果每個(gè)層的轉(zhuǎn)換參數(shù)不同,那么肯定需要這樣做。

下面代碼顯示了如何使用Core Image過(guò)濾器在OS X上實(shí)現(xiàn)過(guò)渡效果。在使用所需參數(shù)配置過(guò)濾器后,將其分配給過(guò)渡對(duì)象的過(guò)濾器屬性。 之后,應(yīng)用動(dòng)畫(huà)的過(guò)程與其他類型的動(dòng)畫(huà)對(duì)象相同。

// Using a Core Image filter to animate a transition on OS X

// Create the Core Image filter, setting several key parameters.
CIFilter* aFilter = [CIFilter filterWithName:@"CIBarsSwipeTransition"];
[aFilter setValue:[NSNumber numberWithFloat:3.14] forKey:@"inputAngle"];
[aFilter setValue:[NSNumber numberWithFloat:30.0] forKey:@"inputWidth"];
[aFilter setValue:[NSNumber numberWithFloat:10.0] forKey:@"inputBarOffset"];
 
// Create the transition object
CATransition* transition = [CATransition animation];
transition.startProgress = 0;
transition.endProgress = 1.0;
transition.filter = aFilter;
transition.duration = 1.0;
 
[self.imageView2 setHidden:NO];
[self.imageView.layer addAnimation:transition forKey:@"transition"];
[self.imageView2.layer addAnimation:transition forKey:@"transition"];
[self.imageView setHidden:YES];

注意:在動(dòng)畫(huà)中使用Core Image過(guò)濾器時(shí),最棘手的部分是配置過(guò)濾器。 例如,使用條形滑動(dòng)轉(zhuǎn)換,指定輸入角度太高或太低可能會(huì)使它看起來(lái)好像沒(méi)有轉(zhuǎn)換發(fā)生。 如果您沒(méi)有看到您想要的動(dòng)畫(huà),請(qǐng)嘗試將過(guò)濾器參數(shù)調(diào)整為不同的值,以查看是否更改了結(jié)果。


Customizing the Timing of an Animation - 自定義動(dòng)畫(huà)的時(shí)序

Timing是動(dòng)畫(huà)的重要組成部分,Core Animation可以通過(guò)CAMediaTiming協(xié)議的方法和屬性為動(dòng)畫(huà)指定精確的時(shí)間信息。 兩個(gè)核心動(dòng)畫(huà)類采用這個(gè)協(xié)議。 CAAnimation類采用它,以便您可以在動(dòng)畫(huà)對(duì)象中指定時(shí)間信息。 CALayer還采用它,以便您可以為隱式動(dòng)畫(huà)配置一些與時(shí)序相關(guān)的功能,盡管包含這些動(dòng)畫(huà)的隱式事務(wù)對(duì)象通常提供優(yōu)先級(jí)的默認(rèn)時(shí)序信息。

當(dāng)考慮時(shí)間和動(dòng)畫(huà)時(shí),了解層對(duì)象如何隨著時(shí)間的推移是重要的。 每個(gè)層都有自己的本地時(shí)間,用于管理動(dòng)畫(huà)時(shí)序。 通常,兩個(gè)不同層的本地時(shí)間足夠接近,您可以為每個(gè)層指定相同的時(shí)間值,并且用戶可能不會(huì)注意到任何內(nèi)容。 然而,層的本地時(shí)間可以由其父層或其自己的時(shí)序參數(shù)修改。 例如,更改圖層的速度屬性會(huì)導(dǎo)致該圖層(及其子圖層)的動(dòng)畫(huà)持續(xù)時(shí)間按比例更改。

為了幫助您確定時(shí)間值適用于給定層,CALayer類定義convertTime:fromLayer:convertTime:toLayer:方法。 您可以使用這些方法將固定時(shí)間值轉(zhuǎn)換為圖層的本地時(shí)間,或?qū)r(shí)間值從一個(gè)層轉(zhuǎn)換為另一層。 這些方法會(huì)考慮可能影響圖層本地時(shí)間的媒體時(shí)序?qū)傩裕⒎祷乜膳c其他圖層一起使用的值。 下面代碼顯示了一個(gè)示例,您應(yīng)該定期使用以獲取圖層的當(dāng)前本地時(shí)間。 CACurrentMediaTime函數(shù)是一個(gè)方便的函數(shù),它返回計(jì)算機(jī)的當(dāng)前時(shí)鐘時(shí)間,該方法將采用該函數(shù)并將其轉(zhuǎn)換為圖層的本地時(shí)間。

 // Getting a layer’s current local time

CFTimeInterval localLayerTime = [myLayer convertTime:CACurrentMediaTime() fromLayer:nil];

一旦您在圖層的本地時(shí)間中有時(shí)間值,您可以使用該值更新動(dòng)畫(huà)對(duì)象或圖層的時(shí)間相關(guān)屬性。 通過(guò)這些時(shí)序?qū)傩裕梢詫?shí)現(xiàn)一些有趣的動(dòng)畫(huà)行為,其中包括:

  • 使用beginTime屬性設(shè)置動(dòng)畫(huà)的開(kāi)始時(shí)間。 通常,動(dòng)畫(huà)將在下一個(gè)更新周期開(kāi)始。 您可以使用beginTime參數(shù)將動(dòng)畫(huà)開(kāi)始時(shí)間延遲幾秒鐘。 將兩個(gè)動(dòng)畫(huà)連接在一起的方法是設(shè)置一個(gè)動(dòng)畫(huà)的開(kāi)始時(shí)間,以匹配另一個(gè)動(dòng)畫(huà)的結(jié)束時(shí)間。如果延遲動(dòng)畫(huà)的開(kāi)始,您可能還需要將fillMode屬性設(shè)置為kCAFillModeBackwards。 即使圖層樹(shù)中的圖層對(duì)象包含不同的值,此填充模式也會(huì)使圖層顯示動(dòng)畫(huà)的起始值。 沒(méi)有這種填充模式,您將看到在動(dòng)畫(huà)開(kāi)始執(zhí)行之前跳轉(zhuǎn)到最終值。 其他填充模式也可用。

  • autoreverses屬性會(huì)使動(dòng)畫(huà)在指定的持續(xù)時(shí)間內(nèi)執(zhí)行,然后返回到動(dòng)畫(huà)的起始值。 您可以將此屬性與repeatCount屬性組合,以在起始值和結(jié)束值之間來(lái)回動(dòng)畫(huà)。 將重復(fù)計(jì)數(shù)設(shè)置為自動(dòng)轉(zhuǎn)換動(dòng)畫(huà)的整數(shù)(例如1.0)會(huì)導(dǎo)致動(dòng)畫(huà)停止其起始值。 添加額外的一半步驟(例如重復(fù)計(jì)數(shù)為1.5)會(huì)導(dǎo)致動(dòng)畫(huà)停止其結(jié)束值。

  • 使用具有組動(dòng)畫(huà)的timeOffset屬性可以在稍后時(shí)間啟動(dòng)一些動(dòng)畫(huà)。


Pausing and Resuming Animations - 停止和暫停動(dòng)畫(huà)

要暫停動(dòng)畫(huà),您可以利用層采用CAMediaTiming協(xié)議并將層的動(dòng)畫(huà)速度設(shè)置為0.0。 將速度設(shè)置為零可暫停動(dòng)畫(huà),直到將值更改回非零值。 下面代碼顯示了如何暫停和恢復(fù)動(dòng)畫(huà)的簡(jiǎn)單示例。

// Pausing and resuming a layer’s animations

-(void)pauseLayer:(CALayer*)layer {

CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];

layer.speed = 0.0;

layer.timeOffset = pausedTime;

}

-(void)resumeLayer:(CALayer*)layer {

CFTimeInterval pausedTime = [layer timeOffset];

layer.speed = 1.0;

layer.timeOffset = 0.0;

layer.beginTime = 0.0;

CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;

layer.beginTime = timeSincePause;

}

Explicit Transactions Let You Change Animation Parameters - 顯式轉(zhuǎn)場(chǎng)讓您更改動(dòng)畫(huà)參數(shù)

對(duì)圖層進(jìn)行的每一次更改都必須是事務(wù)的一部分。 CATransaction類在適當(dāng)?shù)臅r(shí)間管理動(dòng)畫(huà)的創(chuàng)建和分組及其執(zhí)行。 在大多數(shù)情況下,您不需要?jiǎng)?chuàng)建自己的事務(wù)。 每當(dāng)向其中一個(gè)圖層添加顯式或隱式動(dòng)畫(huà)時(shí),Core Animation將自動(dòng)創(chuàng)建一個(gè)隱式事務(wù)。 但是,您也可以創(chuàng)建顯式的事務(wù)來(lái)更精確地管理這些動(dòng)畫(huà)。

您可以使用CATransaction類的方法創(chuàng)建和管理事務(wù)。 開(kāi)始(并隱式創(chuàng)建)一個(gè)新的事務(wù)調(diào)用begin類方法; 要結(jié)束該事務(wù),調(diào)用commit類方法。 在這些調(diào)用之間是您想成為事務(wù)一部分的更改。 例如,要更改圖層的兩個(gè)屬性,可以使用下面的代碼。

// Creating an explicit transaction

[CATransaction begin];
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
[CATransaction commit];

使用交易的主要原因之一是在顯式事務(wù)的限制內(nèi),您可以更改持續(xù)時(shí)間,計(jì)時(shí)功能和其他參數(shù)。 您還可以為整個(gè)事務(wù)分配完成塊,以便在動(dòng)畫(huà)組完成時(shí)通知您的應(yīng)用。 更改動(dòng)畫(huà)參數(shù)需要使用setValue:forKey:方法修改事務(wù)字典中的相應(yīng)鍵。 例如,要將默認(rèn)持續(xù)時(shí)間更改為10秒,您可以更改kCATransactionAnimationDuration鍵,如下所示。

//Changing the default duration of animations

[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:10.0f]
                 forKey:kCATransactionAnimationDuration];
// Perform the animations
[CATransaction commit];

您可以在要為不同動(dòng)畫(huà)集提供不同默認(rèn)值的情況下嵌套事務(wù)。 要將一個(gè)事務(wù)嵌套在另一個(gè)事務(wù)中,只需再次調(diào)用begin類方法。 每個(gè)開(kāi)始調(diào)用必須通過(guò)對(duì)commit方法的相應(yīng)調(diào)用進(jìn)行匹配。 只有在您提交最外層事務(wù)的更改后,Core Animation才會(huì)啟動(dòng)相關(guān)聯(lián)的動(dòng)畫(huà)。

下面代碼顯示了嵌套在另一個(gè)事務(wù)中的一個(gè)事務(wù)的示例。 在此示例中,內(nèi)部事務(wù)將更改與外部事務(wù)相同的動(dòng)畫(huà)參數(shù),但使用不同的值。

// Nesting explicit transactions

[CATransaction begin]; // Outer transaction

// Change the animation duration to two seconds

[CATransaction setValue:[NSNumber numberWithFloat:2.0f]

forKey:kCATransactionAnimationDuration];

// Move the layer to a new position

theLayer.position = CGPointMake(0.0,0.0);

[CATransaction begin]; // Inner transaction

// Change the animation duration to five seconds

[CATransaction setValue:[NSNumber numberWithFloat:5.0f]

forKey:kCATransactionAnimationDuration];

// Change the zPosition and opacity

theLayer.zPosition=200.0;

theLayer.opacity=0.0;

[CATransaction commit]; // Inner transaction

[CATransaction commit]; // Outer transaction

Adding Perspective to Your Animations - 為您的動(dòng)畫(huà)添加視覺(jué)

應(yīng)用程序可以在三個(gè)空間維度中操縱圖層,但為了簡(jiǎn)單起見(jiàn),Core Animation使用平行投影顯示圖層,這將基本上將場(chǎng)景平坦化為二維平面。 這種默認(rèn)行為導(dǎo)致具有不同zPosition值的相同大小的圖層顯示為相同的大小,即使它們?cè)趜軸上相距較遠(yuǎn)。 你通常會(huì)在三維中觀看這樣一個(gè)視角的觀點(diǎn)已經(jīng)消失了。 但是,您可以通過(guò)修改圖層的轉(zhuǎn)換矩陣來(lái)包含透視信息來(lái)更改該行為。

當(dāng)修改場(chǎng)景的透視圖時(shí),需要修改包含正在查看的圖層的超層的sublayerTransform矩陣。 修改超層通過(guò)將相同的透視信息應(yīng)用于所有子層來(lái)簡(jiǎn)化您必須編寫的代碼。 它還確保透視圖正確應(yīng)用于在不同平面中彼此重疊的兄弟子層。

下面代碼顯示了為父層創(chuàng)建簡(jiǎn)單透視變換的方法。 在這種情況下,自定義eyePosition變量指定沿著Z軸的相對(duì)距離以查看圖層。 通常你為eyePosition指定一個(gè)正值,以便按照預(yù)期的方式保持這些層面。 更大的值導(dǎo)致更平坦的場(chǎng)景,而較小的值會(huì)導(dǎo)致層之間更顯著的視覺(jué)差異。

// Adding a perspective transform to a parent layer

CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = -1.0/eyePosition;
 
// Apply the transform to a parent layer.
myParentLayer.sublayerTransform = perspective;

配置父層后,您可以更改任何子層的zPosition屬性,并根據(jù)其距離眼睛位置的相對(duì)距離觀察其大小如何變化。

后記

未完,待續(xù)~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,182評(píng)論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,489評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,290評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,776評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,510評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,866評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,860評(píng)論 3 447
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,036評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,585評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,331評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,536評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,058評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,754評(píng)論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,154評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,469評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,273評(píng)論 3 399
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,505評(píng)論 2 379

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