從矩陣與空間操作的關(guān)系理解CSS3的transform

前不久開源了一個(gè)插件化移動(dòng)端運(yùn)動(dòng)效果庫 finger-mover,說到運(yùn)動(dòng)效果歼捐,不得不提到CSS3的 transform,也就是變換晨汹。這篇文章概括了在實(shí)現(xiàn) finger-mover 時(shí)對 transform 的理解與總結(jié)豹储。

注:文中的圖片多數(shù)截取自視頻:線性代數(shù)的本質(zhì),也強(qiáng)烈建議大家系統(tǒng)的觀看這套視頻淘这。另外如果文中有誤請不吝指教剥扣。

文章結(jié)構(gòu)如下:

* 矩陣
    * 概述
* 向量
    * 什么是向量
    * 基向量
* 線性變換
* 如何用數(shù)值描述線性變換巩剖?
* 回到 CSS 的 transform

我不知道大家所理解的矩陣是怎樣的,但我所理解的矩陣是:該陣法免疫法術(shù)攻擊且100%反傷對方隨機(jī)一個(gè)單位(回合制游戲)钠怯。

以上描述是在小學(xué)時(shí)代的理解佳魔,現(xiàn)在可能有所不同,慢慢說......

矩陣

概述

矩陣晦炊,是線性代數(shù)中涉及的內(nèi)容鞠鲜,線性代數(shù)在科學(xué)領(lǐng)域有很多應(yīng)用的場景,如下:

大部分同學(xué)在大學(xué)時(shí)期應(yīng)該都學(xué)過一本叫做線性代數(shù)的書断国,如果沒猜錯(cuò)的話贤姆,你們的老師在教學(xué)的時(shí)候大多都是概念性的灌輸,比如矩陣乘法如何運(yùn)算稳衬,加法如何運(yùn)算霞捡,大家只要記住就ok了,但是大部分同學(xué)都不理解薄疚,為什么矩陣的乘法要這樣算碧信?矩陣乘法的意義是什么?街夭,特別是我們搞計(jì)算機(jī)的砰碴,如果有做過 2D/3D 變換的同學(xué)一定聽說過矩陣,比如在前端的CSS中莱坎,使用 transform 做 2D/3D 的變換衣式,其中就應(yīng)用到了矩陣的知識(shí),這篇文章并不是一篇數(shù)學(xué)性質(zhì)的文章檐什,所以大家不要看了感覺一陣眩暈碴卧,這篇文章的目的在于:從矩陣與空間之間的關(guān)系講述:為什么矩陣可以應(yīng)用在空間操作(變換)∧苏或者用一句大白話:這玩意兒怎么就能讓div翻過來住册,轉(zhuǎn)過去,扭的他爹都不認(rèn)識(shí)他的瓮具。

先看一段 css 代碼:

/* 2D */
transform: matrix(1, 0, 0, 1, 0, 0);
/* 3D */
transform: matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);

上面兩行 css 代碼其實(shí)什么變換都不會(huì)做荧飞,因?yàn)槟鞘亲儞Q的默認(rèn)狀態(tài),即沒有變換名党。但是其中使用到了 matrix叹阔,翻譯成中文叫做:矩陣。如果有深入研究過 css 的同學(xué)對這兩行代碼也許不陌生传睹,但是大多數(shù)人在使用 transform 變換時(shí)很少直接使用 matrix 矩陣耳幢,除非你不想讓人看懂你在做些什么鳥變換...,所以更多的時(shí)候,我們會(huì)使用類似如下語法:

transform: translateX(100px) rotateZ(30deg);

如上代碼所示睛藻,一目了然启上,要做什么變換大家一看就知道了。但其實(shí)店印,這只是一個(gè)語法糖冈在,其底層依然使用的是 matrix

如果想要理解矩陣為何可以應(yīng)用到 2D/3D 變換按摘,那么只從數(shù)值水平的角度理解是不夠的包券,你需要從幾何的角度去理解矩陣,這存在著根本性的差異院峡。而這兴使,也就是本篇文章的真正意義。

不過照激,這需要我們先了解一些必要的基本概念发魄,這些概念至關(guān)重要,首先就是向量

向量

什么是向量

既然矩陣是線性代數(shù)的一部分俩垃,那么就不得不提到 向量励幼,因?yàn)橄蛄渴蔷€性代數(shù)最基礎(chǔ)、最根源的組成部分口柳,所以我們要先搞清楚苹粟,向量是什么?我說過跃闹,這篇文章不會(huì)很“數(shù)學(xué)”嵌削,所以大家不要被嚇到。用一句話描述向量是什么:

向量:空間中的箭頭

這個(gè)在大家的印象里應(yīng)該很好理解望艺,這個(gè)箭頭由兩個(gè)因素決定:方向長度苛秕,我們先把目光局限在二維空間下,如圖:

上圖中找默,在一個(gè)坐標(biāo)系中畫了四個(gè)不同長度和方向的箭頭艇劫,每個(gè)箭頭從原點(diǎn)發(fā)出,他們代表了二維空間中的四個(gè)向量惩激,在線性代數(shù)中店煞,向量通常以原點(diǎn)作為起點(diǎn)。

如果你已經(jīng)理解了“向量是空間中的箭頭”這種觀點(diǎn)风钻,下面我們再進(jìn)一步顷蟀,我們重新用一句話來描述向量:

向量:是有序的數(shù)字列表

假設(shè)大家對坐標(biāo)系的概念都有所了解,我們還是把目光局限在二維空間骡技,在坐標(biāo)系中任意選取單位長度衩椒,這樣我們就能夠使用一個(gè)一個(gè)的刻度來標(biāo)刻這個(gè)坐標(biāo)系,選取特定的方向?yàn)閤/y軸的正方向,那么不難看出毛萌,每一個(gè)向量,都可以用唯一的一個(gè)坐標(biāo)來表示喝滞,同樣的阁将,坐標(biāo)系中的每一個(gè)坐標(biāo)都對應(yīng)著一個(gè)唯一的箭頭(向量),如下圖:

在坐標(biāo)系中右遭,由于坐標(biāo)通常用來標(biāo)示一個(gè)點(diǎn)做盅,如 P(2, 8) 表示點(diǎn) P 的坐標(biāo)為 (2, 8),為了區(qū)分點(diǎn)和向量窘哈,在表示向量時(shí)吹榴,我們通常把坐標(biāo)豎著寫,然后用一對兒中括號(hào)來描述滚婉,如上圖中的:

在三維空間也是一樣的道理图筹,如下圖,我就不做重復(fù)的解釋让腹,唯一不同的是远剩,每一個(gè)向量由 x/y/z 三個(gè)數(shù)字組成的坐標(biāo)來表示:

對于向量,你只需要知道它是“空間中的箭頭”或者“有序的數(shù)字列表”這就足夠了骇窍,怎么樣瓜晤?不難理解吧,我們繼續(xù)往下看腹纳,在坐標(biāo)系中存在一種特殊的向量痢掠,我們稱之為 基向量

基向量

基向量嘲恍,也叫單位向量足画,是單位長度為1的向量,如下圖中:i帽j帽 就是這個(gè)二維坐標(biāo)系的基向量:

對于向量蛔钙,我們就先介紹到這里锌云,這已經(jīng)足夠了。除了向量吁脱,還有一個(gè)概念需要大家了解桑涎,即線性變換。

線性變換

“變換”本質(zhì)上是“函數(shù)”的一種花哨的叫法兼贡,玩編程的都知道函數(shù)攻冷,與在數(shù)學(xué)中的概念類似,函數(shù)接收輸入的內(nèi)容遍希,并輸出對應(yīng)的結(jié)果等曼,如圖:

變換也是同樣的道理,只不過接收向量作為輸入,并輸出變換后的向量:

既然 “變換” 與 “函數(shù)” 本質(zhì)相同禁谦,那么為什么叫變換而不叫函數(shù)呢胁黑?這實(shí)際上就暗示了我們,你可以把這個(gè)輸入輸出的過程州泊,看做一個(gè)向量從初始狀態(tài)到最終狀態(tài)的一個(gè)變化過程,如下圖:

現(xiàn)在遥皂,我們把情況宏觀一下,目前只討論一個(gè)向量的變換爬凑,我們知道潘靖,二維空間的一整個(gè)平面,可以看做是由無數(shù)個(gè)向量組成(或者無數(shù)個(gè)點(diǎn)組成,因?yàn)槊恳粋€(gè)點(diǎn)唯一標(biāo)識(shí)一個(gè)向量棒假,所以這里說平面由無數(shù)個(gè)向量組成),假如這無數(shù)個(gè)向量同時(shí)做相同的變換,那其實(shí)就可以看做是平面的變換,如下圖:

變換前:

變換后:

不過柠偶,并非所有變換都叫做線性變換情妖,線性變換必須要滿足下面兩個(gè)條件:

  • 1、直線在變換后仍然為直線诱担,不能有所彎曲
  • 2毡证、原點(diǎn)不能移動(dòng)

如下變換,就不是一個(gè)線性變換蔫仙,因?yàn)橹本€變成了曲線:

如何用數(shù)值描述線性變換料睛?

在上一小節(jié)中我們知道,空間的變換也可以說是向量的變換摇邦,而向量在空間中恤煞,可以用一組有序的數(shù)字列表來表示(即向量的坐標(biāo)),所以向量變換前后施籍,必然會(huì)引起“有序數(shù)字列表的變換”居扒,那么我們是否可以用數(shù)字去描述變換呢?

之前在向量一節(jié)中丑慎,我們了解過基向量喜喂,單位長度為1,其實(shí)空間中的任意一個(gè)向量我們都可以看做是:基向量變換后的和向量竿裂,如下圖:

向量 <b>v</b> 的坐標(biāo)是

玉吁,如果我們把 3-2 看做兩個(gè)標(biāo)量,也就是純數(shù)字腻异,那么向量 <b>v</b> 可以看做是基向量被標(biāo)量縮放后相加得到的和向量: <b>v</b> = 3<b>i</b> + (-2<b>j</b>)

了解了這些进副,我們現(xiàn)在就通過一個(gè)例子,來認(rèn)識(shí)一個(gè)至關(guān)重要的事實(shí)捂掰,假如我們有向量 <b>v</b> = -1<b>i</b> + 2<b>j</b>敢会,如下圖:

此時(shí),基向量 <b>i</b> 的坐標(biāo)是 (1, 0)【注意:為了方便这嚣,這里就用圓括號(hào)代表向量的坐標(biāo)鸥昏,下同】,基向量 <b>j</b> 的坐標(biāo)是 (0, 1)姐帚,假設(shè)經(jīng)過了某些變換之后吏垮,基向量 <b>i</b> 的坐標(biāo)變?yōu)?(1, -2)罐旗,基向量 <b>j</b> 的坐標(biāo)變?yōu)?(3膳汪, 0),如下圖:

那么變換后的向量 <b>v</b> 依然滿足 <b>v</b> = -1<b>i</b> + 2<b>j</b>九秀,如下:

以上例子所描述的事實(shí)遗嗽,實(shí)際上是線性變換的性質(zhì)的推論,該性質(zhì)可以從幾何角度表述為:線性變換后的網(wǎng)格平行且等距鼓蜒。

既然線性變換前后都滿足該線性關(guān)系:<b>v</b> = -1<b>i</b> + 2<b>j</b>

那么很容易根據(jù)變換后 i帽j帽 的坐標(biāo)推算出變換后 <b>v</b> 的坐標(biāo):

也就是 (5, 2)痹换,即:

那么我們是否可以認(rèn)為征字,給定任意一個(gè)向量,其坐標(biāo) (x, y)娇豫,我們可以通過變換后的基向量的坐標(biāo)推斷出該向量變換后的坐標(biāo)呢匙姜?答案是肯定的,假如基向量變換后的坐標(biāo) i帽j帽 如下圖:

那么任意向量 (x, y) 在經(jīng)過變換后的坐標(biāo)計(jì)算如下:

這告訴我們另外一個(gè)事實(shí)冯痢,<b>二維空間的線性變換僅由四個(gè)數(shù)字完全確定</b>氮昧,這四個(gè)數(shù)字就是基向量 <b>i</b> 變換后 <b>i帽</b> 的坐標(biāo),以及基向量 <b>j</b> 變換后 <b>j帽</b> 的坐標(biāo)浦楣,如下圖:

是不是很酷袖肥?只需要四個(gè)數(shù)字,我們就確定了二維空間的一個(gè)變換振劳。通常昭伸,我們把這四個(gè)數(shù)字放到一個(gè) 2 x 2 的格子中,我們稱之為 2 x 2 矩陣:

現(xiàn)在澎迎,當(dāng)你再看到 2 x 2 矩陣的時(shí)候,你的第一幾何直觀反映應(yīng)該是:它描述了一個(gè)二維空間的變換选调。

我們把情況一般化夹供,如下圖:

我們有一個(gè) 2 x 2 的矩陣 [a, c] [b, d],其中 [a, c] 是基向量 <b>i</b> 變換后的坐標(biāo)仁堪,[b, d] 是基向量 <b>j</b> 變換后的坐標(biāo)哮洽,那么根據(jù)這個(gè)變換,以及線性變換的性質(zhì)弦聂,我們可以推斷出任意向量 [x, y] 變換后的坐標(biāo):

<p class="tip">
實(shí)際上鸟辅,這就是數(shù)學(xué)家之所以這樣定義 矩陣的向量乘法 的原因。
</p>

到了這里莺葫,讓我們整理一下思路匪凉,首先,對于一個(gè) 2 x 2 的矩陣捺檬,你的直觀幾何感受應(yīng)該是再层,第一列的兩個(gè)數(shù)是對基向量 <b>i</b> 的變換,第二列的兩個(gè)數(shù)是對基向量 <b>j</b> 的變換堡纬,這四個(gè)數(shù)字組成的 2 x 2 的矩陣聂受,描述了一個(gè)對空間的線性變換,我們可以根據(jù)這個(gè)變換推斷出任意一點(diǎn)(或者任意向量)變換后的坐標(biāo)烤镐。

其實(shí)我么你還可以換一個(gè)角度考慮蛋济,我們就單純的把 2 x 2 矩陣叫做變換,那么向量與矩陣的乘積炮叶,就要可以看做是該向量應(yīng)用了這個(gè)變換碗旅。其實(shí)渡处,這就是矩陣向量乘法的幾何意義。

回到 CSS 的 transform

說了一大堆扛芽,是時(shí)候回到 CSStransform骂蓖,我們來看一下2D變換下 transform 屬性的 matrix 寫法:

transform: matrix(a, b, c, d, e, f);

在文章開始,我們知道各個(gè)參數(shù)默認(rèn)值如下:

transform: matrix(1, 0, 0, 1, 0, 0);

有的同學(xué)可能會(huì)問:說好的 2 x 2 矩陣也就是四個(gè)數(shù)字就能確定一個(gè)二維空間變換川尖,你這里明明有6個(gè)數(shù)啊登下,其實(shí),transform 2D變換是一個(gè) 3 * 3 的矩陣叮喳,為什么是這樣被芳?因?yàn)椋?em>位移(translate),前面我們說過馍悟,線性變換要滿足其中一個(gè)特點(diǎn):原點(diǎn)不能移動(dòng)畔濒,但是位移卻使原點(diǎn)發(fā)生了移動(dòng),所以 2 x 2 矩陣滿足不了需求锣咒,只能再加一列侵状,也就是 3 x 3 的矩陣。

matrix 中的 a b c d e f 放到一個(gè) 3 x 3 的矩陣中應(yīng)該是這樣的:

其實(shí)毅整,在沒有位移(translate)的情況下他嚷,[a, b] [c, d] 四個(gè)數(shù)字組成的 2 x 2 矩陣是完全可以描述2D變換的朗伶,現(xiàn)在我們只看由 [a, b] [c, d] 組成的 2 x 2 矩陣:

我們把 a b c d 四個(gè)數(shù)字使用默認(rèn)值替換一下峰锁,即:a = 1回还,b = 0c = 0戏蔑,d = 1蹋凝,如下:

通過之前的介紹,我們在看到這個(gè)矩陣的時(shí)候总棵,應(yīng)該知道鳍寂,第一列的坐標(biāo) (1, 0) 應(yīng)該是基向量 <b>i</b> 變換后的坐標(biāo),但是基向量 <b>i</b> 在變換前的坐標(biāo)就是 (1, 0)彻舰,也就是說沒有任何變換伐割,同理,基向量 <b>j</b> 也沒有任何變換刃唤,所以說隔心,這就是 a b c d 默認(rèn)值設(shè)定為下面代碼所示的值的原因:

transform: matrix(a, b, c, d, e, f);
// a b c d 默認(rèn)值為 1 0 0 1
transform: matrix(1, 0, 0, 1, e, f);

那么大家想想一下,我們把 a 的值從 1 變?yōu)?2 會(huì)發(fā)生什么尚胞?如果把 a 的值從 1 變?yōu)?2 那么矩陣如下:

也就是說硬霍,基向量 <b>i</b> 的坐標(biāo)從 (1, 0) 變成了 (2, 0),這是在干什么笼裳?是不是基向量 <b>i</b> 被放大為了原來的二倍唯卖?舉一個(gè)通俗的例子:原本單位長度1代表20px粱玲,被放大后單位長度1則代表40px。同樣的拜轨,當(dāng)我們把 a 的值從 1 變?yōu)?0.5 則意味著把基向量 <b>i</b> 縮小為原來的一半抽减。事實(shí)上:在 transform: matrix() 中,修改 a 的值橄碾,就是在改變 x 軸方向的縮放比例:

transform: matrix(2, 0, 0, 1, 0, 0);
/* 等價(jià)于 */
transform: scaleX(2);

相信大家已經(jīng)知道了卵沉,修改 d 的值,就是改變 y 軸的縮放比例:

transform: matrix(1, 0, 0, 4, 0, 0);
/* 等價(jià)于 */
transform: scaleY(4);

那么旋轉(zhuǎn)要如何修改 matrix 中的值呢法牲?其實(shí)史汗,想要知道如何修改 a b c d 的值,只需要知道拒垃,旋轉(zhuǎn)后基向量 <b>i</b> 和 <b>j</b> 的坐標(biāo)就可以了停撞,將旋轉(zhuǎn)后的坐標(biāo)對號(hào)填入就可以得到變換矩陣,下面悼瓮,我們就來看看如何確定旋轉(zhuǎn)后基向量 <b>i</b> 和 <b>j</b> 的坐標(biāo)戈毒。

我們知道,在 web 開發(fā)中的坐標(biāo)系和數(shù)學(xué)中的坐標(biāo)系在正方向的選取上不太一致横堡,在大家所熟悉的坐標(biāo)系中副硅,正方向的選取如下:

而在 web 開發(fā)中,坐標(biāo)系的正方向選取是這樣的:

假設(shè)我們將其順時(shí)針旋轉(zhuǎn) 45 度翅萤,如下圖:

假設(shè),上圖中我們旋轉(zhuǎn)的是單位向量腊满,那么旋轉(zhuǎn)后單位向量 <b>i</b> 的坐標(biāo)應(yīng)該是 (cosθ, sinθ)套么,單位向量 <b>j</b> 的坐標(biāo)應(yīng)該是 (-sinθ, cosθ),所以如果用矩陣表示的話碳蛋,應(yīng)該是這樣的:

如果寫到 matrix 里胚泌,自然就是下面這個(gè)樣子:

transform: matrix(cosθ, sinθ, -sinθ, cosθ, 0, 0)

所以,如果我們要順時(shí)針旋轉(zhuǎn) 45 度肃弟,下面兩種寫法是等價(jià)的:

/*
 * Math.cos(Math.PI / 180 * 45) = 0.707106
 * Math.sin(Math.PI / 180 * 45) = 0.707106
 */
transform: matrix(0.707106, 0.707106, -0.707106, 0.707106, 0, 0)

/* 等價(jià)于 */
transform: rotate(45deg);

通過上面縮放和旋轉(zhuǎn)的例子玷室,我們已經(jīng)知道了,2 x 2 的矩陣確實(shí)能夠描述二維空間的變換笤受,這也就是矩陣能夠操作空間的原因穷缤。在 transform 中,除了縮放(scale)箩兽、旋轉(zhuǎn)(rotate) 還有傾斜(skew)津肛,對于傾斜,類似于我們尋找旋轉(zhuǎn)后基向量的坐標(biāo)一樣汗贫,你只需要根據(jù)傾斜所定義的變換規(guī)則身坐,找到基向量變換后的坐標(biāo)就可以了秸脱,實(shí)際上傾斜對應(yīng)如下規(guī)則:

transform: matrix(1, tan(θy), tan(θx), 1, 0, 0);

大家自己拿只筆在紙上畫一畫應(yīng)該就能搞清楚傾斜在做什么樣子的變換。

無論 縮放(scale)部蛇、旋轉(zhuǎn)(rotate) 還是傾斜(skew)摊唇,他們都不會(huì)是原點(diǎn)發(fā)生改變,所以使用 a b c d 四個(gè)數(shù)字組成的矩陣完全可以描述涯鲁,但是不要忘了巷查,我們還有一個(gè) 位移(translate),這時(shí)撮竿,就不得不提到 e f 了吮便,我想我不說大家也都知道了,e f 分別代表了 x y 方向的位移幢踏,事實(shí)也如大家所想:

transform: matrix(1, 0, 0, 1, 100, 200)

/* 等價(jià)于 */
transform: translateX(100px) translateY(200px);

至此髓需,transform 使用 3 x 3 矩陣:

來描述二維空間變換的方式,以及是如何做到的我們就算講完了房蝉。

除了2D變換僚匆,還有3D變換,在 transform 中搭幻,使用 4 x 4 的矩陣描述3D變換咧擂,但實(shí)際上,三維空間的線性變換只需要一個(gè) 3 x 3 的矩陣就可以描述了檀蹋,那么為什么搞了一個(gè) 4 x 4矩陣呢松申?實(shí)際上這和我們在將二維空間的變換使用 3 x 3 矩陣的道理是一樣的,那就是位移俯逾。

我們來看一下3D變換的 matrix 默認(rèn)值:

transform: matrix(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);
transform: matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);

這十六個(gè)數(shù)字就是 4 x 4 矩陣的 16 個(gè)數(shù)值:

如果換成對應(yīng)數(shù)字贸桶,是這樣的:

類似于我們講解 2D 變換一樣,其中由

組成的 3 x 3 矩陣用來描述空間的 3D 線性變換桌肴,如:rotateX rotateY scaleZ 等等皇筛,注意:rotateZ 是 2D 變換哦。

m n o 則分別用來描述位移:translateX translateY translateZ坠七。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末水醋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子彪置,更是在濱河造成了極大的恐慌拄踪,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拳魁,死亡現(xiàn)場離奇詭異宫蛆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門耀盗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來想虎,“玉大人,你說我怎么就攤上這事叛拷∩喑” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵忿薇,是天一觀的道長裙椭。 經(jīng)常有香客問我,道長署浩,這世上最難降的妖魔是什么揉燃? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮筋栋,結(jié)果婚禮上炊汤,老公的妹妹穿的比我還像新娘。我一直安慰自己弊攘,他們只是感情好抢腐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著襟交,像睡著了一般迈倍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捣域,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天啼染,我揣著相機(jī)與錄音,去河邊找鬼焕梅。 笑死提完,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丘侠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼逐样,長吁一口氣:“原來是場噩夢啊……” “哼蜗字!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起脂新,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤挪捕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后争便,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體级零,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奏纪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鉴嗤。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖序调,靈堂內(nèi)的尸體忽然破棺而出醉锅,到底是詐尸還是另有隱情,我是刑警寧澤发绢,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布硬耍,位于F島的核電站,受9級特大地震影響边酒,放射性物質(zhì)發(fā)生泄漏经柴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一墩朦、第九天 我趴在偏房一處隱蔽的房頂上張望坯认。 院中可真熱鬧,春花似錦介杆、人聲如沸鹃操。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荆隘。三九已至,卻和暖如春赴背,著一層夾襖步出監(jiān)牢的瞬間椰拒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工凰荚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留燃观,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓便瑟,卻偏偏與公主長得像缆毁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子到涂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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