iOS開發(fā)-核心動畫(CAAnimation)相關

此文章單方面對 貝塞爾曲線畫圖 核心動畫 圖層相關 方面做下整理,方便查看!

基本概念

Core Animation(核心動畫)是一組功能強大,在開發(fā)中可以用他來實現很多復雜和絢麗的動畫效果,核心動畫作用在CALayer(Core animation layer)上

結構

盜圖 -_-.png

代碼和效果

/**
 *  fillMode 視圖在非Active時的行為
 *
 *  kCAFillModeForwards 動畫開始之后layer迅速移到動畫開始的位置
 *  kCAFillModeBackwards 動畫被添加的那一刻(動畫開始之前)layer迅速移到開始位置,并且在 removedOnCompletion 為 NO 的情況下,動畫結束會移到layer本身的位置
 *  kCAFillModeBoth 動畫添加的那一刻(動畫開始之前)layer迅速移到開始位置,并且在 removedOnCompletion 為 NO 的情況下,動畫結束layer會停留在動畫結束的位置
 *  kCAFillModeRemoved  動畫開始之后layer迅速移到動畫開始的位置,并且在 removedOnCompletion 為 NO 的情況下,動畫結束回憶道layer本身位置
 */
    
/**
 *  timingFunction  動畫節(jié)奏 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]
 *
 *  kCAMediaTimingFunctionLinear            勻速
 *  kCAMediaTimingFunctionEaseIn            慢進
 *  kCAMediaTimingFunctionEaseOut           慢出
 *  kCAMediaTimingFunctionEaseInEaseOut     慢進慢出
 *  kCAMediaTimingFunctionDefault           默認值(慢進慢出)
 */
    
/**
 *  removedOnCompletion 動畫執(zhí)行完畢后是否從圖層上移除 默認為 YES (動畫結束layer移到本身位置)
 */
    
/** 
 *  這樣個要配合使用 repeatDuration = repeatCount * duration(動畫一遍持續(xù)時間,主要控制速度)
 *  repeatCount     動畫重復執(zhí)行次數
 *  repeatDuration  動畫重復執(zhí)行時間
 */
CABasicAnimation
1.位置相關動畫 (position.y 和 position.x transform.translation.x 和 transform.translation.y)

position fromValue:默認自身位置為起始位置 toValue:移動后的位置
transform.translation fromValue:默認自身位置為起始位置(默認0) toValue:相對于layer原始位置距離

  • position.y 和 position.x
/// y軸方向移動  fromValue:默認自身位置為起始位置 toValue:移動后的位置
- (void)animation_CABasicAnimation_position_y
{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.y"];
    //animation.fromValue = @(self.img.center.y); 默認初始位置
    animation.toValue = @(self.img.center.y + 100);
    animation.duration = 3;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.img.layer addAnimation:animation forKey:@"position.y"];
}
position.x/y.gif
  • transform.translation.x 和 transform.translation.y
- (void)animation_CABasicAnimation_translation_x
{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
    //animation.fromValue = @0; 默認初始位置
    animation.toValue = @100;
    animation.duration = 1;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.img.layer addAnimation:animation forKey:@"transform.translation.x"];
}
transform.translation.x/y.gif
2.旋轉相關動畫
  • transform.rotation.x | transform.rotation.y | transform.rotation.z
transform.rotation.x.gif
transform.rotation.y.gif
transform.rotation.z.gif
3.縮放相關動畫
  • transform.scale.x | transform.scale.y | transform.scale.z
- (void)animation_CABasicAnimation_transform_scale
{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    animation.toValue = @8.0;
    animation.duration = 3;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.img.layer addAnimation:animation forKey:@"transform.scale"];
}
transform.scale.gif
4.自身大小相關
  • bounds.origin.x | bounds.origin.y
    • 動畫view圖層上圖層和view上的其他控件 不動畫view本身
    • 方向x 右為負 左為正
    • 方向y 上為負 下為正
//bounds.origin.x
//animation1.fromValue = @0; 默認自身位置為開始位置 為0
animation1.toValue = @(-self.img.bounds.size.width * 0.5);

//bounds.origin.y
//animation2.fromValue = @0; 默認自身位置為開始位置 為0
animation2.toValue = @(-self.img.bounds.size.height * 0.5);
bounds.origin.x/y.gif
  • bounds.size.width | bounds.size.height
    • 動畫view本身 不動畫view上的其他控件
//bounds.size.width
//animation1.fromValue = @(self.img.bounds.size.width); 默認起始值為自身寬度
animation1.toValue = @(self.img.bounds.size.width * 0.5);

//bounds.size.height
//animation2.fromValue = @(self.img.bounds.size.height); 默認起始值為自身高度
animation2.toValue = @(self.img.bounds.size.height * 0.5);
bounds.size.width:height.gif
5.邊角動畫
  • cornerRadius | borderWidth | borderColor
//cornerRadius
//animation1.fromValue = @(self.img.layer.cornerRadius); 默認自身圓角為起始值
animation1.toValue = @50;
animation1.repeatCount = 3;
animation1.repeatDuration = animation.duration * animation.repeatCount;

//borderWidth
//animation.fromValue = @(self.img.layer.borderWidth); 默認自身邊框寬度為起始值
animation2.toValue = @20;
animation2.repeatCount = 3;
animation2.repeatDuration = animation.duration * animation.repeatCount;

//borderColor
//animation3.toValue = (__bridge id _Nullable)([self.img.layer borderColor]); //默認自身邊框顏色為起始值
animation3.toValue = (__bridge id _Nullable)([[UIColor cyanColor] CGColor]);
animation3.repeatCount = 3;
animation3.repeatDuration = animation.duration * animation.repeatCount;
cornerRadius/borderWidth/borderColor.gif
6.自身的一些屬性
  • opacity 不透明
animation.fromValue = @1;
animation.toValue = @0;
opacity.gif
  • backgroundColor
animation.toValue = (__bridge id _Nullable)([[UIColor yellowColor] CGColor]);
backgroundColor.gif
  • contents (layer.contents)
animation.fromValue = (__bridge id _Nullable)([[UIImage imageNamed:@"春雨醫(yī)生"] CGImage]);
animation.toValue = (__bridge id _Nullable)([[UIImage imageNamed:@"丁香醫(yī)生"] CGImage]);
contents.gif
7.陰影相關動畫
  • shadowOffset 陰影位置偏移
//self.img.layer.shadowOpacity = 0.5;
//self.img.layer.shadowOffset = CGSizeMake(0, 0);
animation.fromValue = [NSValue valueWithCGSize:CGSizeMake(0, 0)];
animation.toValue = [NSValue valueWithCGSize:CGSizeMake(20, 20)];
animation.duration = 3;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
shadowOffset.gif
  • shadowColor 陰影顏色
//self.img.layer.shadowOpacity = 0.5;
//self.img.layer.shadowOffset = CGSizeMake(20, 20);
animation.toValue = (__bridge id _Nullable)([UIColor redColor].CGColor);
shadowColor.gif
  • shadowOpacity 陰影不透明值 01(透明完全不透明)
//self.img.layer.shadowOpacity = 0;
//self.img.layer.shadowOffset = CGSizeMake(20, 20);
animation.fromValue = @0;
animation.toValue = @1;
shadowOpacity.gif
  • shadowRadius 暫且叫做陰影模糊度吧
//self.img.layer.shadowOpacity = 0.5;
//self.img.layer.shadowOffset = CGSizeMake(20, 20);
animation.fromValue = @3;
animation.toValue = @10;
shadowRadius.gif
CAKeyframeAnimation

可以看做是一個有更多位置設定的CABaseAnimation,可以設定keyPath起點、中間關鍵點(可以是多個)、終點的值,每一幀所對應的時間,動畫會沿著設定點進行移動

CAKeyframeAnimation的一些獨有屬性

  • values: 關鍵幀數組對象,里面每一個元素即為一個關鍵幀
  • path: 動畫路徑對象,可以指定一個路徑,在執(zhí)行動畫時路徑會沿著路徑移動,注:Path在動畫中只會影響視圖的Position
  • keyTimes: 設置關鍵幀對應的時間數組,范圍:0.0-1.0之間的浮點型
    • 數組中的每一個連續(xù)值都必須大于或等于前面的值,因為里面存儲的是動畫持續(xù)時間內的每一幀的時間點,時間點是從0%-100%,時間不可能回退
    • 為了得到最好的結果,數組中的元素個數應該與values中的元素個數或路徑屬性中的控制點的數量相匹配
  • timingFunctions: 設置關鍵幀對應速度效果的數組
  • calculationMode: 這個屬性用來設定 關鍵幀中間的值是怎么被計算的
    NSString * const kCAAnimationLinear
    NSString * const kCAAnimationDiscrete 只展示關鍵幀的狀態(tài),沒有中間過程,沒有動畫
    NSString * const kCAAnimationPaced
    NSString * const kCAAnimationCubic
    NSString * const kCAAnimationCubicPaced
- (void)animation_CAKeyframeAnimation_Rect
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.duration = 4.0;
    animation.repeatCount = 2;
    animation.repeatDuration = animation.duration * animation.repeatCount;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(self.img.center.x, self.img.center.y)];
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(self.img.center.x + 150, self.img.center.y)];
    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(self.img.center.x + 150, self.img.center.y + 150)];
    NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(self.img.center.x, self.img.center.y + 150)];
    NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(self.img.center.x, self.img.center.y)];
    animation.values = @[value1, value2, value3, value4, value5];
    animation.keyTimes = @[@0, @0.4, @0.5, @0.9, @1.0];
    
    /*  利用貝塞爾畫的一個矩形,跟上面效果一樣,只不過不能設置關鍵幀動畫時間
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(self.img.center.x, self.img.center.y, 150, 150)];
    animation.path = path.CGPath;
     */
    
    [self.img.layer addAnimation:animation forKey:@"position"];
}
values_rect.gif
path_rect.gif

利用貝塞爾畫個圓路徑動畫

- (void)animation_CAKeyframeAnimation_Circle
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.duration = 3;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    animation.repeatCount = 2;
    animation.repeatDuration = animation.repeatCount * animation.duration;
    
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.img.center.x + 75, self.img.center.y) radius:75 startAngle:M_PI endAngle:3*M_PI clockwise:YES];
  
    animation.path = path.CGPath;
    [self.img.layer addAnimation:animation forKey:@"position"];
}
path_circle.gif
CATransition

轉場動畫,在開發(fā)中巧用會有意想不到的效果,還方便

/**
 *  CATransition (type) 過渡動畫的類型
 *
 *  kCATransitionFade   漸變
 *  kCATransitionMoveIn 覆蓋
 *  kCATransitionPush   推出
 *  kCATransitionReveal 揭開(可以說是抽開)
 *
 *  私有動畫類型的值有:"cube"、"suckEffect"、"oglFlip"、 "rippleEffect"、"pageCurl"、"pageUnCurl"等等
 */
    
/**
 *  CATransition (subtype) 過渡動畫的方向
 *
 *  kCATransitionFromRight  從右邊
 *  kCATransitionFromLeft   從左邊
 *  kCATransitionFromTop    從頂部
 *  kCATransitionFromBottom 從底部
 */

下面來組示例,看下效果,生成四個顏色的圖片,來個切換動畫

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    static int i = 0;
    i = i >= self.imgsArr.count-1 ? 0:i+1;
    self.img.image = [self.imgsArr objectAtIndex:i];
    CATransition *animation = [CATransition animation];
    animation.duration = 0.5;
    animation.type = @"cube";
    animation.subtype = kCATransitionFromRight;
    [self.img.layer addAnimation:animation forKey:@"transition"];
}
- (NSArray *)imgsArr
{
    if (!_imgsArr) {
        _imgsArr = [NSArray arrayWithObjects:[self returnImage1WithCGSize:self.img.bounds.size andColor:[UIColor redColor]],
                                             [self returnImage1WithCGSize:self.img.bounds.size andColor:[UIColor greenColor]],
                                             [self returnImage1WithCGSize:self.img.bounds.size andColor:[UIColor cyanColor]],
                                             [self returnImage1WithCGSize:self.img.bounds.size andColor:[UIColor magentaColor]], nil];
    }
    return _imgsArr;
}
//根據size和傳進來的color生成一張顏色圖片
- (UIImage *)returnImage1WithCGSize:(CGSize)size andColor:(UIColor *)color
{
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, size.width, size.height)];
    [color setFill];
    [path fill];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return image;
}

我平時開發(fā)中的圖片輪播一般都是用這個動畫做的,加兩個手勢就行,缺點就是不能翻頁中間不能停留,沒有scroll那么全的功能,但是代碼簡單方便


kCATransitionPush_模仿輪播圖.gif

kCATransitionFade.gif

kCATransitionMoveIn.gif

kCATransitionReveal.gif

私有-cube.gif

示例: 我最近做項目遇到這樣一個問題,登錄界面跳到主界面的時候我一般喜歡用根視圖去跳,因為我認為登錄注冊界面可能八百年才用到一次,用導航或者模態(tài)來轉場不是太好,但是用根視圖跳轉顯得太突兀,動畫不太好看,這時轉場動畫便派上用場

//登錄
SideslipViewController *sideslip = [[SideslipViewController alloc] init];
[UIApplication sharedApplication].keyWindow.rootViewController = sideslip;
    
CATransition *transition = [[CATransition alloc] init];
transition.duration = 0.3;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
transition.type = kCATransitionReveal;
transition.subtype = kCATransitionFromTop;
[[UIApplication sharedApplication].keyWindow.layer addAnimation:transition forKey:@"LoginIn"];
//登出
LoginViewController *login = [[LoginViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:login];
nav.navigationBar.hidden = YES;
[UIApplication sharedApplication].keyWindow.rootViewController = nav;
    
CATransition *transition = [[CATransition alloc] init];
transition.duration = 0.3;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromBottom;
[[UIApplication sharedApplication].keyWindow.layer addAnimation:transition forKey:@"LoginOut"];
LoginInOrOut_Animation.gif
CASpringAnimation

iOS9之后出來的新的彈簧動畫,繼承CABasicAnimation

/** 一些重要的屬性
 *  CASpringAnimation的重要屬性:
 *
 *  mass:質量(影響彈簧的慣性,質量越大,彈簧慣性越大,運動的幅度越大)
 *  stiffness:彈性系數(彈性系數越大,彈簧的運動越快)
 *  damping:阻尼系數(阻尼系數越大,彈簧的停止越快)
 *  initialVelocity:初始速率(彈簧動畫的初始速度大小,彈簧運動的初始方向與初始速率的正負一致,若初始速率為0,表示忽略該屬性)
 *  settlingDuration:結算時間(根據動畫參數估算彈簧開始運動到停止的時間,動畫設置的時間最好根據此時間來設置)
 */
CASpringAnimation *animation = [CASpringAnimation animationWithKeyPath:@"position"];
animation.mass = 10.0;
animation.stiffness = 500;
animation.damping = 10;
animation.initialVelocity = 5.0f;
animation.duration = animation.settlingDuration; //時間需要注意下,用系統(tǒng)計算出來動畫所需時間
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(self.img.center.x, self.img.center.y + 200)];
[self.img.layer addAnimation:animation forKey:@"position"];

CASpringAnimation_position.gif

以上零散單個Demo地址: https://github.com/SupermanChao/Animation

CAAnimationGroup

使用Group可以將多個動畫合并一起加入到圖層中,Group中所有動畫一起執(zhí)行,可以展示很多動畫種類
一個簡單的動畫組例子,選取顏色
Demo地址:https://github.com/SupermanChao/AnimationGroup

Animation-Group.gif

CATransaction

最后講一下事務(CATransaction),在核心動畫里面存在事務(CATransaction)這樣一個概念,它負責協(xié)調多個動畫原子更新顯示操作,簡單來說事務是核心動畫里面的一個基本的單元,動畫的產生必然伴隨著layer的Animatable屬性的變化,而layer屬性的變化必須屬于某一個事務

事務分為隱式和顯式:

  • 隱式:沒有明顯調用事務的方法,由系統(tǒng)自動生成事務,比如直接設置一個layer的position屬性,則會在當前線程自動生成一個事務,并在下一個runLoop中自動commit事務
  • 顯式:明顯調用事務的方法([CATransaction begin]和[CATransaction commit])
事務的可設置屬性(會覆蓋隱式動畫的設置):
//動畫持續(xù)時間
+ (CFTimeInterval)animationDuration;
//動畫時間曲線
+ (nullable CAMediaTimingFunction *)animationTimingFunction;
//是否關閉動畫
+ (BOOL)disableActions;
//動畫執(zhí)行完畢回調
+ (nullable void (^)(void))completionBlock;

下面來個小例子,圓環(huán)進度動畫,先看效果后上代碼
代碼地址:https://github.com/SupermanChao/CATransaction-Demo

LCProgressAnimation.gif

//圓環(huán)貝塞爾曲線
- (UIBezierPath *)path
{
    if (!_path) {
        CGFloat radius = (MIN(self.frame.size.width, self.frame.size.height) - self.lineWidth) * 0.5;
        CGPoint center = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5);
        _path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:-M_PI_2 endAngle:M_PI + M_PI_2 clockwise:YES];
    }
    return _path;
}

//軌道
- (CAShapeLayer *)outLayer
{
    if (!_outLayer) {
        _outLayer = [CAShapeLayer layer];
        _outLayer.lineWidth = self.lineWidth;
        _outLayer.fillColor = [UIColor clearColor].CGColor;
        _outLayer.strokeColor = self.pathwayColor.CGColor;
        _outLayer.path = self.path.CGPath;
    }
    return _outLayer;
}

//進度
- (CAShapeLayer *)progressLayer
{
    if (!_progressLayer) {
        _progressLayer = [CAShapeLayer layer];
        _progressLayer.lineWidth = self.lineWidth;
        _progressLayer.fillColor = [UIColor clearColor].CGColor;
        _progressLayer.lineCap = kCALineCapRound;
        _progressLayer.strokeColor = self.scheduleColor.CGColor;
        _progressLayer.path = self.path.CGPath;
        _progressLayer.strokeStart = 0;
        _progressLayer.strokeEnd = 0.001;
    }
    return _progressLayer;
}

//定時器協(xié)調運作
- (void)onTimer
{
    switch (self.accuracy) {
        case LCAnimationAccuracyLow:
            self.progress += 2;
            break;
        case LCAnimationAccuracyHeight:
            self.progress += 0.5;
            break;
        case LCAnimationAccuracyVeryHeight:
            self.progress += 0.1;
            break;
        default:
            self.progress += 1;
            break;
    }
    
    [CATransaction begin];
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
    [CATransaction setAnimationDuration:self.totalTime / self.count];
    self.progressLayer.strokeEnd = self.progress / 100.0;
    [CATransaction commit];
    
    if (self.progress >= 99.99) {
        [self lc_stopAnimation];
        if ([self.delegate respondsToSelector:@selector(lc_animationFinishAction)]) {
            [self.delegate lc_animationFinishAction];
        }
    };
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,003評論 2 374

推薦閱讀更多精彩內容