Quartz2D --> 二維繪圖引擎(四-漸變、透明層)

一、Gradients(漸變)

漸變是從一個顏色到另外一種顏色變化的填充啤誊。Quartz 提供了 CGShadingRef 和 CGGradientRef 兩種數(shù)據(jù)類型來創(chuàng)建軸向或徑向漸變捐寥。

  • axial gradient --- 軸向漸變(也稱為線性漸變)沿著由兩個端點連接的軸線漸變帽驯。所有位于垂直于軸線的某條線上的點都具有相同的顏色值寸痢。
  • radial gradient --- 徑向漸變是沿著兩個端點連接的軸線放射狀漸變,不過路徑通常由兩個圓來定義哨坪,所有位于以軸線上點為圓心的圓的周長上點都具有相同的顏色值庸疾。
1、CGShading 和 CGGradient 對象的對比

CGGradient 是 CGShading 的子集当编,更易于使用,而 CGShading可以定義更加復(fù)雜的漸變徒溪。這兩個類型都可以繪制軸向漸變和徑向漸變忿偷。

CGGradient CGShading
可以使用同一個CGGradient對象繪制軸向和徑向漸變 需要為軸向漸變和徑向漸變創(chuàng)建不同的 CGShading 對象
設(shè)置CGGradient對象的漸變的幾何形狀(軸向或徑向)是在繪制時指定的 是在創(chuàng)建時指定的
Quartz來計算漸變梯度上每個點對應(yīng)的顏色值(不需要過多的人為干擾) 必須提供使用 CGFunctionRef 回調(diào)函數(shù)來計算漸變梯度上每個點對應(yīng)的顏色值
可以容易的定義多個定位點和顏色 需要設(shè)計自己的回調(diào)函數(shù)來定義多個定位點和顏色,所以需要我們手動處理更多的東西
2臊泌、CGGradient 的使用

CGGradient 是漸變的抽象定義鲤桥,它只指定了顏色和位置,但沒有指定幾何形狀渠概。我們可以在軸向和徑向幾何形狀中使用它茶凳。這樣使它更容易重用。

使用CGGradient對象創(chuàng)建和畫一個漸變相當(dāng)簡單,需要以下步驟:

  • 創(chuàng)建CGGradient對象:
    • 使用函數(shù)CGGradientRef __nullable CGGradientCreateWithColorComponents( CGColorSpaceRef cg_nullable space, const CGFloat * cg_nullable components, const CGFloat * __nullable locations, size_t count)創(chuàng)建播揪。參數(shù)含義:space --- 顏色空間贮喧,components --- 顏色組件, locations --- 位置組件(如果“ locations”為NULL,第一個顏色在“顏色”將在位置0,最后的顏色在“顏色”將在位置1,其余的將在中間均勻分布猪狈。否則每個位置的值都應(yīng)該是0-1的CGFloat類型箱沦。如果沒有提供0和1的位置,漸變將會使用接近0和1位置的那些值雇庙。)谓形, count --- 想使用的顏色組件數(shù)量。
    • 使用函數(shù)CGGradientRef __nullable CGGradientCreateWithColors( CGColorSpaceRef __nullable space, CFArrayRef cg_nullable colors, const CGFloat * __nullable locations)創(chuàng)建疆前。這里如果space不為NULL 寒跳,則所有顏色數(shù)組中的顏色都將轉(zhuǎn)換到改顏色空間,若為NULL,則將會使用通用RGB顏色空間竹椒,但是iOS只允許使用設(shè)備空間顏色童太,所以iOS應(yīng)用這里不能為NULL !!!。這里colors是CFArrayRef類型的,這里必須是包含CGColor類型對象的非空數(shù)組康愤。
  • 繪制漸變:
    • 使用函數(shù)CGContextDrawLinearGradient(CGContextRef cg_nullable c, CGGradientRef cg_nullable gradient, CGPoint startPoint, CGPoint endPoint, CGGradientDrawingOptions options)繪制線性漸變儡循。
    • 使用函數(shù)CGContextDrawRadialGradient(CGContextRef cg_nullable c, CGGradientRef cg_nullable gradient, CGPoint startCenter, CGFloat startRadius, CGPoint endCenter, CGFloat endRadius, CGGradientDrawingOptions options)創(chuàng)建徑向漸變。

這里參數(shù)options是一個枚舉類型:

typedef CF_OPTIONS (uint32_t, CGGradientDrawingOptions) {
  kCGGradientDrawsBeforeStartLocation = (1 << 0), // 漸變可以波及起點之前
  kCGGradientDrawsAfterEndLocation = (1 << 1) // 漸變可以波及終點之后
};
  • 當(dāng)不再需要時釋放CGGradient對象征冷。

示例:

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGGradientRef gradient;
    CGColorSpaceRef colorSpace;
    colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFloat locations[] = {0.0, 0.1, 0.5, 0.6, 0.8, 1.0};
    CGFloat colorComponents[] = {1.0, 0.0, 0.0, 1.0,
                                 1.0, 1.0, 0.0, 1.0,
                                 1.0, 0.0, 1.0, 1.0,
                                 0.0, 1.0, 0.0, 1.0,
                                 0.0, 1.0, 1.0, 1.0,
                                 0.0, 0.0, 1.0, 1.0};
    gradient = CGGradientCreateWithColorComponents(colorSpace, colorComponents, locations, 6);
//    CFArrayRef colorArray;
//    NSArray * array = @[(id)[UIColor redColor].CGColor, (id)[UIColor cyanColor].CGColor, (id)[UIColor yellowColor].CGColor, (id)[UIColor blueColor].CGColor];
//    colorArray = (__bridge CFArrayRef)array;
//    gradient = CGGradientCreateWithColors(colorSpace, colorArray, locations);
    
//    CGContextDrawLinearGradient(currentContext, gradient, CGPointMake(50, 50), CGPointMake(150, 150), 0); // 0 代表兩端均不超范圍渲染
    CGContextDrawRadialGradient(currentContext, gradient, CGPointMake(50, 50), 30, CGPointMake(150, 150), 100, 0);
    CGColorSpaceRelease(colorSpace);
    CGGradientRelease(gradient);
}

效果圖:

CGGradientCreateWithColors()函數(shù)創(chuàng)建的線性漸變

CGGradientCreateWithColorComponents()函數(shù)創(chuàng)建線性漸變
徑向漸變
3择膝、CGShading的使用

CGShadingRef不透明的數(shù)據(jù)類型可以讓你自己控制顏色在每個點的梯度計算。這就必須在創(chuàng)建一個CGShading對象之前,先創(chuàng)建一個CGFunction類型對象(CGFunctionRef)检激,用以定義一個計算顏色漸變的函數(shù)肴捉。CGShading 使用戶有更高的控制權(quán),可以定義更加復(fù)雜的漸變叔收。
?因為創(chuàng)建CGFunctionRef函數(shù)中需要使用回調(diào)函數(shù)齿穗,所以下面從回調(diào)函數(shù)開始一步步去了解CGShading的使用。

  • 創(chuàng)建CGFunctionRef函數(shù)中的回調(diào)函數(shù):該回調(diào)函數(shù)是結(jié)構(gòu)體類型:
struct CGFunctionCallbacks {
    unsigned int version; // 版本數(shù)據(jù)一般使用0
    CGFunctionEvaluateCallback __nullable evaluate; //  用于評估函數(shù)的回調(diào)饺律,一般不可為NULL
    CGFunctionReleaseInfoCallback __nullable releaseInfo; // 如果用于評估函數(shù)的回調(diào)中info為NULL,則這里也可以是NULL,
    // 若不為NULL,該回調(diào)用于在CGFunction被銷毀時release在CGFunction 創(chuàng)建時傳給function的info參數(shù)信息窃页。
};
typedef struct CGFunctionCallbacks CGFunctionCallbacks; 
創(chuàng)建評估函數(shù)回調(diào):樣式必須與下面的類似,函數(shù)名可以隨意复濒,但是參數(shù)必須一致脖卖!

void (*CGFunctionEvaluateCallback)(void * __nullable info, const CGFloat * in, CGFloat * out)
?(1、) info : 這是一個接受CGFunctionCreate函數(shù)傳遞的info信息的參數(shù)巧颈。
?(1畦木、) in:浮點數(shù)的數(shù)組,Quartz 傳遞 in 數(shù)組給回調(diào)砸泛,數(shù)組中的值必須在CGFunction對象定義的輸入值范圍內(nèi)十籍。數(shù)組的大小是由CGFunctionCreate函數(shù)中domainDimension參數(shù)傳遞的數(shù)據(jù)指定的。
?(1唇礁、) out:浮點數(shù)的數(shù)組勾栗,回調(diào)函數(shù)傳遞 out 數(shù)組給 Quartz,它包含用于顏色空間中每個顏色組件的元素及一個 alpha 值垒迂。輸出值應(yīng)該在 CGFunction 對象定義的輸出值范圍內(nèi)械姻。數(shù)組的大小是由CGFunctionCreate函數(shù)中rangeDimension參數(shù)傳遞的數(shù)據(jù)指定的。
? 示例:

// 這一函數(shù)實現(xiàn)的是平方的功能
void evaluateSquare(void *info, const float *inData, float *outData)
{
    outData[0] = inData[0] * inData[0];
}
void MyFunctionEvaluateCallback(void * __nullable info, const CGFloat *  in, CGFloat *  out)
{
    CGFloat v;
    size_t k, components;
    static const CGFloat c[] = {1, 0, .5, 0 }; // 定義基準(zhǔn)顏色數(shù)組
    components = (size_t)info;
    v = *in; // 獲取輸入的值
    for (k = 0; k < components -1; k++){
        *out++ = c[k] * v; // 設(shè)置算法机断,獲取想要輸出的結(jié)果楷拳。
        // 該結(jié)果是指輸出結(jié)果為在基準(zhǔn)顏色定義上獲取與輸入值相乘結(jié)果后的顏色
        // 在下面的例子中輸入的domainDimension參數(shù)為{0, 1}吏奸,所以輸出顏色會為(0欢揖,0,0)和(1奋蔚,0她混,0.5)
    }
    *out++ = 1; // 將 alpha值恒為 1烈钞。
}
  • 創(chuàng)建CGFunctionRef函數(shù):使用函數(shù)CGFunctionRef __nullable CGFunctionCreate(void * __nullable info, size_t domainDimension, const CGFloat *__nullable domain, size_t rangeDimension, const CGFloat * __nullable range, const CGFunctionCallbacks * cg_nullable callbacks)。其中參數(shù)的意義:
    • info : 傳遞給回調(diào)函數(shù)的額外信息的參數(shù)坤按,可以為NULL.
    • domainDimension :輸入給回調(diào)函數(shù)的值的數(shù)量毯欣。
    • domain:是一個含有2M個元素的字符數(shù)組,M是輸入值的數(shù)量即domainDimension臭脓。對于從0到(M-1)之間的每一個數(shù)字k來說酗钞,必須有domain[2k] <= domain[2k + 1],在該區(qū)間內(nèi)in[k]將會被限制剪切来累,即domain[2k] <= in[k] <= domain[2k + 1]砚作。即:給每個輸入值規(guī)定一范圍,輸入值必須在設(shè)置的范圍以內(nèi)嘹锁。 如果domain 為NULL,則輸入值不會被剪切葫录。但強(qiáng)烈建議設(shè)置domain。
    • rangeDimension:從回調(diào)函數(shù)輸出的值的數(shù)量领猾。
    • range:與domain一樣米同,不過是針對的輸出值!瘤运!
    • callbacks:回調(diào)函數(shù)窍霞。

??示例:

static CGFunctionRef MyGetFunction(CGColorSpaceRef colorspace)
{
    size_t numComponents;
    static const CGFloat input_value_range [2] = { 0, 1};
    static const CGFloat output_value_ranges [8] = { 0, 1, 0, 1, 0, 1, 0, 1 };
    static const CGFunctionCallbacks callbacks = { 0, &MyFunctionEvaluateCallback, NULL};
    numComponents = 1 + CGColorSpaceGetNumberOfComponents (colorspace);
    return CGFunctionCreate ((void *) numComponents, 1, input_value_range, numComponents, output_value_ranges, &callbacks);
}
  • 創(chuàng)建CGShading對象:一、使用函數(shù)CGShadingRef __nullable CGShadingCreateAxial( CGColorSpaceRef cg_nullable space, CGPoint start, CGPoint end, CGFunctionRef cg_nullable function, bool extendStart, bool extendEnd)創(chuàng)建線性漸變拯坟。參數(shù):space - 顏色空間、start - 起始點韭山、end - 結(jié)束點郁季、function - 計算函數(shù)、extendStart - 是否渲染起始點以外的區(qū)域钱磅、extendEnd - 是否渲染j結(jié)束點以外的區(qū)域梦裂。 二、使用函數(shù)CGShadingRef __nullable CGShadingCreateRadial( CGColorSpaceRef cg_nullable space, CGPoint start, CGFloat startRadius, CGPoint end, CGFloat endRadius, CGFunctionRef cg_nullable function, bool extendStart, bool extendEnd)創(chuàng)建徑向漸變盖淡。參數(shù)詳情這里不再贅述年柠。

  • Clip the Context And Drawing CGShading Object(裁剪上下文、繪制CGShading對象)
    ?繪制漸變的工作原理不同于顏色和圖案可以使用stroke和fill描繪對象褪迟。如果要出現(xiàn)想要的特定形狀需要相應(yīng)的剪切上下文冗恨。使用繪制函數(shù)CGContextDrawShading(CGContextRef cg_nullable c, cg_nullable CGShadingRef shading)進(jìn)行繪制

  • 最后將創(chuàng)建的都要記得釋放掉。

完整示例:線性漸變

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGShadingRef shading;
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFunctionRef function = MyGetFunction(colorSpace);
    shading = CGShadingCreateAxial(colorSpace, CGPointMake(50, 50), CGPointMake(150, 150), function, NO, NO);
    CGContextSaveGState(currentContext);
    UIBezierPath * bezierPath = [UIBezierPath bezierPath];
    [bezierPath addArcWithCenter:CGPointMake(100, 100) radius:50 startAngle:M_PI endAngle:M_PI * 2 clockwise:YES];
    [bezierPath closePath];
    CGContextAddPath(currentContext, bezierPath.CGPath);
    CGContextClip(currentContext);
    CGContextDrawShading(currentContext, shading);
    CGColorSpaceRelease(colorSpace);
    CGFunctionRelease(function);
    CGShadingRelease(shading);
    CGContextRestoreGState(currentContext);
}

void MyFunctionEvaluateCallback(void * __nullable info, const CGFloat *  in, CGFloat *  out)
{
    CGFloat v;
    size_t k, components;
    static const CGFloat c[] = {1, 0, .5, 0 };
    components = (size_t)info;
    v = *in;
    for (k = 0; k < components -1; k++){
        *out++ = c[k] * v;
    }
    *out++ = 1;
}

static CGFunctionRef MyGetFunction(CGColorSpaceRef colorspace)
{
    size_t numComponents;
    static const CGFloat input_value_range [2] = { 0, 1};
    static const CGFloat output_value_ranges [8] = { 0, 1, 0, 1, 0, 1, 0, 1 };
    static const CGFunctionCallbacks callbacks = { 0, &MyFunctionEvaluateCallback, NULL};
    numComponents = 1 + CGColorSpaceGetNumberOfComponents (colorspace);
    return CGFunctionCreate ((void *) numComponents, 1, input_value_range, numComponents, output_value_ranges, &callbacks);
}
效果圖

完整示例:徑向漸變

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGShadingRef shading;
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFunctionRef function = MyGetFunction(colorSpace);
    shading = CGShadingCreateRadial(colorSpace, CGPointMake(50, 300), 50, CGPointMake(200, 100), 100, function, NO, NO);
    CGContextSaveGState(currentContext);
    UIBezierPath * bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 300, 400)];
    CGContextAddPath(currentContext, bezierPath.CGPath);
    CGContextClip(currentContext);
    CGContextDrawShading(currentContext, shading);
    CGColorSpaceRelease(colorSpace);
    CGFunctionRelease(function);
    CGShadingRelease(shading);
    CGContextRestoreGState(currentContext);
}

void MyFunctionEvaluateCallback(void * __nullable info, const CGFloat *  in, CGFloat *  out)
{
    size_t k, components;
    double frequency[4] = { 55, 220, 110, 0 };
    components = (size_t)info;
    for (k = 0; k < components - 1; k++){
        *out++ = (1 + sin(*in * frequency[k]))/2;
    }
    *out++ = 1; // alpha
}
static CGFunctionRef MyGetFunction(CGColorSpaceRef colorspace)
{
    size_t numComponents;
    static const CGFloat input_value_range [2] = { 0, 1};
    static const CGFloat output_value_ranges [8] = { 0, 1, 0, 1, 0, 1, 0, 1 };
    static const CGFunctionCallbacks callbacks = { 0, &MyFunctionEvaluateCallback, NULL};
    numComponents = 1 + CGColorSpaceGetNumberOfComponents (colorspace);
    return CGFunctionCreate ((void *) numComponents, 1, input_value_range, numComponents, output_value_ranges, &callbacks);
}
效果圖

?從上面兩個示例代碼可以看出這兩個示例代碼最重要的兩個差異的地方就是:1味赃、線性漸變示例代碼創(chuàng)建shading對象使用CGShadingCreateAxial() 函數(shù)掀抹,而徑向漸變示例代碼使用CGShadingCreateRadial() 函數(shù),這決定了繪制漸變的本質(zhì)的不同心俗。2傲武、回調(diào)函數(shù)部分完全不同蓉驹,回調(diào)函數(shù)其實就是決定了計算漸變梯度上每個點對應(yīng)的顏色值。根據(jù)不同的計算方式可以實現(xiàn)各種漸變展示揪利,當(dāng)然這很需要對數(shù)學(xué)函數(shù)的理解~??????态兴。

二、Transparency Layers(透明層)

?透明層由兩個或兩個以上的對象組合而產(chǎn)生一個復(fù)合圖形疟位。復(fù)合結(jié)果被視為一個單獨的對象瞻润。透明層是可以嵌套的。

繪制Transparency Layers:

  • 開啟透明層繪制:

    • 使用函數(shù)CGContextBeginTransparencyLayer(CGContextRef cg_nullable c, CFDictionaryRef __nullable auxiliaryInfo)字典讓你提供選項來指定關(guān)于layer的附加信息,但由于在Quartz 2D API中該字典還沒有被使用,所以傳遞NULLO缀埂8叶!
    • 使用函數(shù)CGContextBeginTransparencyLayerWithRect( CGContextRef cg_nullable c, CGRect rect, CFDictionaryRef __nullable auxInfo)相對于上一函數(shù)多了一個限制邊界的參數(shù)rect罢吃。
  • 在透明層中繪制需要組合的對象楚午。

  • 調(diào)用函數(shù)CGContextEndTransparencyLayer(CGContextRef cg_nullable c)結(jié)束透明層繪制。

示例:

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGSize myShadowOffset = CGSizeMake (-20, 30);
    CGContextSetShadow (currentContext, myShadowOffset, 10);
    CGContextBeginTransparencyLayer(currentContext, NULL);
    CGGradientRef gradientCop;
    CGGradientRef gradientBed;
    CGColorSpaceRef colorSpace;
    colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFloat colorComponents[] = {1.0, 0.0, 0.0, 1.0,
                                 1.0, 1.0, 0.0, 1.0,
                                 1.0, 0.0, 1.0, 1.0,
                                 0.0, 1.0, 0.0, 1.0,
                                 0.0, 1.0, 1.0, 1.0,
                                 0.0, 0.0, 1.0, 1.0};
    gradientCop = CGGradientCreateWithColorComponents(colorSpace, colorComponents, NULL, 6);
    gradientBed = CGGradientCreateWithColorComponents(colorSpace, colorComponents, NULL, 6);
    CGContextSaveGState(currentContext);
    UIBezierPath * copPath = [UIBezierPath bezierPath];
    [copPath moveToPoint:CGPointMake(70, 20)];
    [copPath addQuadCurveToPoint:CGPointMake(50, 90) controlPoint:CGPointMake(100, 55)];
    [copPath addLineToPoint:CGPointMake(150, 90)];
    [copPath addQuadCurveToPoint:CGPointMake(130, 20) controlPoint:CGPointMake(100, 55)];
    [copPath closePath];
    CGContextAddPath(currentContext, copPath.CGPath);
    CGContextClip(currentContext);
    CGContextDrawLinearGradient(currentContext, gradientCop, CGPointMake(20, 55), CGPointMake(180, 55), 0);
    CGGradientRelease(gradientCop);
    CGContextRestoreGState(currentContext);
    
    CGContextSaveGState(currentContext);
    UIBezierPath * bedPath = [UIBezierPath bezierPath];
    [bedPath moveToPoint:CGPointMake(90, 90)];
    [bedPath addLineToPoint:CGPointMake(110, 90)];
    [bedPath addLineToPoint:CGPointMake(110, 190)];
    [bedPath addQuadCurveToPoint:CGPointMake(100, 210) controlPoint:CGPointMake(115, 195)];
    [bedPath addQuadCurveToPoint:CGPointMake(90, 190) controlPoint:CGPointMake(85, 195)];
    [bedPath closePath];
    CGContextAddPath(currentContext, bedPath.CGPath);
    CGContextClip(currentContext);
    CGContextDrawRadialGradient(currentContext, gradientBed, CGPointMake(100, 210), 0, CGPointMake(100, 90), 10, 0);
    CGGradientRelease(gradientBed);
    CGContextRestoreGState(currentContext);
    
    CGColorSpaceRelease(colorSpace);
    CGContextEndTransparencyLayer(currentContext);
}
效果圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末尿招,一起剝皮案震驚了整個濱河市矾柜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌就谜,老刑警劉巖怪蔑,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異丧荐,居然都是意外死亡缆瓣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門虹统,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弓坞,“玉大人,你說我怎么就攤上這事车荔《啥常” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵忧便,是天一觀的道長族吻。 經(jīng)常有香客問我,道長珠增,這世上最難降的妖魔是什么超歌? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮切平,結(jié)果婚禮上握础,老公的妹妹穿的比我還像新娘。我一直安慰自己悴品,他們只是感情好禀综,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布简烘。 她就那樣靜靜地躺著,像睡著了一般定枷。 火紅的嫁衣襯著肌膚如雪孤澎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天欠窒,我揣著相機(jī)與錄音覆旭,去河邊找鬼。 笑死岖妄,一個胖子當(dāng)著我的面吹牛型将,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荐虐,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼七兜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了福扬?” 一聲冷哼從身側(cè)響起腕铸,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铛碑,沒想到半個月后狠裹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡汽烦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年涛菠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撇吞。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡碗暗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出梢夯,到底是詐尸還是另有隱情,我是刑警寧澤晴圾,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布颂砸,位于F島的核電站,受9級特大地震影響死姚,放射性物質(zhì)發(fā)生泄漏人乓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一都毒、第九天 我趴在偏房一處隱蔽的房頂上張望色罚。 院中可真熱鬧,春花似錦账劲、人聲如沸戳护。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腌且。三九已至梗肝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間铺董,已是汗流浹背巫击。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留精续,地道東北人坝锰。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像重付,于是被迫代替她去往敵國和親顷级。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

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