【问题标题】:Extensive use of jQuery UI draggable, then save an image and use in Wordpress广泛使用 jQuery UI 可拖动,然后保存图像并在 Wordpress 中使用
【发布时间】:2014-03-28 06:56:42
【问题描述】:

2014 年 2 月 26 日更新

我已经知道这个问题会很详细,所以对于所有愿意尝试帮助我的人:我会尽快提供赏金。

案例

我的网站的循环(首页)看起来像这样。 (缩小以获得更好的概览)

如您所见,它是一个类似于“博客”的常规帖子流,带有标题、一些元信息、缩略图(“特色图片”)和摘录。缩略图的包装(父级)限制为 658 像素宽和 120 像素高。图像本身具有max-width: 100%,因此它永远不会比其父图像宽。在代码中,它看起来像这样:

.entry-thumbnail {
  max-height: 120px;
  overflow: hidden;
  margin-bottom: 1em;
}
.entry-thumbnail img {
  height: auto;
  max-width: 100%;
  margin: 0 auto;
}

如果图片本身的内容位于顶部,这将非常有效。但是,当图像的顶部相当空时,缩略图看起来也是空的。那是因为只显示图像的顶部 120 像素。其余像素被“截断”,因为 overflow: hidden 位于其父级上。

例如,您可以看到顶部有太多的空白。

解决方案

编辑 1an answer provided by D. Kasipovic 提供了一个很好的新见解。而不是保存两个单独的图像(一个完整的缩略图和一个裁剪的),应该可以保存图像的偏移位置。这样,这些值可以在首页上的每张图片中插入,而无需使用多张图片。

编辑 2:我编辑了 the fiddle。现在,只要更改图像的位置,输入字段 (#offset-val) 中的值就会发生变化。表示的值是相对于其父级的值。

理想情况下,此值会保存在数据库中(并在更改时被覆盖),并且在调用时,缩略图会获得 top: X 的 css 值,在这种情况下,X 代表数据库中的值。

到目前为止我所尝试的

首先,我一直在研究如何制作可拖动的图像等等。 (参见前面提到的小提琴)。这工作正常。我查看了画布并将画布保存到图像以保存图像。然而,这不是我需要的。我已经完成了小提琴。现在只需将输入字段的值保存到数据库并将该值与the_post_thumbnail 函数挂钩(使用过滤器?),这样当在首页时,一个额外的参数被传递给它,即@ 987654332@值。

需要做什么/目标

  • (最终得到一个 Wordpress 插件)
  • 将值保存到数据库(并在更改时覆盖)
  • 在循环中,该值应作为top 的X 值在style-tag 内导入
  • 应更改 the_post_thumbnail() 以便插入 style="top=X;",仅当在存档页面或首页的循环中时

如果有不清楚的地方,请务必指出。脑子里很清楚,但很难用语言表达。

【问题讨论】:

    标签: jquery jquery-ui wordpress thumbnails


    【解决方案1】:

    这听起来像是可以用 javascript 通过读取图像并比较每个像素的颜色来检测图像中的颜色变化,从而确定图像中的内容从哪里开始,以及哪里只有空白,并将上边距偏移到内容开始的位置。

    结果并没有我想象的那么简单,但我最终写了一个小 jQuery 插件。

    其中涉及一些复杂的计算,因此效率不高,但在一些随机图像的小测试中似乎可以正常工作。

    我添加了一个可以玩的容差设置,并且可以按选择器设置容差,如

    $('.entry-thumbnail img:eq(3)').setTop({
        tolerance : 90
    });
    

    容差是一个像素上的颜色相对于附近的其他像素而言可以关闭的百分比,以便将其视为颜色变化,因此是内容而不是空白。

    这是插件

    (function(window, $, undefined) {
    
        $.fn.setTop = function(options) {
    
            var settings = $.extend({ // default settings
                tolerance   : 90
            }, options);
    
            return this.each(function() {
                if (this.tagName.toLowerCase() == 'img') { // check that it's an image
                    var image = new Image(),
                        self  = this;
    
                    $(image).one('load', function() {
                        var width   = this.width,
                            height  = this.height,
                            canvas  = document.createElement('canvas'),
                            context, imgd;
    
                        canvas.width  = width;
                        canvas.height = height;
                        context       = canvas.getContext('2d');
    
                        context.drawImage( this, 0, 0 );
    
                         // add a catch for cross domain images
                        try { imgd = context.getImageData(0, 0, width, height); }
                        catch (e) { imgd = null; }
    
                        if (imgd) {
                            var pix   = imgd.data,
                                l     = pix.length,
                                prev  = null,
                                top   = 0;
    
                            for (var h=0; h<height; h++) {
                                var line = [];
    
                                for (var w=0; w < (width*4); w+=4) {
                                    var offset = h * (width * 4);
                                    var pixel  = [ pix[ w + offset ], pix[ w + offset + 1], pix[w + offset + 2] ];
                                    line.push(pixel);
                                }
    
                                if (prev) {
                                    if (! checkLine(line, prev, settings.tolerance) ) {
                                        top = h;
                                        break;
                                    }
                                }
                                prev = line;
                            }
                            self.style.marginTop = -top +'px';
                        }
                    });
    
                    image.src = this.src;
                    if (image.complete) $(image).load(); // cache busting
                }
            });
        }
    
        function checkLine(line, prev, tol) { // check each line for color changes along the pixels
                                              // also check the previous line so as to detect change happening line by line
            var valid = true;                 // and add a little offset to not be fooled by colors changing over many pixels / anti-aliasing
    
            for (var i=0, l=line.length; i<l-11; i++) {
                var diff  = parseFloat((100 - getDeltaE(line[i], line[i+10])).toFixed(2));
                if (diff < tol) {
                    valid = false
                    break;
                }else{
                    var diff2 = parseFloat((100 - getDeltaE(line[i], prev[i+5])).toFixed(2));
                    if (diff2 < tol) {
                        valid = false
                        break;
                    }
                }
            }
            return valid;
        }
    
        function getDeltaE(pixel1, pixel2) {  // use DeltaE to check color differences
            var arr = [pixel1, pixel2], arr2 = [];
    
            for (var i=0; i<arr.length; i++) {
                var _r = (arr[i][0] / 255), _g = (arr[i][1] / 255), _b = (arr[i][2] / 255);
    
                if ( _r > 0.04045) { _r = Math.pow(((_r + 0.055) / 1.055), 2.4); }
                else { _r = _r / 12.92; }
    
                if ( _g > 0.04045) { _g = Math.pow(((_g + 0.055) / 1.055), 2.4); }
                else { _g = _g / 12.92; }
    
                if (_b > 0.04045) { _b = Math.pow(((_b + 0.055) / 1.055), 2.4); }
                else { _b = _b / 12.92; }
    
                _r = _r * 100;
                _g = _g * 100;
                _b = _b * 100;
    
                var X = _r * 0.4124 + _g * 0.3576 + _b * 0.1805,
                    Y = _r * 0.2126 + _g * 0.7152 + _b * 0.0722,
                    Z = _r * 0.0193 + _g * 0.1192 + _b * 0.9505;
    
                var ref_X =  95.047, ref_Y = 100.000, ref_Z = 108.883,
                    _X = X / ref_X, _Y = Y / ref_Y, _Z = Z / ref_Z;
    
                if (_X > 0.008856) { _X = Math.pow(_X, (1/3)); }
                else { _X = (7.787 * _X) + (16 / 116); }
    
                if (_Y > 0.008856) { _Y = Math.pow(_Y, (1/3)); }
                else { _Y = (7.787 * _Y) + (16 / 116); }
    
                if (_Z > 0.008856) { _Z = Math.pow(_Z, (1/3)); }
                else { _Z = (7.787 * _Z) + (16 / 116); }
    
                var CIE_L = (116 * _Y) - 16;
                var CIE_a = 500 * (_X - _Y);
                var CIE_b = 200 * (_Y - _Z);
    
                arr2[i] = [((116 * _Y) - 16), (500 * (_X - _Y)), (200 * (_Y - _Z))];
            }
    
            var x = {l: arr2[0][0], a: arr2[0][2], b: arr2[0][2]},
                y = {l: arr2[1][0], a: arr2[1][3], b: arr2[1][2]},
                labx = x,
                laby = y,
                k2 = 0.015,
                k1 = 0.045,
                kl = 1, kh = 1, kc = 1,
                c1 = Math.sqrt(x.a * x.a + x.b * x.b),
                c2 = Math.sqrt(y.a * y.a + y.b * y.b),
                sh = 1 + k2 * c1,
                sc = 1 + k1 * c1,
                sl = 1,
                da = x.a - y.a,
                db = x.b - y.b,
                dc = c1 - c2,
                dl = x.l - y.l,
                dh = Math.sqrt((da * da) + (db * db) - (dc * dc));
    
            return Math.sqrt(Math.pow((dl/(kl * sl)),2) + Math.pow((dc/(kc * sc)),2) + Math.pow((dh/(kh * sh)),2));
        }
    })(window, jQuery, undefined);
    

    你会这样称呼它

    jQuery(function($) {
    
        $('.entry-thumbnail img').setTop();
    
    });
    

    Javascript 的同源策略禁止以这种方式读取跨域图像,所以我无法真正设置一个小提琴来显示它的工作原理,当然,图像必须托管在同一个域中。

    在 wordpress 中,您通常会将插件和调用该插件的代码放在一个文件中,并使用 wp_enqeue 以 jQuery 作为依赖项等加载文件。

    编辑:

    要添加一个选项,让帖子作者可以在使用媒体上传器插入图片时指定每张图片的偏移量,您需要一个小插件来更改媒体上传器并添加这样的字段,并更改输出图像以包含该数据。

    这会有点复杂,但它是可行的。

    首先我们需要创建一个插件,从文件夹和文件开始。
    使用编辑器在wordpress -&gt; wp-content -&gt; plugins下创建插件文件夹和文件

    该插件将包含三个文件,我将它们命名为这样

    我已将插件命名为 whitespace-remover,但它的名称并不重要。
    这三个文件是主要的 php 插件文件,一个用于使用媒体上传器时的 javascript 文件,以及一个包含上述插件的 javascript 文件,该文件稍作改动以说明作者添加的偏移量。

    让我们从前端加载的 javascript 文件开始,whitespace_front.js
    和以前一样,但是现在它检查一个数据属性,看看作者是否添加了偏移量

    jQuery(function($) {
    
        $('.entry-thumbnail img').each(function() {
            var offset = $(this).data('offset');
    
            if ( offset ) {
                $(this).css('margin-top', Math.abs(offset) * -1);
            }else{
                $(this).setTop();
            }
        });
    
    });
    
    
    (function(window, $, undefined) {
    
        $.fn.setTop = function(options) {
    
            var settings = $.extend({ // default settings
                tolerance   : 90
            }, options);
    
            return this.each(function() {
                if (this.tagName.toLowerCase() == 'img') { // check that it's an image
                    var image = new Image(),
                        self  = this;
    
                    $(image).one('load', function() {
                        var width   = this.width,
                            height  = this.height,
                            canvas  = document.createElement('canvas'),
                            context,
                            imgd;
    
                        canvas.width  = width;
                        canvas.height = height;
                        context       = canvas.getContext('2d');
    
                        context.drawImage( this, 0, 0 );
    
                        try { imgd = context.getImageData(0, 0, width, height); } // add a catch for cross domain images
                        catch (e) { imgd = null; }
    
                        if (imgd) {
                            var pix   = imgd.data,
                                l     = pix.length,
                                prev  = null,
                                top   = 0;
    
                            for (var h=0; h<height; h++) {
                                var line = [];
    
                                for (var w=0; w < (width*4); w+=4) {
                                    var offset = h * (width * 4);
                                    var pixel  = [ pix[ w + offset ], pix[ w + offset + 1], pix[w + offset + 2] ];
                                    line.push(pixel);
                                }
    
                                if (prev) {
                                    if (! checkLine(line, prev, settings.tolerance) ) {
                                        top = h;
                                        break;
                                    }
                                }
                                prev = line;
                            }
                            self.style.marginTop = -top +'px';
                        }
                    });
    
                    image.src = this.src;
                    if (image.complete) $(image).load(); // cache busting
                }
            });
        }
    
        function checkLine(line, prev, tol) { // check each line for color changes along the pixels
                                              // also check the previous line so as to detect change happening line by line
            var valid = true;                 // and add a little offset to not be fooled by colors changing over many pixels / anti-aliasing
    
            for (var i=0, l=line.length; i<l-11; i++) {
                var diff  = parseFloat((100 - getDeltaE(line[i], line[i+10])).toFixed(2));
                if (diff < tol) {
                    valid = false
                    break;
                }else{
                    var diff2 = parseFloat((100 - getDeltaE(line[i], prev[i+5])).toFixed(2));
                    if (diff2 < tol) {
                        valid = false
                        break;
                    }
                }
            }
            return valid;
        }
    
        function getDeltaE(pixel1, pixel2) {  // use DeltaE to check color differences
            var arr = [pixel1, pixel2], arr2 = [];
    
            for (var i=0; i<arr.length; i++) {
                var _r = (arr[i][0] / 255), _g = (arr[i][5] / 255), _b = (arr[i][2] / 255);
    
                if ( _r > 0.04045) { _r = Math.pow(((_r + 0.055) / 1.055), 2.4); }
                else { _r = _r / 12.92; }
    
                if ( _g > 0.04045) { _g = Math.pow(((_g + 0.055) / 1.055), 2.4); }
                else { _g = _g / 12.92; }
    
                if (_b > 0.04045) { _b = Math.pow(((_b + 0.055) / 1.055), 2.4); }
                else { _b = _b / 12.92; }
    
                _r = _r * 100;
                _g = _g * 100;
                _b = _b * 100;
    
                var X = _r * 0.4124 + _g * 0.3576 + _b * 0.1805,
                    Y = _r * 0.2126 + _g * 0.7152 + _b * 0.0722,
                    Z = _r * 0.0193 + _g * 0.1192 + _b * 0.9505;
    
                var ref_X =  95.047, ref_Y = 100.000, ref_Z = 108.883,
                    _X = X / ref_X, _Y = Y / ref_Y, _Z = Z / ref_Z;
    
                if (_X > 0.008856) { _X = Math.pow(_X, (1/3)); }
                else { _X = (7.787 * _X) + (16 / 116); }
    
                if (_Y > 0.008856) { _Y = Math.pow(_Y, (1/3)); }
                else { _Y = (7.787 * _Y) + (16 / 116); }
    
                if (_Z > 0.008856) { _Z = Math.pow(_Z, (1/3)); }
                else { _Z = (7.787 * _Z) + (16 / 116); }
    
                var CIE_L = (116 * _Y) - 16;
                var CIE_a = 500 * (_X - _Y);
                var CIE_b = 200 * (_Y - _Z);
    
                arr2[i] = [((116 * _Y) - 16), (500 * (_X - _Y)), (200 * (_Y - _Z))];
            }
    
            var x = {l: arr2[0][0], a: arr2[0][6], b: arr2[0][2]},
                y = {l: arr2[1][0], a: arr2[1][7], b: arr2[1][2]},
                labx = x,
                laby = y,
                k2 = 0.015,
                k1 = 0.045,
                kl = 1, kh = 1, kc = 1,
                c1 = Math.sqrt(x.a * x.a + x.b * x.b),
                c2 = Math.sqrt(y.a * y.a + y.b * y.b),
                sh = 1 + k2 * c1,
                sc = 1 + k1 * c1,
                sl = 1,
                da = x.a - y.a,
                db = x.b - y.b,
                dc = c1 - c2,
                dl = x.l - y.l,
                dh = Math.sqrt((da * da) + (db * db) - (dc * dc));
    
            return Math.sqrt(Math.pow((dl/(kl * sl)),2) + Math.pow((dc/(kc * sc)),2) + Math.pow((dh/(kh * sh)),2));
        }
    })(window, jQuery, undefined);
    

    现在我们需要在媒体上传器将图像发送到编辑器时添加该数据属性,因此我们必须更改原生 Wordpress 的 send_to_editor 函数来执行此操作,并将其放入文件 whitespace.js

    jQuery(function($) {
    
        window.send_to_editor = function (a){
    
            var img    = $('img', a),
                offset = new Array(img.length),
                j = 0,
                b,
                c = "undefined" != typeof tinymce,
                d = "undefined" != typeof QTags;
    
            $.ajax({
                url  : ws_js_glob.url,
                type : 'POST',
                data : {
                    data     : $.map(img, function(el) {
                        var id = /wp-image-(.*?)($|\s)/.exec(el.className);
                        return id[1] ? id[1] : null;
                    }),
                    action   :'whitespace',
                    security : ws_js_glob.secret
                },
                async : false,
                dataType : 'json'
            }).done(function(result) {
                offset = result;
            });
    
            a = a.replace(/\<img\s/gi, function(x) {
                var off_set = offset[j++];
                return off_set && off_set.length ? x + 'data-offset="'+ off_set +'" ' : x;
            });
    
            if (wpActiveEditor)
                c && (b =! tinymce.activeEditor || "mce_fullscreen" != tinymce.activeEditor.id && "wp_mce_fullscreen" != tinymce.activeEditor.id
                    ?
                    tinymce.get(wpActiveEditor)
                    :
                    tinymce.activeEditor);
    
            else if (c && tinymce.activeEditor)
                b = tinymce.activeEditor,
                wpActiveEditor = b.id;
    
            else if (!d)
                return !1;
    
            b && !b.isHidden() ? (tinymce.isIE && b.windowManager.insertimagebookmark && b.selection.moveToBookmark(b.windowManager.insertimagebookmark),
                -1 !== a.indexOf("[caption")
                ?
                b.wpSetImgCaption&&(a=b.wpSetImgCaption(a))
                :
                -1!==a.indexOf("[gallery")
                    ?
                    b.plugins.wpgallery && (a=b.plugins.wpgallery._do_gallery(a))
                    :
                    0===a.indexOf("[embed")&&b.plugins.wordpress&&(a=b.plugins.wordpress._setEmbed(a)),
                b.execCommand("mceInsertContent",!1,a)):d
            ?
            QTags.insertContent(a):document.getElementById(wpActiveEditor).value+=a;
            try{tb_remove()}
            catch(e){}
            return false;
        }
    
    });
    

    最后,我们需要将它们联系在一起的 PHP,添加脚本,并向媒体上传器添加一些自定义字段,这在 whitespace-remover.php

    <?php
    /*
    Plugin Name: Whitespace Remover
    Plugin URI: http://stackoverflow.com/questions/22024587/extensive-use-of-jquery-ui-draggable-then-save-an-image-and-use-in-wordpress/
    Description: Removes whitespace
    Version: 1.0
    Author: adeneo
    */
    
    if ( ! function_exists( 'add_action' ) ) 
        die( "This is just a plugin" ); 
    
    if ( ! defined( 'WHITESPACE_PLUGIN_BASENAME' ) )
        define( 'WHITESPACE_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
    
    if ( ! defined( 'WHITESPACE_PLUGIN_NAME' ) )
        define( 'WHITESPACE_PLUGIN_NAME', trim( dirname( WHITESPACE_PLUGIN_BASENAME ), '/' ) );
    
    if ( ! defined( 'WHITESPACE_PLUGIN_DIR' ) )
        define( 'WHITESPACE_PLUGIN_DIR', untrailingslashit( dirname( __FILE__ ) ) );
    
    if ( ! defined( 'WHITESPACE_PLUGIN_URL' ) )
        define( 'WHITESPACE_PLUGIN_URL', untrailingslashit( plugins_url( '', __FILE__ ) ) );
    
    add_filter( 'attachment_fields_to_edit', 'top_offset_attachment_field_credit', 10, 2 );
    add_filter( 'attachment_fields_to_save', 'top_offset_attachment_field_credit_save', 10, 2 );
    add_action( 'wp_ajax_whitespace' , 'ajaxhandler' );
    add_action( 'admin_enqueue_scripts', 'admin_scripts' );
    add_action( 'wp_enqueue_scripts', 'front_scripts' );
    
    function top_offset_attachment_field_credit( $form_fields, $post ) {
        $form_fields['top_offset'] = array(
            'label' => 'Top Offset',
            'input' => 'number',
            'value' => get_post_meta( $post->ID, 'top_offset', true ),
            'helps' => 'If provided, the image will be offset at the top to remove whitespace',
        );
    
        return $form_fields;
    }
    
    function top_offset_attachment_field_credit_save( $post, $attachment ) {
        if( isset( $attachment['top_offset'] ) )
            update_post_meta( $post['ID'], 'top_offset', $attachment['top_offset'] );
    
        return $post;
    }
    
    function ajaxhandler() {
        check_ajax_referer( 'my_secret_string', 'security', true );
        $attachment_id = $_POST['data'];
        $ids = array();
    
        foreach ($attachment_id as $id) {
            array_push($ids, get_post_meta($id, 'top_offset', true));
        }
    
        echo json_encode($ids);
        die();
    }
    
    function admin_scripts() {
        wp_register_script( 'whitespace_js', WHITESPACE_PLUGIN_URL . '/whitespace.js'    , array('jquery'), 1, true);
        wp_localize_script( 'whitespace_js', 'ws_js_glob', array(url => admin_url( 'admin-ajax.php' ), secret => wp_create_nonce( 'my_secret_string' ) ) );
        wp_enqueue_script(  'whitespace_js' );
    }
    
    function front_scripts() {
        wp_register_script( 'whitespace_front_js', WHITESPACE_PLUGIN_URL . '/whitespace_front.js'    , array('jquery'), 1, true);
        wp_enqueue_script(  'whitespace_front_js' );
    } 
    
    ?>
    

    这应该在媒体上传器中添加一个新的自定义字段来设置每个图像的顶部偏移量

    这有点复杂,但如果您曾经编写过插件,那应该是直截了当的。
    这还没有经过真正的测试,只是我写的东西来帮助你,它可以改进很多,仍然需要一些测试等。

    【讨论】:

    • 它确实运作良好 - 看到它在行动here。我非常感谢您为此付出的努力和时间。但是,我真的希望作者能够手动设置他们认为合适的偏移量。 (我信任人类胜过信任机器,天网不可信!)所以我会再等几天,以防有人提供手动设置偏移量的方法。如果没有答案,我会给你全部赏金。再次感谢,+1。
    • @BramVanroy - 在图像上设置的属性用作偏移量的情况下添加一些内容相当容易,然后如果没有属性存在,则回退到自动偏移量,但是当作者插入了一张图片,您如何想象他们会设置这样的属性,他们可以只更改图片的 HTML 还是只使用媒体上传器?新媒体上传器很难修改,因为它是用 ajax 触发的,并且有自己的事件,但这是可能的。如果他们可以直接将属性添加到图像标签,那么很容易做到这一点。
    • 不,作者完全没有网络编码经验。我希望这可以在媒体上传器中完成。可能,可以创建一个“新媒体上传器”字段以允许更多选项。我将对我的主要帖子进行编辑,并勾勒出它在我脑海中的样子。 (将通过评论更新您。)
    • 不完全是我的想法(作者/上传者事先不知道上边距是多少,这就是我创建的小提琴的用途)。但也许我会弄明白的,再次感谢。
    【解决方案2】:

    我正在我的 Intranet 应用程序中使用类似的东西。基本上,我在 jquery 中编写了一个脚本,允许裁剪扫描的图像,因此您可以只保存您感兴趣的部分。

    首先,由于我不擅长 WordPress 插件编程,我可以这样建议的是,如果可能,您实际上不会裁剪图像。您可以改为抵消它。因此,当您保存移动图像中的数据时,您只保存基于初始位置的偏移量。在这种情况下,原始图像会保留下来,并且您可以使用裁剪参数来偏移图像(例如,将其顶部移动 100 像素,顶部:-100 像素)。

    如果你真的需要裁剪图像,你可以使用 imagemagick 来完成(我在我的应用程序中就是这样做的),但它会包括编辑 WordPress 代码,我帮不上什么忙。

    希望我至少能帮上一点忙。

    【讨论】:

    • 保存偏移量是一个更好的主意!谢谢你。不幸的是,我完全不知道如何保存和使用这些值。
    • 好吧,假设图像有 id #image,你可以在页面加载时获得 $("#image").top() 和 $("#image").top() 在保存,然后比较这两个值。或者您也可以在页面加载时尝试使用 $("#image").offset().top 并在保存时使用相同的变量,然后比较它们。然后将保存的偏移量用作 margin-top: -offsetpx;或顶部:-offsetpx;在最终图像中,取决于您的结构。
    • 不,我知道那部分是如何工作的。我的意思是编写 Wordpress 插件/保存数据并在以后重新使用它是我没有任何经验的事情。
    • 好吧,我最好的选择是有一个隐藏字段,该字段将填充偏移值,然后跟踪 WordPress 保存表单的位置并将该列添加到数据库中。就写插件而言,我真的帮不了你。
    • 没问题。我将等待其他一些可能的答案。无论如何都要为这个好主意 +1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多