• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    js動畫(animate)簡單引擎代碼示例_javascript技巧

    來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 21:05:41
    文檔

    js動畫(animate)簡單引擎代碼示例_javascript技巧

    js動畫(animate)簡單引擎代碼示例_javascript技巧:用慣了jquery的同學,相信都很欣賞其動畫引擎。確實相對比較完善!如果,如果想像力足夠豐富的話,相信可以做出超出想像的效果。當然,跟2d庫比起來,還是相差相當一段距離。jquery壓根也不是專門為動畫而設計的。模擬真實世界方面,還是不足的。但在web世
    推薦度:
    導讀js動畫(animate)簡單引擎代碼示例_javascript技巧:用慣了jquery的同學,相信都很欣賞其動畫引擎。確實相對比較完善!如果,如果想像力足夠豐富的話,相信可以做出超出想像的效果。當然,跟2d庫比起來,還是相差相當一段距離。jquery壓根也不是專門為動畫而設計的。模擬真實世界方面,還是不足的。但在web世
    用慣了jquery的同學,相信都很欣賞其動畫引擎。確實相對比較完善!如果,如果想像力足夠豐富的話,相信可以做出超出想像的效果。當然,跟2d庫比起來,還是相差相當一段距離。jquery壓根也不是專門為動畫而設計的。模擬真實世界方面,還是不足的。但在web世界里還是游刃有余的。動畫其實一直是flash的專屬領地(web區(qū)哉)。只是它常常淪為黑客攻擊的漏洞所在,而且要裝插件,有時候文件實在太大,而且性耗實在是高啊。html5出現(xiàn)后,其實adobe自己都轉(zhuǎn)移陣地到html5了。當然,我覺得很長一段時間內(nèi),flash是不會被放棄的。

    長話短說,步入正題。仿照flash的動畫原理,自己寫了一個非常簡單的js動畫引擎。

    首先,用過flash的同學都知道。flash有個時間線,上面布滿了“幀”。其實每個幀都是一個鏡頭,鏡頭連貫起來就是一副動畫效果。其實,這跟電影的原理也一樣的,小時候玩過膠片的都知道,對著光可以看到一副副的鏡頭。人眼分辨兩個畫面的連貫是有時間限度的。如果想看不到兩個畫面變換時的閃爍大概30幀/秒左右,電影是24幀的。所以,如果能保證,動畫切換能保證每秒30次,基本上,就做到了動畫的流暢效果,但是這取決環(huán)境。所以具體情況,具體而定,其實關于這方面的知識我也是一知半解。就這個動畫引擎而言,了解這么多也差不多足夠了,有興趣可以查找相關知識!

    下面開始說說設計原理。

    首先需要一個幀頻,也就是多少幀每秒。如果有了總用時,就可以計算出整個動畫下來有多少個“畫面”(總幀數(shù))。這種設計,顯然有個不足的地方,不能保證時間正好是個整數(shù)幀。除非1ms一幀。這是一個網(wǎng)友提出來的,我感覺不好就沒有采用。所以這個引擎是有時間誤差的。有了總幀數(shù),當動畫運行到最后一幀的時候,整個動畫也就播放完。如果需要重復播放,重新把當前幀歸0。這種動畫有一個好處,就可以直接運行到指定幀。也就是flash里的gotoAndStop和gotoAndPlay。其實整個動畫設計原理都是照著flash實現(xiàn)的。包括一個很重要的方法:enterFrame。位置就是根據(jù)進入當前幀來計算的。還有其它一些方法:stop、play、next......等等因為目前來說,這個引擎是寫非常簡單和粗糙的,先不說這么詳細了。下面先上代碼和示例吧!

    animate.js 動畫核心
    代碼如下:
    var animation = function(obj) {
    this.obj = obj;
    this.frames = 0;
    this.timmer = undefined;
    this.running = false;
    this.ms = [];
    }

    animation.prototype = {
    fps: 36,
    init: function(props, duration, tween) {
    //console.log('初始化');
    this.curframe = 0;
    this.initstate = {};
    this.props = props;
    this.duration = duration || 1000;
    this.tween = tween || function(t, b, c, d) {
    return t * c / d + b;
    };
    this.frames = Math.ceil(this.duration * this.fps/1000);
    for (var prop in this.props) {
    this.initstate[prop] = {
    from: parseFloat($util.dom.getStyle(this.obj, prop)),
    to: parseFloat(this.props[prop])
    };
    }
    },
    start: function() {
    if (!this.running && this.hasNext()) {
    //console.log('可以執(zhí)行...');
    this.ms.shift().call(this)
    }
    return this;
    },
    //開始播放
    play: function(callback) {
    //console.log('開始動畫!');
    var that = this;

    this.running = true;

    if (this.timmer) {
    this.stop();
    }

    this.timmer = setInterval(function() {
    if (that.complete()) {
    that.stop();
    that.running = false;
    if (callback) {
    callback.call(that);
    }
    return;
    }
    that.curframe++;
    that.enterFrame.call(that);
    },
    / this.fps);

    return this;
    },
    // 停止動畫
    stop: function() {
    //console.log('結(jié)束動畫!');
    if (this.timmer) {
    clearInterval(this.timmer);
    // 清除掉timmer id
    this.timmer = undefined;
    }

    },
    go: function(props, duration, tween) {
    var that = this;
    //console.log(tween)
    this.ms.push(function() {
    that.init.call(that, props, duration, tween);
    that.play.call(that, that.start);
    });
    return this;
    },
    //向后一幀
    next: function() {
    this.stop();
    this.curframe++;
    this.curframe = this.curframe > this.frames ? this.frames: this.curframe;
    this.enterFrame.call(this);
    },
    //向前一幀
    prev: function() {
    this.stop();
    this.curframe--;
    this.curframe = this.curframe < 0 ? 0 : this.curframe;
    this.enterFrame.call(this);
    },
    //跳躍到指定幀并播放
    gotoAndPlay: function(frame) {
    this.stop();
    this.curframe = frame;
    this.play.call(this);
    },
    //跳到指定幀停止播放
    gotoAndStop: function(frame) {
    this.stop();
    this.curframe = frame;
    this.enterFrame.call(this);
    },
    //進入幀動作
    enterFrame: function() {
    //console.log('進入幀:' + this.curframe)
    var ds;
    for (var prop in this.initstate) {
    //console.log('from: ' + this.initstate[prop]['from'])
    ds = this.tween(this.curframe, this.initstate[prop]['from'], this.initstate[prop]['to'] - this.initstate[prop]['from'], this.frames).toFixed(2);
    //console.log(prop + ':' + ds)
    $util.dom.setStyle(this.obj, prop, ds)
    }
    },
    //動畫結(jié)束
    complete: function() {
    return this.curframe >= this.frames;
    },
    hasNext: function() {
    return this.ms.length > 0;
    }
    }

    下面是一個簡單的工具,其中有所用到的緩動公式:

    util.js

    代碼如下:
    $util = {
    /**
    * 類型檢測
    */
    type : function(obj){
    var rep = /\[object\s+(\w+)\]/i;
    var str = Object.prototype.toString.call(obj).toLowerCase();
    str.match(rep);
    return RegExp.$1;
    },
    /**
    * 深拷貝
    */
    $unlink :function (object){
    var unlinked;
    switch ($type(object)){
    case 'object':
    unlinked = {};
    for (var p in object) {
    unlinked[p] = $unlink(object[p]);
    }
    break;
    case 'array':
    unlinked = [];
    for (var i = 0, l = object.length; i < l; i++) {
    unlinked[i] = $unlink(object[i]);
    }
    break;
    default: return object;
    }
    return unlinked;
    },
    /**
    *Dom 相關操作
    */
    dom:{
    $: function(id) {
    return document.getElementById(id);
    },
    getStyle: function(obj, prop) {
    var style = obj.currentStyle || window.getComputedStyle(obj, '');
    if (obj.style.filter) {
    return obj.style.filter.match(/\d+/g)[0];
    }
    return style[prop];
    },
    setStyle: function(obj, prop, val) {
    switch (prop) {
    case 'opacity':
    if($util.client.browser.ie){
    obj.style.filter = 'alpha(' + prop + '=' + val*100 + ')'
    }else{
    obj.style[prop] = val;
    }
    break;
    default:
    obj.style[prop] = val + 'px';
    break;
    }
    },
    setStyles: function(obj, props) {
    for (var prop in props) {
    switch (prop) {
    case 'opacity':
    if($util.client.browser.ie){
    obj.style.filter = 'alpha(' + prop + '=' + props[prop] + ')'
    }else{
    obj.style[prop] = props[prop];
    }
    break;
    default:
    obj.style[prop] = props[prop] + 'px';
    break;
    }
    }
    }
    },
    /**
    *Event 事件相關
    */
    evt : {
    addEvent : function(oTarget, sEventType, fnHandler) {
    if (oTarget.addEventListener) {
    oTarget.addEventListener(sEventType, fnHandler, false);
    } else if (oTarget.attachEvent) {
    oTarget.attachEvent("on" + sEventType, fnHandler);
    } else {
    oTarget["on" + sEventType] = fnHandler;
    }
    },
    rmEvent : function removeEventHandler (oTarget, sEventType, fnHandler) {
    if (oTarget.removeEventListener) {
    oTarget.removeEventListener(sEventType, fnHandler, false);
    } else if (oTarget.detachEvent) {
    oTarget.detachEvent("on" + sEventType, fnHandler);
    } else {
    oTarget["on" + sEventType] = null;
    }
    }
    },
    /**
    *Ajax 異步加載
    */
    ajax : {
    request:function (options) {
    var xhr, res;
    var url = options.url,
    context = options.context,
    success = options.success,
    type = options.type,
    datatype = options.datatype,
    async = options.async,
    send = options.send,
    headers = options.headers;

    try {
    xhr = new XMLHttpRequest();
    } catch(e) {
    try {
    xhr = new ActiveXObject('MSXML2.XMLHTTP');
    } catch(e) {
    xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }
    }

    xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
    res = xhr.responseText;
    success(res);
    }
    }
    xhr.open(type, url, async);
    xhr.send(send);
    }
    },
    /**
    *Array 數(shù)組相關
    */
    array : {
    minIndex : function(ary){
    return Math.min.apply(null,ary);
    },
    maxitem : function(ary){
    return Math.max.apply(null,ary);
    }
    },
    /**
    *Client 客戶端檢測
    */
    client : function(){
    // 瀏覽器渲染引擎 engines
    var engine = {
    ie: 0,
    gecko: 0,
    webkit: 0,
    khtml: 0,
    opera: 0,

    //complete version
    ver: null
    };

    // 瀏覽器
    var browser = {
    //browsers
    ie: 0,
    firefox: 0,
    safari: 0,
    konq: 0,
    opera: 0,
    chrome: 0,
    //specific version
    ver: null
    };

    // 客戶端平臺platform/device/OS
    var system = {
    win: false,
    mac: false,
    x11: false,

    //移動設備
    iphone: false,
    ipod: false,
    ipad: false,
    ios: false,
    android: false,
    nokiaN: false,
    winMobile: false,

    //game systems
    wii: false,
    ps: false
    };

    // 檢測瀏覽器引擎
    var ua = navigator.userAgent;
    if (window.opera){
    engine.ver = browser.ver = window.opera.version();
    engine.opera = browser.opera = parseFloat(engine.ver);
    } else if (/AppleWebKit\/(\S+)/.test(ua)){
    engine.ver = RegExp["$1"];
    engine.webkit = parseFloat(engine.ver);

    //figure out if it's Chrome or Safari
    if (/Chrome\/(\S+)/.test(ua)){
    browser.ver = RegExp["$1"];
    browser.chrome = parseFloat(browser.ver);
    } else if (/Version\/(\S+)/.test(ua)){
    browser.ver = RegExp["$1"];
    browser.safari = parseFloat(browser.ver);
    } else {
    //approximate version
    var safariVersion = 1;
    if (engine.webkit < 100){
    safariVersion = 1;
    } else if (engine.webkit < 312){
    safariVersion = 1.2;
    } else if (engine.webkit < 412){
    safariVersion = 1.3;
    } else {
    safariVersion = 2;
    }

    browser.safari = browser.ver = safariVersion;
    }
    } else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){
    engine.ver = browser.ver = RegExp["$1"];
    engine.khtml = browser.konq = parseFloat(engine.ver);
    } else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){
    engine.ver = RegExp["$1"];
    engine.gecko = parseFloat(engine.ver);

    //determine if it's Firefox
    if (/Firefox\/(\S+)/.test(ua)){
    browser.ver = RegExp["$1"];
    browser.firefox = parseFloat(browser.ver);
    }
    } else if (/MSIE ([^;]+)/.test(ua)){
    engine.ver = browser.ver = RegExp["$1"];
    engine.ie = browser.ie = parseFloat(engine.ver);
    }

    //detect browsers
    browser.ie = engine.ie;
    browser.opera = engine.opera;

    //detect platform
    var p = navigator.platform;
    system.win = p.indexOf("Win") == 0;
    system.mac = p.indexOf("Mac") == 0;
    system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);

    //detect windows operating systems
    if (system.win){
    if (/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(ua)){
    if (RegExp["$1"] == "NT"){
    switch(RegExp["$2"]){
    case "5.0":
    system.win = "2000";
    break;
    case "5.1":
    system.win = "XP";
    break;
    case "6.0":
    system.win = "Vista";
    break;
    case "6.1":
    system.win = "7";
    break;
    default:
    system.win = "NT";
    break;
    }
    } else if (RegExp["$1"] == "9x"){
    system.win = "ME";
    } else {
    system.win = RegExp["$1"];
    }
    }
    }

    //mobile devices
    system.iphone = ua.indexOf("iPhone") > -1;
    system.ipod = ua.indexOf("iPod") > -1;
    system.ipad = ua.indexOf("iPad") > -1;
    system.nokiaN = ua.indexOf("NokiaN") > -1;

    //windows mobile
    if (system.win == "CE"){
    system.winMobile = system.win;
    } else if (system.win == "Ph"){
    if(/Windows Phone OS (\d+.\d+)/.test(ua)){;
    system.win = "Phone";
    system.winMobile = parseFloat(RegExp["$1"]);
    }
    }

    //determine iOS version
    if (system.mac && ua.indexOf("Mobile") > -1){
    if (/CPU (?:iPhone )?OS (\d+_\d+)/.test(ua)){
    system.ios = parseFloat(RegExp.$1.replace("_", "."));
    } else {
    system.ios = 2; //can't really detect - so guess
    }
    }

    //determine Android version
    if (/Android (\d+\.\d+)/.test(ua)){
    system.android = parseFloat(RegExp.$1);
    }

    //gaming systems
    system.wii = ua.indexOf("Wii") > -1;
    system.ps = /playstation/i.test(ua);

    //return it
    return {
    engine: engine,
    browser: browser,
    system: system
    };

    }(),
    /**
    *Tween 緩動相關
    */
    tween: {
    Linear: function(t, b, c, d) {
    return c * t / d + b;
    },
    Quad: {
    easeIn: function(t, b, c, d) {
    return c * (t /= d) * t + b;
    },
    easeOut: function(t, b, c, d) {
    return - c * (t /= d) * (t - 2) + b;
    },
    easeInOut: function(t, b, c, d) {
    if ((t /= d / 2) < 1) return c / 2 * t * t + b;
    return - c / 2 * ((--t) * (t - 2) - 1) + b;
    }
    },
    Cubic: {
    easeIn: function(t, b, c, d) {
    return c * (t /= d) * t * t + b;
    },
    easeOut: function(t, b, c, d) {
    return c * ((t = t / d - 1) * t * t + 1) + b;
    },
    easeInOut: function(t, b, c, d) {
    if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
    return c / 2 * ((t -= 2) * t * t + 2) + b;
    }
    },
    Quart: {
    easeIn: function(t, b, c, d) {
    return c * (t /= d) * t * t * t + b;
    },
    easeOut: function(t, b, c, d) {
    return - c * ((t = t / d - 1) * t * t * t - 1) + b;
    },
    easeInOut: function(t, b, c, d) {
    if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
    return - c / 2 * ((t -= 2) * t * t * t - 2) + b;
    }
    },
    Quint: {
    easeIn: function(t, b, c, d) {
    return c * (t /= d) * t * t * t * t + b;
    },
    easeOut: function(t, b, c, d) {
    return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
    },
    easeInOut: function(t, b, c, d) {
    if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
    return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
    }
    },
    Sine: {
    easeIn: function(t, b, c, d) {
    return - c * Math.cos(t / d * (Math.PI / 2)) + c + b;
    },
    easeOut: function(t, b, c, d) {
    return c * Math.sin(t / d * (Math.PI / 2)) + b;
    },
    easeInOut: function(t, b, c, d) {
    return - c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
    }
    },
    Expo: {
    easeIn: function(t, b, c, d) {
    return (t == 0) ? b: c * Math.pow(2, 10 * (t / d - 1)) + b;
    },
    easeOut: function(t, b, c, d) {
    return (t == d) ? b + c: c * ( - Math.pow(2, -10 * t / d) + 1) + b;
    },
    easeInOut: function(t, b, c, d) {
    if (t == 0) return b;
    if (t == d) return b + c;
    if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
    return c / 2 * ( - Math.pow(2, -10 * --t) + 2) + b;
    }
    },
    Circ: {
    easeIn: function(t, b, c, d) {
    return - c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
    },
    easeOut: function(t, b, c, d) {
    return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
    },
    easeInOut: function(t, b, c, d) {
    if ((t /= d / 2) < 1) return - c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
    return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
    }
    },
    Elastic: {
    easeIn: function(t, b, c, d, a, p) {
    if (t == 0) return b;
    if ((t /= d) == 1) return b + c;
    if (!p) p = d * .3;
    if (!a || a < Math.abs(c)) {
    a = c;
    var s = p / 4;
    } else var s = p / (2 * Math.PI) * Math.asin(c / a);
    return - (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
    },
    easeOut: function(t, b, c, d, a, p) {
    if (t == 0) return b;
    if ((t /= d) == 1) return b + c;
    if (!p) p = d * .3;
    if (!a || a < Math.abs(c)) {
    a = c;
    var s = p / 4;
    } else var s = p / (2 * Math.PI) * Math.asin(c / a);
    return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);
    },
    easeInOut: function(t, b, c, d, a, p) {
    if (t == 0) return b;
    if ((t /= d / 2) == 2) return b + c;
    if (!p) p = d * (.3 * 1.5);
    if (!a || a < Math.abs(c)) {
    a = c;
    var s = p / 4;
    } else var s = p / (2 * Math.PI) * Math.asin(c / a);
    if (t < 1) return - .5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
    return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
    }
    },
    Back: {
    easeIn: function(t, b, c, d, s) {
    if (s == undefined) s = 1.70158;
    return c * (t /= d) * t * ((s + 1) * t - s) + b;
    },
    easeOut: function(t, b, c, d, s) {
    if (s == undefined) s = 1.70158;
    return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
    },
    easeInOut: function(t, b, c, d, s) {
    if (s == undefined) s = 1.70158;
    if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
    return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
    }
    },
    Bounce: {
    easeIn: function(t, b, c, d) {
    return c - Tween.Bounce.easeOut(d - t, 0, c, d) + b;
    },
    easeOut: function(t, b, c, d) {
    if ((t /= d) < (1 / 2.75)) {
    return c * (7.5625 * t * t) + b;
    } else if (t < (2 / 2.75)) {
    return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
    } else if (t < (2.5 / 2.75)) {
    return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
    } else {
    return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
    }
    },
    easeInOut: function(t, b, c, d) {
    if (t < d / 2) return Tween.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;
    else return Tween.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
    }
    }
    }

    }

    下面是個應用:

    代碼如下:




    無標題文檔

    聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    js動畫(animate)簡單引擎代碼示例_javascript技巧

    js動畫(animate)簡單引擎代碼示例_javascript技巧:用慣了jquery的同學,相信都很欣賞其動畫引擎。確實相對比較完善!如果,如果想像力足夠豐富的話,相信可以做出超出想像的效果。當然,跟2d庫比起來,還是相差相當一段距離。jquery壓根也不是專門為動畫而設計的。模擬真實世界方面,還是不足的。但在web世
    推薦度:
    標簽: 技巧 簡單 js
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 亚洲第一区精品观看| 国产在线精品一区二区在线观看 | 国产亚洲精品a在线观看app| 亚洲精品国自产拍在线观看| 国产成人精品午夜福麻豆| 999在线视频精品免费播放观看| 亚洲精品97久久中文字幕无码| 99久久精品国产一区二区| 国产精品无码久久久久久| 中文字幕九七精品乱码| 国内精品久久久久久久影视麻豆| 国产精品1024香蕉在线观看| 亚洲国产另类久久久精品| 无码AV动漫精品一区二区免费| 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲 | 国产精品久久久久久久久免费| 少妇人妻偷人精品免费视频| 欧美成人精品一区二三区在线观看| 91自慰精品亚洲| 久久亚洲国产精品一区二区| 国产精品久久久久久| 国产精品久久久久天天影视| 97久久国产亚洲精品超碰热| 久久精品国产亚洲av麻豆小说 | 性色精品视频网站在线观看 | 少妇伦子伦精品无码STYLES| 亚洲国产精品无码专区影院 | 欧美日韩国产精品 | 精品无码三级在线观看视频 | 国产AV无码专区亚洲精品| 欧产日产国产精品精品| 国产成人亚洲精品91专区手机| 亚洲av午夜国产精品无码中文字| 国模精品一区二区三区| 国产精品无码久久久久| 国产区精品高清在线观看| 精品久久国产一区二区三区香蕉| 国产精品尹人在线观看| 国产精品龙口护士门在线观看| 国产精品户外野外| 国产日韩高清三级精品人成|