精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

現代 CSS 高階技巧,像 Canvas 一樣自由繪圖構建樣式!

開發 前端
在今天,是否 CSS 還存在著更進一步的功能,能夠實現更為強大的效果?沒錯,是可以的,這也就引出了今天的主角,CSS Houdini 之 CSS Paint API。

在上一篇文章中 -- 現代 CSS 之高階圖片漸隱消失術[1],我們借助了 CSS @Property 及 CSS Mask 屬性,成功的實現了這樣一種圖片漸變消失的效果:

圖片

CodePen Demo -- 基于 @property 和 mask 的文本漸隱消失術[2]。

但是,這個效果的缺陷也非常明顯,雖然借助了 SCSS 簡化了非常多的代碼,但是,如果我們查看編譯后的 CSS 文件,會發現,在利用 SCSS 只有 80 的代碼的情況下,編譯后的 CSS 文件行數高達 2400+ 行,實在是太夸張了。

圖片

究其原因在于,我們利用原生的 CSS 去控制 400 個小塊的過渡動畫,控制了 400 個 CSS 變量!代碼量因而變得如此之大。

CSS Houdini 之 CSS Paint API

那么,如何有效的降低代碼量呢?

又或者說,在今天,是否 CSS 還存在著更進一步的功能,能夠實現更為強大的效果?

沒錯,是可以的,這也就引出了今天的主角,CSS Houdini 之 CSS Paint API。

首先,什么是 CSS Houdini?

Houdini 是一組底層 API,它們公開了 CSS 引擎的各個部分,從而使開發人員能夠通過加入瀏覽器渲染引擎的樣式和布局過程來擴展 CSS。Houdini 是一組 API,它們使開發人員可以直接訪問 CSS 對象模型[3] (CSSOM),使開發人員可以編寫瀏覽器可以解析為 CSS 的代碼,從而創建新的 CSS 功能,而無需等待它們在瀏覽器中本地實現。

而 CSS Paint API 則是 W3C 規范中之一,目前的版本是 CSS Painting API Level 1[4]。它也被稱為 CSS Custom Paint 或者 Houdini's Paint Worklet。

簡單來說人話,CSS Paint API 的優缺點都很明顯。

CSS Paint API 的優點:

  1. 實現更為強大的 CSS 功能,甚至是很多 CSS 原本不支持的功能
  2. 將這些自定義的功能,很好的封裝起來,當初一個屬性快速復用

當然,優點看著很美好,缺點也很明顯,CSS Paint API 的缺點:

  1. 需要寫一定量的 JavaScript 代碼,有一定的上手成本
  2. 現階段兼容的問題

小試牛刀 registerPaint

CSS Houdini[5] 的特性就是 Worklet (en-US)[6]。在它的幫助下,你可以通過引入一行 JavaScript 代碼來引入配置化的組件,從而創建模塊式的 CSS。不依賴任何前置處理器、后置處理器或者 JavaScript 框架。

廢話不多說,我們直接來看一個最簡單的例子。

<div style="--color: red"></div>
<div style="--color: blue"></div>
<div style="--color: yellow"></div>

<script>
if (CSS.paintWorklet) {
CSS.paintWorklet.addModule('/CSSHoudini.js');
}
</script>
div {
margin: auto;
width: 100px;
height: 100px;
background: paint(drawBg);
}
// 這個文件的名字為 CSSHoudini.js
// 對應上面 HTML 代碼中的 CSS.paintWorklet.addModule('/CSSHoudini.js')
registerPaint('drawBg', class {

static get inputProperties() {return ['--color']}

paint(ctx, size, properties) {
const c = properties.get('--color');

ctx.fillStyle = c;
ctx.fillRect(0, 0, size.width, size.height);
}
});

先看看最終的結果:

圖片

看似有點點復雜,其實非常好理解。仔細看我們的 CSS 代碼,在 background 賦值的過程中,沒有直接寫具體顏色,而是借助了一個自定義了 CSS Houdini 函數,實現了一個名為 drawBg 的方法。從而實現的給 Div 上色。

registerPaint 是以 worker 的形式工作,具體有幾個步驟:

  1. 建立一個 CSSHoudini.js,比如我們想用 CSS Painting API,先在這個 JS 文件中注冊這個模塊 registerPaint('drawBg', class),這個 class 是一個類,下面會具體講到。
  2. 我們需要在 HTML 中引入 CSS.paintWorklet.addModule('CSSHoudini.js'),當然CSSHoudini.js 只是一個名字,沒有特定的要求,叫什么都可以。
  3. 這樣,我們就成功注冊了一個名為drawBg 的自定義 Houdini 方法,現在,可以用它來擴展 CSS 的功能。
  4. 在 CSS 中使用,就像代碼中示意的那樣background: paint(drawBg)。
  5. 接下來,就是具體的 registerPaint 實現的 drawBg 的內部的代碼。

上面的步驟搞明白后,核心的邏輯,都在我們自定義的 drawBg 這個方法后面定義的 class 里面。CSS Painting API 非常類似于 Canvas,這里面的核心邏輯就是:

  1. 可以通過static get inputProperties() {} 拿到各種從 CSS 傳遞進來的 CSS 變量。
  2. 通過一套類似 Canvas 的 API 完成整個圖片的繪制工作。

而我們上面 DEMO 做的事情也是如此,獲取到 CSS 傳遞進來的 CSS 變量的值。然后,通過 ctx.fillStyle 和 ctx.fillRect 完成整個背景色的繪制。

使用 registerPaint 實現自定義背景圖案

OK,了解了上面最簡單的 DEMO 之后,接下來我們嘗試稍微進階一點點。利用 registerPaint 實現一個 circleBgSet 的自定義 CSS 方法,實現類似于這樣一個背景圖案:

圖片

?CodePen Demo -- CSS Hudini Example - Background Circle[7]。

首先,我們還是要在 HTML 中,利用 CSS.paintWorklet.addModule('') 注冊引入我們的 JavaScript 文件。

<div style=""></div>

<script>
if (CSS.paintWorklet) {
CSS.paintWorklet.addModule('/CSSHoudini.js'');
}
</script>

其次,在 CSS 中,我們只需要在調用 background 屬性的時候,傳入我們即將要實現的方法:

div {
width: 100vw;
height: 1000vh;
background: paint(circleBgSet);
--gap: 3;
--color: #f1521f;
--size: 64;
}

可以看到,核心在于 background: paint(circleBgSet),我們將繪制背景的工作,交給接下來我們要實現的 circleBgSet 方法。同時,我們定義了 3 個 CSS 變量,它們的作用分別是:

  1. --gap:表示圓點背景的間隙。
  2. -color:表示圓點的顏色。
  3. --size:表示圓點的最大尺寸。

好了,接下來,只需要在 JavaScript 文件中,利用 CSS Painting API 實現 circleBgSet 方法即可。

來看看完整的 JavaScript 代碼:

// 這個文件的名字為 CSSHoudini.js
registerPaint(
"circleBgSet",
class {
static get inputProperties() {
return [
"--gap",
"--color",
"--size"
];
}
paint(ctx, size, properties) {
const gap = properties.get("--gap");
const color = properties.get("--color");
const eachSize = properties.get("--size");
const halfSize = eachSize / 2;
const n = size.width / eachSize;
const m = size.height / eachSize;
ctx.fillStyle = color;
for (var i = 0; i < n + 1; i++) {
for (var j = 0; j < m + 1; j++) {
let x = i * eachSize + ( j % 2 === 0 ? halfSize : 0);
let y = j * eachSize / gap;
let radius = i * 0.85;
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.fill();
}
}
}
}
);

代碼其實也不多,并且核心的代碼非常好理解。這里,我們再簡單的解釋下:

  1. static get inputProperties() {},我們在 CSS 代碼中定義了一些 CSS 變量,而需要取到這些變量的話,需要利用到這個方法。它使我們能夠訪問所有 CSS 自定義屬性和它們設置的值。
  2. paint(ctx, size, properties) {} 核心繪畫的方法,其中 ctx 類似于 Canvas 2D 畫布的 ctx 上下文對象,size 表示 PaintSize 對象,可以拿到對于元素的高寬值,而 properties 則是表示 StylePropertyMapReadOnly 對象,可以拿到 CSS 變量相關的信息

圖片

  1. 最終,仔細看看我們的paint() 方法,核心做的就是拿到 CSS 變量后,基于雙重循環,把我們要的圖案繪制在畫布上。這里核心就是調用了下述 4 個方法,對 Canvas 了解的同學不難發現,這里的 API 和 Canvas 是一模一樣的。
  • ctx.fillStyle = color
  • ctx.beginPath()
  • ctx.arc(x, y, radius, 0, 2 * Math.PI)
  • ctx.fill()

這里,其實 CSS Houdini 的畫布 API 是 Canvas API 的是一樣的,具體存在這樣一些映射,我們在官方規范 CSS Painting API Level 1 - The 2D rendering context[8] 可以查到:

圖片

還記得我們上面傳入了 3 個 CSS 變量嗎?這里我們只需要簡單改變上面的 3 個 變量,就可以得到不一樣的圖形。讓我們試一試:

div {
width: 100vw;
height: 1000vh;
background: paint(circleBgSet);
// --gap: 3;
// --color: #f1521f;
// --size: 64;
--gap: 6;
--color: #ffcc00;
--size: 75;
}

圖片

又或者:

div {
width: 100vw;
height: 1000vh;
background: paint(circleBgSet);
// --gap: 3;
// --color: #f1521f;
// --size: 64;
--gap: 4;
--color: #0bff00;
--size: 50;
}

圖片

利用 registerPaint 實現自定義 mask

有了上面的鋪墊,下面我們開始實現我們今天的主題,利用 registerPaint 自定義方法還原實現這個效果,簡化 CSS 代碼量:

圖片

自定義的 paint 方法,不但可以用于 background,你想得到的地方,其實都可以。

能力越大,責任越大!在 Houdini 的幫助下你能夠在 CSS 中實現你自己的布局、柵格、或者區域特性,但是這么做并不是最佳實踐。CSS 工作組已經做了許多努力來確保 CSS 中的每一項特性都能正常運行,覆蓋各種邊界情況,同時考慮到了安全、隱私,以及可用性方面的表現。如果你要深入使用 Houdini,確保你也把以上這些事項考慮在內!并且先從小處開始,再把你的自定義 Houdini 推向一個富有雄心的項目。

因此,這里,我們利用 CSS Houdini 的 registerPaint 實現自定義的 mask 屬性繪制。

首先,還是一樣,HTML 中需要引入一下定義了 registerPaint 方法的 JavaScript 文件:

<div></div>

<script>
if (CSS.paintWorklet) {
CSS.paintWorklet.addModule('/CSSHoudini.js');
}
</script>

首先,我們會實現一張簡單的圖片:


div {
width: 300px;
height: 300px;
background: url(https://tvax4.sinaimg.cn/large/6f8a2832gy1g8npte0txnj21jk13a4qr.jpg);
}

效果如下:

圖片

當然,我們的目標是利用 registerPaint 實現自定義 mask,那么需要添加一些 CSS 代碼:


div {
width: 300px;
height: 300px;
background: url(https://tvax4.sinaimg.cn/large/6f8a2832gy1g8npte0txnj21jk13a4qr.jpg);
mask: paint(maskSet);
--size-m: 10;
--size-n: 10;
}

這里,我們 mask: paint(maskSet) 表示使用我們自定義的 maskSet 方法,并且,我們引入了兩個 CSS 自定義變量 --size-m 和 --size-n,表示我們即將要用 mask 屬性分隔圖片的行列數。

接下來,就是具體實現新的自定義 mask 方法。當然,這里我們只是重新實現一個 mask,而 mask 屬性本身的特性,透明的地方背后的內容將會透明這個特性是不會改變的。

JavaScript 代碼:

// 這個文件的名字為 CSSHoudini.js
registerPaint(
"maskSet",
class {
static get inputProperties() {
return ["--size-n", "--size-m"];
}

paint(ctx, size, properties) {
const n = properties.get("--size-n");
const m = properties.get("--size-m");
const width = size.width / n;
const height = size.height / m;

for (var i = 0; i < n; i++) {
for (var j = 0; j < m; j++) {
ctx.fillStyle = "rgba(0,0,0," + Math.random() + ")";
ctx.fillRect(i * width, j * height, width, height);
}
}
}
}
);

這一段代碼非常好理解,我們做的事情就是拿到兩個 CSS 自定義變量 --size-n 和 --size-m 后,通過一個雙循環,依次繪制正方形填滿整個 DIV 區域,每個小正方形的顏色為帶隨機透明度的黑色。

記住,mask 的核心在于,透過顏色的透明度來隱藏一個元素的部分或者全部可見區域。因此,整個圖片將變成這樣:

圖片

當然,我們這個自定義 mask 方法也是可以用于 background 的,如果我們把這個方法作用于 backgorund,你會更好理解一點。

div {
width: 300px;
height: 300px;
background: paint(maskSet);
// mask: paint(maskSet);
--size-m: 10;
--size-n: 10;
}

實際的圖片效果是這樣:

圖片

好,回歸正題,我們繼續。我們最終的效果還是要動畫效果,Hover 的時候讓圖片方塊化消失,肯定還是要和 CSS @property 自定義變量發生關聯的,我們簡單改造下代碼,加入一個 CSS @property 自定義變量。

@property --transition-time {
syntax: '<number>';
inherits: false;
initial-value: 1;
}

div {
width: 300px;
height: 300px;
background: url(https://tvax4.sinaimg.cn/large/6f8a2832gy1g8npte0txnj21jk13a4qr.jpg);
mask: paint(maskSet);
--size-m: 10;
--size-n: 10;
--transition-time: 1;
transition: --transition-time 1s linear;
}

div:hover {
--transition-time: 0;
}

這里,我們引入了 --transition-time 這個變量。接下來,讓他在 maskSet 函數中,發揮作用:

registerPaint(
"maskSet",
class {
static get inputProperties() {
return ["--size-n", "--size-m", "--transition-time"];
}

paint(ctx, size, properties) {
const n = properties.get("--size-n");
const m = properties.get("--size-m");
const t = properties.get("--transition-time");
const width = size.width / n;
const height = size.height / m;

for (var i = 0; i < n; i++) {
for (var j = 0; j < m; j++) {
ctx.fillStyle = "rgba(0,0,0," + (t * (Math.random() + 1)) + ")";
ctx.fillRect(i * width, j * height, width, height);
}
}
}
}
);

這里,與上面唯一的變化在于這一行代碼:ctx.fillStyle = "rgba(0,0,0," + (t * (Math.random() + 1)) + ")"。

對于每一個小格子的 mask,我們讓他的顏色值的透明度設置為 (t * (Math.random() + 1)):

  1. 其中 t 就是--transition-time 這個變量,記住,在 hover 的過程中,它的值會逐漸從 1 衰減至 0
  2. (Math.random() + 1) 表示先生成一個 0 ~ 1 的隨機數,再讓這個隨機數加 1,加 1 的目的是讓整個值必然大于 1,處于 1 ~ 2 的范圍
  3. 由于一開始--transition-time 的值一開始是 1,所以乘以 (Math.random() + 1) 的值也必然大于 1,而最終在過渡過程中 --transition-time 會逐漸變為 0, 整個表達式的值也最終會歸于 0
  4. 由于上述 (3)的值控制的是每一個 mask 小格子的透明度,也就是說每個格子的透明度都會從一個介于 1 ~ 2 的值逐漸變成 0,借助這個過程,我們完成了整個漸隱的動畫

看看最終的效果:

圖片

?CodePen Demo -- CSS Hudini Example[9]。

是的,細心的同學肯定會發現,文章一開頭給的 DEMO 是切分了 400 份 mask 的,而我們上面實現的效果,只用了 100 個 mask。

這個非常好解決,我們不是傳入了 --size-n? 和 --size-m 兩個變量么?只需要修改這兩個值,就可以實現任意格子的 Hover 漸隱效果啦。還是上面的代碼,簡單修改 CSS 變量的值:

div:nth-child(1) {
--size-m: 4;
--size-n: 4;
}
div:nth-child(2) {
--size-m: 6;
--size-n: 6;
}
div:nth-child(3) {
--size-m: 10;
--size-n: 10;
}
div:nth-child(4) {
--size-m: 15;
--size-n: 15;
}

結果如下:

圖片

?CodePen Demo -- CSS Hudini Example[10]。

到這里,還有一個小問題,可以看到,在消失的過程中,整個效果非常的閃爍!每個格子其實閃爍了很多次。

這是由于在過渡的過程中,ctx.fillStyle = "rgba(0,0,0," + (t * (Math.random() + 1)) + ")"? 內的 Math.random() 每一幀都會重新被調用并且生成全新的隨機值,因此整個動畫過程一直在瘋狂閃爍。

如何解決這個問題?在這篇文章中,我找到了一種利用偽隨機,生成穩定隨機函數的方法:Exploring the CSS Paint API: Image Fragmentation Effect[11]。

啥意思呢?就是我們希望每次生成的隨機數都是都是一致的。其 JavaScript 代碼如下:

const mask = 0xffffffff;
const seed = 30; /* update this to change the generated sequence */
let m_w = (123456789 + seed) & mask;
let m_z = (987654321 - seed) & mask;

let random = function() {
m_z = (36969 * (m_z & 65535) + (m_z >>> 16)) & mask;
m_w = (18000 * (m_w & 65535) + (m_w >>> 16)) & mask;
var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
result /= 4294967296;
return result;
}

我們利用上述實現的隨機函數 random() 替換掉我們代碼原本的 Math.random(),并且,mask 小格子的 ctx.fillStyle 函數,也稍加變化,避免每一個 mask 矩形小格子的漸隱淡出效果同時發生。

修改后的完整 JavaScript 代碼如下:

registerPaint(
"maskSet",
class {
static get inputProperties() {
return ["--size-n", "--size-m", "--transition-time"];
}

paint(ctx, size, properties) {
const n = properties.get("--size-n");
const m = properties.get("--size-m");
const t = properties.get("--transition-time");
const width = size.width / n;
const height = size.height / m;
const l = 10;

const mask = 0xffffffff;
const seed = 100; /* update this to change the generated sequence */
let m_w = (123456789 + seed) & mask;
let m_z = (987654321 - seed) & mask;

let random = function () {
m_z = (36969 * (m_z & 65535) + (m_z >>> 16)) & mask;
m_w = (18000 * (m_w & 65535) + (m_w >>> 16)) & mask;
var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
result /= 4294967296;
return result;
};

for (var i = 0; i < n; i++) {
for (var j = 0; j < m; j++) {
ctx.fillStyle = 'rgba(0,0,0,'+((random()*(l-1) + 1) - (1-t)*l)+')';
ctx.fillRect(i * width, j * height, width, height);
}
}
}
}
);

還是上述的 DEMO,讓我們再來看看效果,分別設置了不同數量的 mask 漸隱消失:

圖片

CodePen Demo -- CSS Hudini Example & Custom Random[12]。

Wow!修正過后的效果不再閃爍,并且消失動畫也并非同時進行。在 Exploring the CSS Paint API: Image Fragmentation Effect[13] 這篇文章中,還介紹了一些其他利用 registerPaint 實現的有趣的 mask 漸隱效果,感興趣可以深入再看看。

這樣,我們就將原本 2400 行的 CSS 代碼,通過 CSS Painting API 的 registerPaint,壓縮到了 50 行以內的 JavaScript 代碼。

當然,CSS Houdini 的本事遠不止于此,本文一直在圍繞 background 描繪相關的內容進行闡述(mask 的語法也是背景 background 的一種)。在后續的文章我將繼續介紹在其他屬性上的應用。

兼容性如何?

那么,CSS Painting API 的兼容性到底如何呢?

CanIUse - registerPaint[14] 數據如下(截止至 2022-11-23):

圖片

Chrome 和 Edge 基于 Chromium[15] 內核的瀏覽器很早就已經支持,而主流瀏覽器中,Firefox 和 Safari 目前還不支持。

CSS Houdini 雖然強大,目前看來要想大規模上生產環境,仍需一段時間的等待。讓我們給時間一點時間!

最后

好了,本文到此結束,希望本文對你有所幫助 :)

參考資料

[1]現代 CSS 之高階圖片漸隱消失術: ?https://github.com/chokcoco/cococss/issues/23?。?

[2]CodePen Demo -- 基于 @property 和 mask 的文本漸隱消失術: ?https://codepen.io/Chokcoco/pen/qBKPgZY?。?

[3]CSS 對象模型: ?https://developer.mozilla.org/zh-CN/docs/Web/API/CSS_Object_Model?。?

[4]CSS Painting API Level 1: ?https://drafts.css-houdini.org/css-paint-api/#paintworkletglobalscope?。?

[5]CSS Houdini: ?https://developer.mozilla.org/zh-CN/docs/Web/Guide/Houdini?。?

[6]Worklet (en-US): ?https://developer.mozilla.org/en-US/docs/Web/API/Worklet?。?

[7]CodePen Demo -- CSS Hudini Example - Background Circle: ?https://codepen.io/Chokcoco/pen/abKExxN?。?

[8]CSS Painting API Level 1 - The 2D rendering context: ?https://drafts.css-houdini.org/css-paint-api/#paintworkletglobalscope?。?

[9]CodePen Demo -- CSS Hudini Example: https://codepen.io/Chokcoco/pen/KKeQWJb。?

[10]CodePen Demo -- CSS Hudini Example: ?https://codepen.io/Chokcoco/pen/oNyEpLN?。?

[11]Exploring the CSS Paint API: Image Fragmentation Effect: ?https://dev.to/this-is-learning/exploring-the-css-paint-api-image-fragmentation-effect-3ekl?。?

[12]CodePen Demo -- CSS Hudini Example & Custom Random: ?https://codepen.io/Chokcoco/pen/eYKVQGG?。?

[13]Exploring the CSS Paint API: Image Fragmentation Effect: ?https://dev.to/this-is-learning/exploring-the-css-paint-api-image-fragmentation-effect-3ekl?。?

[14]CanIUse - registerPaint: ?https://caniuse.com/?search=registerPaint?。?

[15]Chromium: ?https://www.google.com.hk/search?newwindow=1&rlz=1C5GCEM_enCN988CN988&q=Chromium&spell=1&sa=X&ved=2ahUKEwi3he2ensL7AhVaSmwGHdnzBxgQkeECKAB6BAgoEAE?

責任編輯:姜華 來源: iCSS前端趣聞
相關推薦

2023-11-01 08:36:07

CSSTailwind

2021-09-07 10:29:11

JavaScript模塊CSS

2022-12-22 08:34:22

CSS不規則圖形

2021-08-12 06:08:15

CSS 技巧組件狀態

2023-04-05 14:19:07

FlinkRedisNoSQL

2023-05-23 13:59:41

RustPython程序

2013-12-17 09:02:03

Python調試

2022-12-21 15:56:23

代碼文檔工具

2013-12-31 09:19:23

Python調試

2021-05-20 08:37:32

multiprocesPython線程

2013-08-22 10:17:51

Google大數據業務價值

2015-03-16 12:50:44

2015-02-05 13:27:02

移動開發模塊SDK

2011-01-18 10:45:16

喬布斯

2012-06-08 13:47:32

Wndows 8Vista

2022-08-09 09:38:29

JavaScript函數

2024-08-29 08:07:59

GoAPI開發

2021-12-14 19:40:07

Node路由Vue

2025-09-12 00:00:00

DevToolsJavaScript調試術

2017-05-22 10:33:14

PythonJuliaCython
點贊
收藏

51CTO技術棧公眾號

午夜在线a亚洲v天堂网2018| 成年人在线观看网站| 婷婷综合社区| 91精品国产手机| www国产无套内射com| 国产女主播福利| 精品69视频一区二区三区Q| 亚洲福利在线观看| 亚洲乱码国产一区三区| 天堂资源在线中文| 国产高清精品网站| 中文字幕欧美日韩在线| 精品国产乱码久久久久久1区二区| 亚洲成人三级| 国产精品一二三四| 91国自产精品中文字幕亚洲| xxxx日本免费| 99精品国产九九国产精品| 亚洲精品国产品国语在线app| 91在线高清免费观看| 蜜臀久久精品久久久用户群体| 2021年精品国产福利在线| 午夜成人免费视频| 亚洲欧美成人一区| 91在线视频国产| 欧美视频导航| 精品亚洲一区二区| 一区二区久久精品| 97成人资源| 1204国产成人精品视频| 亚洲人成免费网站| 亚洲国产精品成人一区二区| 成人在线激情网| 四虎影院观看视频在线观看| 2023国产一二三区日本精品2022| 欧洲一区二区视频| 9999热视频| 免费精品国产| 欧美日韩高清一区二区| 国产中文字幕视频在线观看| 精品麻豆一区二区三区| 99re这里只有精品首页| 国产精品视频久久久| 日本亚洲色大成网站www久久| 九一成人免费视频| 精品福利在线导航| 亚洲妇熟xx妇色黄蜜桃| 亚洲一区资源| 亚洲精品国产a久久久久久| 欧美日韩在线观看一区| 欧美一区二区三区黄片| 国产一区二区成人久久免费影院 | 免费看日本黄色| av中文字幕在线| 91免费在线播放| 国产精品一区而去| 伊人久久中文字幕| 免费一级欧美片在线播放| 在线亚洲伦理| 2025韩国理伦片在线观看| 亚洲图片另类小说| 亚洲精品成人一区| 91久久国产最好的精华液| 亚洲欧美日韩网| 日韩精品一区在线视频| 国产网站在线免费观看| 国产精品毛片无遮挡高清| 免费日韩一级片| 亚洲在线视频福利| 亚洲熟妇无码av| av毛片精品| 麻豆国产精品777777在线| 亚洲精品一区二三区不卡| 一边摸一边做爽的视频17国产 | 99久久伊人网影院| 国产精品一区二区免费| 性一交一乱一乱一视频| 国产二区国产一区在线观看| 高清日韩一区| 亚洲精品一区二区三区蜜桃| 国产ts人妖一区二区| 国产精品日韩欧美一区二区| 人妻妺妺窝人体色www聚色窝| 成人黄色av网站在线| 97视频中文字幕| 隣の若妻さん波多野结衣| 国产99精品国产| 激情欧美一区二区三区中文字幕| 羞羞在线观看视频| 澳门黄色一级片| 日韩精品美女| 欧美色xxxx| 亚洲 欧美 日韩系列| 色在线视频观看| 色综合一个色综合亚洲| 日本熟妇人妻xxxxx| 91精品影视| 欧美精品粉嫩高潮一区二区| 国产在线观看免费播放| 欧美亚洲国产日韩| 在线观看中文字幕亚洲| 亚洲成色www久久网站| 91麻豆成人精品国产免费网站| 91成人小视频| 亚洲丶国产丶欧美一区二区三区| 人人妻人人澡人人爽欧美一区双 | 在线播放 亚洲| 中文一区二区视频| 久久免费看少妇高潮| 国内精品视频在线观看| 在线激情网站| 国产破处视频在线观看| 亚洲精品国产系列| 国产一区二区黑人欧美xxxx| 亚洲男同性恋视频| 久久中文在线| 亚洲精品一区二区口爆| 免费一级淫片aaa片毛片a级| 美女av一区二区| 亚洲三级在线免费观看| 欧美1级片网站| av午夜在线| 成年人二级毛片| 国产手机视频在线观看| 欧美巨大黑人极品精男| 午夜一区二区三区视频| 国产精品国产三级国产aⅴ中文 | 一本色道久久综合精品婷婷| 久久无码专区国产精品s| 一区二区国产日产| 国产精品激情自拍| 亚洲天堂日韩电影| 国产精品国产三级国产aⅴ入口| 手机在线电影一区| 国产99re66在线视频| 4438国产精品一区二区| 国产精品一级无码| 手机在线视频你懂的| 国产精品电影网| 日韩二区三区在线| 制服丝袜亚洲网站| 国产91丝袜在线播放九色| eeuss鲁片一区二区三区| 三级网站视频在在线播放| 你懂的国产在线| 特级丰满少妇一级| 视频一区二区在线| 欧美日韩国产丝袜另类| 99精品久久久| 鲁大师精品99久久久| 国外av在线| 日韩av电影网| 国产亚洲精品久久久久久豆腐| 9色在线视频网站| 国产精品久久久久久久久搜平片| 国产乱子伦农村叉叉叉| 99热这里只有精品首页| 久久综合色影院| 欧美激情一区二区三区免费观看| 在线观看毛片av| 91蜜桃臀久久一区二区| 日韩一区二区久久久| 中文字幕免费观看| 99re热这里只有精品视频| 尤物一区二区三区| 中文字幕在线免费观看视频| 亚洲国产99精品国自产| 人妻久久一区二区| 久久精品久久99精品久久| 日本在线观看一区二区三区| 欧美特大特白屁股xxxx| 亚洲欧美一区二区三区情侣bbw| 天天综合网入口| 国产一区二区亚洲| 99久久亚洲精品蜜臀| 夜夜嗨av色一区二区不卡| 国产精品日日夜夜| 国产成人激情av| 亚洲色成人www永久在线观看| 性色av浪潮av| 在线观看中文字幕的网站| 制服丝袜亚洲精品中文字幕| 神马久久精品综合| 精品亚洲国产成人av制服丝袜| 在线精品日韩| 国产专区精品| 欧美国产日韩中文字幕在线| 国模私拍视频在线| 疯狂做受xxxx欧美肥白少妇 | 亚洲永久视频| 日产精品高清视频免费| 欧美大陆国产| 欧美极品欧美精品欧美视频 | 国产精品99久久久久久白浆小说 | 欧美精品在欧美一区二区少妇| 国产小视频你懂的| 懂色av中文字幕一区二区三区| 分分操这里只有精品| 久久99影视| 95av在线视频| 欧美少妇精品| 中文在线资源观看视频网站免费不卡| 在线观看免费视频a| 天堂中文在线官网| 国产一区二区视频在线看| 亚洲欧美中文日韩在线v日本| 亚洲一区二区不卡视频| 国产小视频免费| 久久久av网站| 日韩欧美的一区二区| 亚洲一级一级97网| 欧美日韩国产二区| 欧美国产视频一区二区| 国产精品欧美在线| 国产精品波多野结衣| 国产精品久久久久久久乖乖| 免费在线观看毛片网站| 久久久久久香蕉| 国产91在线视频观看| 91精品国产高清91久久久久久 | 9l亚洲国产成人精品一区二三| 中文字幕区一区二区三| 全球成人免费直播| 亚洲激情av| 波多野结衣视频一区二区| 日本高清www免费视频| 国产又粗又猛又爽又黄视频| 国语对白做受69按摩| 国产精品久久久久久久久夜色| 中文字幕一区二区三区波野结 | 最新精品国偷自产在线| 在线成人超碰| 国产精品一区二区久久不卡| 中文字幕一区二区三区视频| 欧美三级日韩三级| 国产亚洲日本欧美韩国| 国产精品一区二区久久| 在线观看欧美亚洲| 亚洲一区二区三区四区五区| 五月天综合视频| 中文字幕免费高清网站| 欧美性猛交xxx乱大交3蜜桃| 国产成人午夜性a一级毛片| 999精品在线| 国产不卡一区视频| 欧美性猛交99久久久久99按摩| 亚洲老头老太hd| 国产精品夜间视频香蕉| 精品久久久久久久免费人妻| 老熟女高潮一区二区三区| 日韩av综合在线| av在线不卡免费| 欧美激情综合| 国产女人水真多18毛片18精品视频 | 热久久精品免费视频| 91这里只有精品| 色婷婷狠狠综合| 国产无遮挡呻吟娇喘视频| 精品国产鲁一鲁一区二区张丽| 国产在线久久久| 国产网站在线免费观看| 美女撒尿一区二区三区| 在线观看中文| 欧美精品videos另类日本| 在线视频一二三区| 欧美日韩精品一区二区三区在线观看| 国产精品免费看一区二区三区| 国产成人一二| 欧美视频1区| 91综合久久| 久久这里只有精品8| 日韩图片一区| 免费观看成人网| 久久 天天综合| 亚洲无人区码一码二码三码| 97久久精品人人澡人人爽| 69视频在线观看免费| 中文字幕在线免费不卡| 免费视频网站www| 日韩欧美在线观看| 一级黄色片在线| 日韩视频一区二区| 香蕉视频免费在线看| 在线精品视频视频中文字幕| a级毛片免费观看在线| 欧美亚洲成人精品| 亚洲二区av| 激情伦成人综合小说| 久久国产小视频| 91黄色在线看| 人人爽香蕉精品| 国产一级二级av| 国产日韩欧美在线一区| 91成人福利视频| 亚洲一区在线观看视频| 在线观看亚洲黄色| 精品国产乱码久久久久久免费 | 成人深夜在线观看| 国产伦精品一区二区三区视频女| 亚洲欧美日韩中文字幕一区二区三区 | 人体久久天天| 伊人情人网综合| 久久亚洲一区| 国产精品91一区| а天堂中文在线官网| 欧洲精品在线视频| 91综合久久爱com| 一区二区欧美日韩| 国产欧美不卡| 久久久久无码精品| 国产精品久久久久久久久久免费看| 日本五十熟hd丰满| 欧美一区二区三区在线观看视频| 欧美69xxxxx| 欧美激情一区二区久久久| 精品176极品一区| 免费在线成人av| 91久久黄色| 久久久久中文字幕亚洲精品| 国产精品色哟哟| 日韩免费视频一区二区视频在线观看| 欧美一区午夜精品| 中文字幕在线免费| 日本精品久久久久影院| 嗯用力啊快一点好舒服小柔久久| 一区二区三区四区视频在线 | 国产精品日韩成人| 国产成人在线视频观看| 精品欧美一区二区在线观看| 欧美一级二级三级区| 国产精品美女久久久久久免费| 欧美男男freegayvideosroom| 青青视频免费在线观看| 老司机一区二区| 国产精品一区二区亚洲| 在线观看国产一区二区| 日本又骚又刺激的视频在线观看| 午夜精品久久久久久久男人的天堂 | 一本一道久久综合狠狠老精东影业| 巨乳女教师的诱惑| 亚洲日本va午夜在线影院| 国产免费的av| 久久九九全国免费精品观看| 9.1麻豆精品| gogogo免费高清日本写真| 精东粉嫩av免费一区二区三区| 久久午夜精品视频| 欧美区在线观看| 免费黄色网页在线观看| 成人字幕网zmw| 中文精品久久| 久久精品无码专区| 精品久久久久国产| 男人天堂网在线观看| 日本在线观看天堂男亚洲| 国产精选一区| 在线免费视频一区| 亚洲欧美日韩在线| 亚洲精品97久久中文字幕无码 | 日韩欧美中文字幕视频| 日韩美女视频一区二区在线观看| 欧美黑人猛交的在线视频| 成人在线观看91| 99精品视频免费| 久久午夜福利电影| 欧美久久久久久久久中文字幕| 黄色动漫在线| 国产亚洲一区在线播放| 久久成人精品| 国产尤物在线播放| 精品人在线二区三区| 深夜福利视频一区二区| 日本一区免费看| 国产麻豆一精品一av一免费| 国产成人啪精品午夜在线观看| 精品亚洲永久免费精品| 久久天堂影院| www.夜夜爱| 国产亚洲成aⅴ人片在线观看| 亚洲视频在线免费播放| 欧美区在线播放| 要久久爱电视剧全集完整观看| 牛夜精品久久久久久久| 一区二区三区欧美视频| 天堂中文字幕在线| 成人av番号网| 99成人免费视频| 国产美女高潮视频| 亚洲成av人影院在线观看| 免费欧美电影| av片在线免费| 国产网站一区二区三区| 国产成人免费看一级大黄| 欧美在线观看网站| 亚洲天堂免费| 亚洲 小说 欧美 激情 另类| 日韩色视频在线观看| 成人做爰视频www网站小优视频| 永久免费网站视频在线观看| 久久久久国产精品人|