iOS動畫- Core Animation

Core Animation譯為核心動畫,它是一組非常強(qiáng)大的動畫處理API。Core Animation的動畫執(zhí)行過程都是在后臺操作的宠叼,不會阻塞主線程。要注意的是其爵,Core Animation是直接作用在CALayer上的冒冬,并非UIView。


CALayer與UIView

  1. 每個 UIView 內(nèi)部都有一個 CALayer 在背后提供內(nèi)容的繪制和顯示摩渺,并且 UIView 的尺寸樣式都由內(nèi)部的 Layer 所提供简烤。兩者都有樹狀層級結(jié)構(gòu),layer 內(nèi)部有 SubLayers摇幻,View 內(nèi)部有 SubViews.但是 Layer 比 View 多了個AnchorPoint
  • 在 View顯示的時候横侦,UIView 做為 Layer 的 CALayerDelegate,View 的顯示內(nèi)容由內(nèi)部的 CALayer 的 display
  • CALayer 是默認(rèn)修改屬性支持隱式動畫的,在給 UIView 的 Layer 做動畫的時候绰姻,View 作為 Layer 的代理枉侧,Layer 通過 actionForLayer:forKey:向 View請求相應(yīng)的 action(動畫行為)
  • layer 內(nèi)部維護(hù)著三分 layer tree,分別是 presentLayer Tree(動畫樹),modeLayer Tree(模型樹), Render Tree (渲染樹),在做 iOS動畫的時候,我們修改動畫的屬性狂芋,在動畫的其實(shí)是 Layer 的 presentLayer的屬性值,而最終展示在界面上的其實(shí)是提供 View的modelLayer
  • 兩者最明顯的區(qū)別是 View可以接受并處理事件榨馁,而 Layer 不可以

Core Animation的結(jié)構(gòu)

Core Animation的結(jié)構(gòu).png

核心動畫中所有類都遵守CAMediaTiming協(xié)議。
CAAnaimation是個抽象類帜矾,不具備動畫效果翼虫,必須用它的子類才有動畫效果。

CAAnimationGroup和CATransition才有動畫效果屡萤,CAAnimationGroup是個動畫組珍剑,可以同時進(jìn)行縮放,旋轉(zhuǎn)(同時進(jìn)行多個動畫)灭衷。

CATransition是轉(zhuǎn)場動畫次慢,界面之間跳轉(zhuǎn)(切換)都可以用轉(zhuǎn)場動畫旁涤。

CAPropertyAnimation也是個抽象類翔曲,本身不具備動畫效果,只有子類才有劈愚。

CABasicAnimation和CAKeyframeAnimation:
CABasicAnimation基本動畫瞳遍,做一些簡單效果。
CAKeyframeAnimation幀動畫菌羽,做一些連續(xù)的流暢的動畫掠械。


CAAnimation協(xié)議-CAMediaTiming的屬性
//持續(xù)時間,默認(rèn)值是0.25秒
@property CFTimeInterval duration;
//重復(fù)次數(shù),無線循環(huán)可以設(shè)置HUGE_VALF或者CGFLOAT_MAX
@property float repeatCount;
//重復(fù)時間
@property CFTimeInterval repeatDuration;
/*
 可以用來設(shè)置動畫延時執(zhí)行猾蒂,若想延遲2s均唉,就設(shè)置為CACurrentMediaTIme() + 2
 CACurrentMediaTIme():圖層的當(dāng)前時間
 */
@property CFTimeInterval beginTime;
//動畫執(zhí)行速度
@property float speed;
//動畫的時間時間偏移量
@property CFTimeInterval timeOffset;
//是否自動返轉(zhuǎn)動畫,默認(rèn)NO.
 @property BOOL autoreverses;
//決定當(dāng)前對象在非active時間段的行為.比如動畫開始之前,動畫結(jié)束之后
@property(copy) NSString *fillMode;
/*
 kCAFillModeForwards    //當(dāng)動畫結(jié)束后,layer會一直保持著動畫最后的狀態(tài).
 kCAFillModeBackwards   //layer進(jìn)入動畫的初始狀態(tài)并等待動畫開始
 kCAFillModeBoth        //動畫加入后開始之前,layer便處于動畫初始狀態(tài),動畫結(jié)束后layer保持動畫最后的狀
 kCAFillModeRemoved     //動畫結(jié)束后,layer會恢復(fù)到之前的狀態(tài).
 */
CAAnimation的屬性
/*
 速度控制函數(shù),控制動畫運(yùn)行的節(jié)奏
 kCAMediaTimingFunctionLinear         勻速  
 kCAMediaTimingFunctionEaseIn         慢進(jìn)快出
 kCAMediaTimingFunctionEaseOut        快進(jìn)慢出
 kCAMediaTimingFunctionEaseInEaseOut  慢進(jìn)慢出 中間加速
 kCAMediaTimingFunctionDefault        默認(rèn)
*/
@property(nullable, strong) CAMediaTimingFunction *timingFunction;
/*
 默認(rèn)為YES肚菠,代表動畫執(zhí)行完畢后就從圖層上移除舔箭,圖形會恢復(fù)到動畫執(zhí)行前的狀態(tài)。
 如果想讓圖層保持顯示動畫執(zhí)行后的狀態(tài)蚊逢,那就設(shè)置為NO层扶,并且設(shè)置fillMode為kCAFillModeForwards
 */
@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
//動畫的代理回調(diào)
@property(nullable, strong) id delegate;

delegate方法

//動畫開始回調(diào)
- (void)animationDidStart:(CAAnimation *)anim;
//動畫結(jié)束回調(diào)
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;


CABaseAnimation 基礎(chǔ)動畫

主要提供了對于CALayer對象中的可變屬性進(jìn)行簡單動畫的操作
CABasicAnimation的屬性:

//開始值
@property(nullable, strong) id fromValue;
//結(jié)束值
@property(nullable, strong) id toValue;
//過渡值
@property(nullable, strong) id byValue;

三個屬性之間的規(guī)則

  1. fromValuetoValue不為空,動畫的效果會從fromValue的值變化到toValue.
  2. fromValuebyValue都不為空,動畫的效果將會從fromValue變化到fromValue+byValue
  3. toValuebyValue都不為空,動畫的效果將會從toValue-byValue變化到toValue
  4. 只有fromValue的值不為空,動畫的效果將會從fromValue的值變化到當(dāng)前的狀態(tài).
  5. 只有toValue的值不為空,動畫的效果將會從當(dāng)前狀態(tài)的值變化到toValue的值.
  6. 只有byValue的值不為空,動畫的效果將會從當(dāng)前的值變化到(當(dāng)前狀態(tài)的值+byValue)的值.

平移動畫

- (void)startSimpleAnimation
{
    //初始化平移動畫
    CABasicAnimation *baseAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
    //設(shè)置屬性
    baseAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    baseAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 300)];
    baseAnimation.duration = 5.0;
    baseAnimation.repeatCount = 2;
    //動畫執(zhí)行完,保持在最后的狀態(tài)
    baseAnimation.removedOnCompletion = NO;
    baseAnimation.fillMode = kCAFillModeForwards;
    baseAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    //layer添加動畫
    [self.simpleView.layer addAnimation:baseAnimation forKey:@"positionAniamtion"];
}

注:

  • 如果removedOnComletion=NO并且fillMode=kCAFillModeForwards烙荷,那么在動畫執(zhí)行完畢后镜会,圖層會保持顯示動畫執(zhí)行后的狀態(tài)。但在實(shí)質(zhì)上终抽,圖層的屬性值還是動畫執(zhí)行前的初始值戳表,并沒有真正被改變。比如拿诸,CALayer的position初始值為(0,0)扒袖,CABasicAnimation的fromValue為(100,100)坦刀,toValue為(200,300)灭抑,雖然動畫執(zhí)行完畢后圖層保持在(200,300)這個位置,實(shí)質(zhì)上圖層的position還是為(0,0)
  • 如果不設(shè)置removedOnComletion=NO躲庄,那么默認(rèn)為YES描沟,動畫執(zhí)行后飒泻,圖層會回到原來的位置。為什么動畫結(jié)束后返回原狀態(tài)吏廉?首先我們需要搞明白一點(diǎn)的是泞遗,layer動畫運(yùn)行的過程是怎樣的?其實(shí)在我們給一個視圖添加layer動畫時席覆,真正移動并不是我們的視圖本身史辙,而是 presentation layer 的一個緩存。動畫開始時 presentation layer開始移動佩伤,原始layer隱藏聊倔,動畫結(jié)束時,presentation layer從屏幕上移除生巡,原始layer顯示耙蔑。這就解釋了為什么我們的視圖在動畫結(jié)束后又回到了原來的狀態(tài),因為它根本就沒動過孤荣。
  • 這個同樣也可以解釋為什么在動畫移動過程中甸陌,我們?yōu)楹尾荒軐ζ溥M(jìn)行任何操作须揣。所以在我們完成layer動畫之后,最好將我們的layer屬性設(shè)置為我們最終狀態(tài)的屬性钱豁,然后將presentation layer 移除掉耻卡。

透明度變化動畫

-(void)opacityAniamtion{
    CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"opacity"];
    anima.fromValue = [NSNumber numberWithFloat:1.0f];
    anima.toValue = [NSNumber numberWithFloat:0.2f];
    anima.duration = 1.0f;
    [self.simpleView.layer addAnimation:anima forKey:@"opacityAniamtion"];
}

背景色變化動畫

-(void)backgroundAnimation{
    CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    anima.toValue =(id) [UIColor greenColor].CGColor;
    anima.duration = 1.0f;
    [self.simpleView.layer addAnimation:anima forKey:@"backgroundAnimation"];
}
KeyPath的值
KeyPath.png

CASpringAnimation 彈性動畫(iOS9+)

繼承與CABasicAnimation
屬性


//質(zhì)量,振幅和質(zhì)量成反比
@property CGFloat mass;
//剛度系數(shù)(勁度系數(shù)/彈性系數(shù)),剛度系數(shù)越大,形變產(chǎn)生的力就越大,運(yùn)動越快
@property CGFloat stiffness;
//阻尼系數(shù),阻止彈簧伸縮的系數(shù),阻尼系數(shù)越大,停止越快,可以認(rèn)為它是阻力系數(shù)
@property CGFloat damping;
//初始速率,動畫視圖的初始速度大小速率為正數(shù)時,速度方向與運(yùn)動方向一致,速率為負(fù)數(shù)時,速度方向與運(yùn)動方向相反.
@property CGFloat initialVelocity;
//結(jié)算時間,只讀.返回彈簧動畫到停止時的估算時間,根據(jù)當(dāng)前的動畫參數(shù)估算通常彈簧動畫的時間使用結(jié)算時間比較準(zhǔn)確
@property(readonly) CFTimeInterval settlingDuration;

應(yīng)用

- (void)springAnimation{
    CASpringAnimation *spring = [CASpringAnimation animationWithKeyPath:@"position.y"];
    spring.damping = 5;
    spring.stiffness = 100;
    spring.mass = 1;
    spring.initialVelocity = 0;
    spring.duration = spring.settlingDuration;
    spring.fromValue = @(self.simpleView.center.y);
    spring.toValue = @(self.simpleView.center.y + 200);
    spring.fillMode = kCAFillModeForwards;
    [self.simpleView.layer addAnimation:spring forKey:nil];
}


CAKeyframeAnimation 關(guān)鍵幀動畫

Keyframe顧名思義就是關(guān)鍵點(diǎn)的frame牲尺,你可以通過設(shè)定CALayer的始點(diǎn)劲赠、中間關(guān)鍵點(diǎn)、終點(diǎn)的frame秸谢,時間凛澎,動畫會沿你設(shè)定的軌跡進(jìn)行移動 。

屬性解析

/*
 NSArray對象估蹄。里面的元素稱為”關(guān)鍵幀”(keyframe)塑煎。
 動畫對象會在指定的時間(duration)內(nèi),依次顯示values數(shù)組中的每一個關(guān)鍵幀 .
 */
@property(nullable, copy) NSArray *values;
/*
 可以設(shè)置一個CGPathRef\CGMutablePathRef,讓層跟著路徑移動臭蚁。
 path只對CALayer的anchorPoint和position起作用最铁。如果你設(shè)置了path,那么values將被忽略
 */
@property(nullable) CGPathRef path;
/*
  可以為對應(yīng)的關(guān)鍵幀指定對應(yīng)的時間點(diǎn),其取值范圍為0到1.0,keyTimes中的每一個時間值都對應(yīng)values中的每一幀.
  當(dāng)keyTimes沒有設(shè)置的時候,各個關(guān)鍵幀的時間是平分的 .
  */
@property(nullable, copy) NSArray<NSNumber *> *keyTimes;

CABasicAnimation可看做是最多只有2個關(guān)鍵幀的CAKeyframeAnimation

anchorPoint和position的區(qū)別

  1. position用來設(shè)置CALayer在父層中的位置以父層的左上角為原點(diǎn)(0, 0)
  2. anchorPoint稱為“定位點(diǎn)”垮兑、“錨點(diǎn)”冷尉,決定著CALayer身上的哪個點(diǎn)會在position屬性所指的位置。以自己的左上角為原點(diǎn)(0, 0)系枪,它的x雀哨、y取值范圍都是0~1,默認(rèn)值為中心點(diǎn)(0.5, 0.5)
  3. 假如錨點(diǎn)anchorPoint為默認(rèn)值即中點(diǎn)(0.5私爷,0.5)雾棺,而該層的position設(shè)置為(0,0)即為父層的左上點(diǎn)衬浑。anchorPoint默認(rèn)值情況可以理解position為center捌浩。
- (void)positionAniamtion
{
    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    
    //這個點(diǎn)是初始點(diǎn),從這個點(diǎn)開始動畫
    NSValue *value_1 = [NSValue valueWithCGPoint:CGPointMake(100, 500)];
    NSValue *value_2 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
    NSValue *value_3 = [NSValue valueWithCGPoint:CGPointMake(100, 400)];
    //keyTimes中的值是從0.0遞增到1.0
    NSNumber *time_1 = [NSNumber numberWithFloat:0.1];
    NSNumber *time_2 = [NSNumber numberWithFloat:0.6];
    NSNumber *time_3 = [NSNumber numberWithFloat:1.0];
    keyAnimation.values = [NSArray arrayWithObjects:value_1,value_2,value_3, nil];
    //keyTimes是對應(yīng)values的
    keyAnimation.keyTimes = [NSArray arrayWithObjects:time_1,time_2,time_3, nil];
    
    /*
     設(shè)置path工秩,values會失效
     UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 200, 200)];
     keyAnimation.path = path.CGPath;
     */
    keyAnimation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
                                     [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
                                     [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    
    /*
     kCAAnimationLinear    //連續(xù)運(yùn)算模式尸饺,線性。表示當(dāng)關(guān)鍵幀為座標(biāo)點(diǎn)的時候,關(guān)鍵幀之間直接直線相連進(jìn)行插值計算;
     kCAAnimationDiscrete  //離散運(yùn)算模式助币,只顯示關(guān)鍵幀浪听。就是不進(jìn)行插值計算,所有關(guān)鍵幀直接逐個進(jìn)行顯示;
     kCAAnimationPaced     //均勻執(zhí)行運(yùn)算模式,線性奠支。使動畫均勻進(jìn)行,而不是按keyTimes設(shè)置的或者按關(guān)鍵幀平分時間,此時keyTimes和timingFunctions無效; 
     kCAAnimationCubic     //平滑運(yùn)算模式馋辈。對關(guān)鍵幀為座標(biāo)點(diǎn)的關(guān)鍵幀進(jìn)行圓滑曲線相連后插值計算抚芦,這里的主要目的是使得運(yùn)行的軌跡變得圓滑倍谜;
     kCAAnimationCubicPaced//平滑均勻運(yùn)算模式迈螟。在kCAAnimationCubic的基礎(chǔ)上使得動畫運(yùn)行變得均勻,就是系統(tǒng)時間內(nèi)運(yùn)動的距離相同,此時keyTimes以及timingFunctions也是無效的.
     */
    keyAnimation.calculationMode = kCAAnimationPaced;
    keyAnimation.duration = 5.0;
    [self.simpleView.layer addAnimation:keyAnimation forKey:@"positionAniamtion"];
}


CAAnimationGroup 動畫組

可以保存一組動畫對象,將CAAnimationGroup對象加入層后尔崔,組中所有動畫對象可以同時并發(fā)運(yùn)行.

animations:用來保存一組動畫對象的NSArray.

默認(rèn)情況下答毫,一組動畫對象是同時運(yùn)行的,也可以通過設(shè)置動畫對象的beginTime屬性來更改動畫的開始時間.


CATransition 轉(zhuǎn)場動畫

用于做轉(zhuǎn)場動畫季春,能夠為層提供移出屏幕和移入屏幕的動畫效果洗搂。UINavigationController就是通過CATransition實(shí)現(xiàn)了將控制器的視圖推入屏幕的動畫效果.

屬性

//動畫過渡類型
@property(copy) NSString *type;
//動畫過渡方向
@property(nullable, copy) NSString *subtype;
//動畫起點(diǎn)(在整體動畫的百分比)
@property float startProgress;
//動畫終點(diǎn)(在整體動畫的百分比)
@property float endProgress;

應(yīng)用

/*type過渡效果
  fade                  //交叉淡化過渡(不支持過渡方向) kCATransitionFade
  push                  //新視圖把舊視圖推出去  kCATransitionPush
  moveIn                //新視圖移到舊視圖上面   kCATransitionMoveIn
  reveal                //將舊視圖移開,顯示下面的新視圖  kCATransitionReveal
  cube                  //立方體翻滾效果
  oglFlip               //上下左右翻轉(zhuǎn)效果
  suckEffect            //收縮效果,如一塊布被抽走(不支持過渡方向)
  rippleEffect          //滴水效果(不支持過渡方向)
  pageCurl              //向上翻頁效果
  pageUnCurl            //向下翻頁效果
  cameraIrisHollowOpen  //相機(jī)鏡頭打開效果(不支持過渡方向)
  cameraIrisHollowClose //相機(jī)鏡頭關(guān)上效果(不支持過渡方向)
 */    
 /*subtype過渡方向
  kCATransitionFromRight
  kCATransitionFromLeft
  kCATransitionFromBottom 
  kCATransitionFromTop
  */
  // CATransition的使用 
  CATransition *transition = [CATransition animation];
  transition.type = @"pageUnCurl";
  transition.subtype = kCATransitionFromBottom;
  transition.duration = 2.0;
  transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  [self.simpleView.layer addAnimation:transition forKey:@"transition"];

暫停動畫/恢復(fù)動畫
//暫停主要是設(shè)置timeOffset
- (void)pauseAnimation
{
    // t = (tp - begin) * speed + timeOffset

    //將圖層當(dāng)前時間(CACurrentMediaTime())轉(zhuǎn)換成parent time
    CFTimeInterval pauseTime = [self.simpleView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    /*
     speed = parent time / local time (默認(rèn)為1.0)
     speed = 0.0時意味暫停;
     speed = 2.0時是local time的進(jìn)度是parent time的2倍载弄,
     即同一動畫效果parent time需要2秒耘拇,而local time只需要1秒
     */
    self.simpleView.layer.speed = 0.0;
    /*
     timeOffset是local time的時間偏移量
     與speed = 0結(jié)合,表示layer在timeOffset時間偏移量的位置暫停
     */
    self.simpleView.layer.timeOffset = pauseTime;
    
}
/* beginTime的理解
 1. 默認(rèn)beginTime=0.0,并且是相對parent time的
 2. 所以在某種意義上 0.0 是等于 [self.simpleView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    可以通過代理方法animationDidStart宇攻,animationDidStop惫叛,獲取parent time來確認(rèn)
 3. beginTime是用來設(shè)置動畫執(zhí)行時間的,設(shè)置方式如下:
    beginTime = CACurrentMediaTIme()+2,即延遲2秒執(zhí)行動畫逞刷,且動畫執(zhí)行時間還是duration
    beginTime = CACurrentMediaTIme()-2,即從動畫的第2秒開始執(zhí)行嘉涌,并且動畫執(zhí)行時間為duration-2,意味舍棄了前2秒的動畫
 4. 當(dāng)speed = 1.0(默認(rèn)值)&& timeOffset = 0.0(默認(rèn)值)&& beginTime = 0.0(默認(rèn)值)時
    CACurrentMediaTime() = [self.simpleView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    因為[self.simpleView.layer convertTime:CACurrentMediaTime() fromLayer:nil]做的事就是t = (tp-begin) * speed+timeOffset
 */

//恢復(fù)開始主要是將timeOffset轉(zhuǎn)化為beginTime
- (void)startAnimation
{
    CFTimeInterval pausedTime = self.simpleView.layer.timeOffset;
    // 1. 讓CALayer的時間繼續(xù)行走
    self.simpleView.layer.speed = 1.0;
    // 2. 取消上次記錄的停留時刻
    self.simpleView.layer.timeOffset = 0.0;
    // 3. 取消上次設(shè)置的時間
    self.simpleView.layer.beginTime = 0.0;
    // 4. 計算暫停的時間(這里也可以用CACurrentMediaTime()-pausedTime)
    CFTimeInterval timeSincePause = [self.simpleView.layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    // 5. 設(shè)置相對于父坐標(biāo)系的開始時間(往后退timeSincePause)
    self.simpleView.layer.beginTime = timeSincePause;
    
}

參考資料:
iOS動畫-從不會到熟練應(yīng)用
iOS中的動畫
iOS Core Animation詳解
詳解 CALayer 和 UIView 的區(qū)別和聯(lián)系

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末夸浅,一起剝皮案震驚了整個濱河市仑最,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌帆喇,老刑警劉巖警医,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異坯钦,居然都是意外死亡法严,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門葫笼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來深啤,“玉大人,你說我怎么就攤上這事路星∷萁郑” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵洋丐,是天一觀的道長呈昔。 經(jīng)常有香客問我,道長友绝,這世上最難降的妖魔是什么堤尾? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮迁客,結(jié)果婚禮上郭宝,老公的妹妹穿的比我還像新娘辞槐。我一直安慰自己,他們只是感情好粘室,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布榄檬。 她就那樣靜靜地躺著,像睡著了一般衔统。 火紅的嫁衣襯著肌膚如雪鹿榜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天锦爵,我揣著相機(jī)與錄音舱殿,去河邊找鬼。 笑死险掀,一個胖子當(dāng)著我的面吹牛怀薛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播迷郑,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼枝恋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嗡害?” 一聲冷哼從身側(cè)響起焚碌,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎霸妹,沒想到半個月后十电,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叹螟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年鹃骂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罢绽。...
    茶點(diǎn)故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡畏线,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出良价,到底是詐尸還是另有隱情寝殴,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布明垢,位于F島的核電站蚣常,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏痊银。R本人自食惡果不足惜抵蚊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贞绳,春花似錦谷醉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豺裆。三九已至拒秘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間臭猜,已是汗流浹背躺酒。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔑歌,地道東北人羹应。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像次屠,于是被迫代替她去往敵國和親园匹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評論 2 355

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