[技術博客]簡單好用的星級評價和圖片裁剪插件

[技術博客]簡單好用的星級評價和圖片裁剪插件

在前端的編寫中,每每須要使用到某些功能,但這些功能本身來寫又過於複雜,所以使用插件是一個很是簡單又實用的選擇,這裏就推薦兩個JS插件,一個是用於星級評價,另外一個用於圖片的裁剪。javascript

星級評價插件——jquery.raty.js

簡介

項目地址css

看到它的名字就知道,這個插件是基於JQuery的一個JS插件,所以天然採用JQuery的方式來使用這個函數,他的功能,就是用於星級評價。這個插件就能直接顯示評分,同時也支持點擊來進行打分,很是的簡單。html

1558516749586.png

插件的使用

首先引入JS,裏面的css事實上不引入也不存在問題。前端

在須要顯示評分的地方建立一個元素<div id="id" ></div>,對這個元素直接調用raty()函數便可。下面是其raty()函數全部的功能。java

$("#id").raty({
    cancel:      false                                          // Creates a cancel button to cancel the rating.
    cancelClass: 'raty-cancel'                                  // Name of cancel's class.
    cancelHint:  'Cancel this rating!'                          // The cancel's button hint.
    cancelOff:   'cancel-off.png'                               // Icon used on active cancel.
    cancelOn:    'cancel-on.png'                                // Icon used inactive cancel.
    cancelPlace: 'left'                                         // Cancel's button position.
    click:       undefined                                      // Callback executed on rating click.
    half:        false                                          // Enables half star selection.
    halfShow:    true                                           // Enables half star display.
    hints:       ['bad', 'poor', 'regular', 'good', 'gorgeous'] // Hints used on each star.
    iconRange:   undefined                                      // Object list with position and icon on and off to do a mixed icons.
    mouseout:    undefined                                      // Callback executed on mouseout.
    mouseover:   undefined                                      // Callback executed on mouseover.
    noRatedMsg:  'Not rated yet!'                               // Hint for no rated elements when it's readOnly.
    number:      5                                              // Number of stars that will be presented.
    numberMax:   20                                             // Max of star the option number can creates.
    path:        undefined                                      // A global locate where the icon will be looked.
    precision:   false                                          // Enables the selection of a precision score.
    readOnly:    false                                          // Turns the rating read-only.
    round:       { down: .25, full: .6, up: .76 }               // Included values attributes to do the score round math.
    score:       undefined                                      // Initial rating.
    scoreName:   'score'                                        // Name of the hidden field that holds the score value.
    single:      false                                          // Enables just a single star selection.
    space:       true                                           // Puts space between the icons.
    starHalf:    'star-half.png'                                // The name of the half star image.
    starOff:     'star-off.png'                                 // Name of the star image off.
    starOn:      'star-on.png'                                  // Name of the star image on.
    target:      undefined                                      // Element selector where the score will be displayed.
    targetForma: '{score}'                                      // Template to interpolate the score in.
    targetKeep:  false                                          // If the last rating value will be keeped after mouseout.
    targetScore: undefined                                      // Element selector where the score will be filled, instead of creating a new hidden field (scoreName option).
    targetText:  ''                                             // Default text setted on target.
    targetType:  'hint'                                         // Option to choose if target will receive hint o 'score' type.
    starType:    'img'                                          // Element used to represent a star.
});

事實上,咱們所用到的功能每每不多,而若是屢次調用的話,能夠對它再進行必定程度的封裝,能夠以下所示:jquery

function rank(number, size, id){
    $("#id").raty({
        score:number,                           //評分數目
        starOn:"./resource/star-on.png",        //滿星的圖片的地址
        starOff:"./resource/star-off.png",      //空星的圖片的地址
        starHalf:"./resource/star-half.png",    //半星的圖片的地址
        readOnly:true,                          //只讀
        halfShow:true,                          //顯示半星
        size:size,                              //評分大小
    })
 }

比較重要的一點就是隻讀屬性,爲true時這個星級評價是沒法被更改的,爲false時就能夠靠點擊來選擇分數,進行打分的操做。git

獲取到評分的數目也是很簡單,使用$("#id").raty("getScore")就會返回評分的數字。github

其最終效果:web

只讀的星級評分
能夠修改的的星級評分

圖片裁剪插件——cropper.js

在處理用戶的我的信息時,頭像這一塊比較讓人頭大,頭像最好是要1:1的圖片,顯示起來才美觀,但是不能保障用戶上傳的頭像的比例就是1:1,所以就不得不對上傳的頭像進行裁剪。ajax

簡介

項目地址

這個插件能夠提供對圖片的裁剪以及預覽,能夠設定好裁剪的比例等屬性,還可以顯示出預覽圖,用起來仍是比較簡單的。

插件的使用

這個插件雖然是國人所寫,可是其文檔確是英文,同時也並非很好讀懂,在這篇博客中有較好的介紹。最終在使用時也是採用的別人博客裏所介紹的方法來使用,主要來源於這篇博客。其做者比較好的介紹了使用cropper.js進行裁剪的方法,同時也是採用了Bootstrap的模態框(Modal)來實現裁剪和顯示。

插件的使用主要就是對參數options的處理以及處理裁剪的對象。裁剪的設置就是經過在options中添加衆多參數,來調整裁剪的效果。具體的所有的參數和方法能夠見博客,這裏只介紹幾個重要的。

  • aspectRatio—裁剪框的寬高比:一、16/九、4/3等等。
  • viewMode—cropper裁剪時視圖模式:用於控制裁剪框的範圍,這個值能夠設定爲0-3;
  • preview—預覽圖的class名:咱們要爲預覽圖添加class,並將其加到參數中,就能夠看到預覽圖了。

獲取裁剪的對象時,直接採用$('#image').cropper(‘method'[,para])就能夠獲取或者設置裁剪的圖片。好比在上傳圖片時,就須要採用

$('#photo').cropper('getCroppedCanvas', {
        width: 300,
        height: 300
    })

來獲取到最終裁剪的結果。

在此先附上通過適當修改後的代碼:

HTML:

<button type="button" class="btn btn-default mybtn float-md-none ml-0 ml-md-5" data-toggle="modal" data-target="#changeModal" id="show_modal">上傳頭像</button>

<div class="modal fade" id="changeModal" tabindex="-1" role="dialog" aria-hidden="true">
        <div class="modal-dialog modal-lg">
            <div class="modal-content" >
                <div class="modal-header">
                    <!--模態框的頭部-->
                    <h4 class="modal-title float-md-none">
                        <i class="fa fa-pencil"></i>更換頭像
                    </h4>
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true" id="close_modal">×</button>
                </div>
                <div class="modal-body">
                    <!-- 模態框的中部,用於裁剪並顯示預覽 預覽圖和裁剪圖都是默認隱藏的-->
                    <p class="tip-info text-center">
                        未選擇圖片
                    </p>
                    <!--裁剪圖片的地方-->
                    <div class="img-container" style="display: none">
                        <img src="" alt="" id="photo">
                    </div>
                    <!--圖片預覽的地方-->
                    <div class="img-preview-box" style="display: none">
                        <hr>
                        <span>預覽:</span>
                        <div id="testid" class="img-preview img-preview-md" style="width: 100px;height: 100px;"> 
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <!-- 模態框的底部,用於選擇圖片等-->
                    <div class="container">
                        <label class="btn mybtn col-md-3" for="photoInput">
                            <input type="file" class="sr-only" id="photoInput" accept="image/*">
                                <span>打開圖片</span>
                        </label>
                        <button class="btn mybtn disabled col-md-2 offset-md-4 mb-2" disabled="true" onclick="sendPhoto();">提交</button>
                        <button class="btn mybtn col-md-2 mb-2" aria-hidden="true" data-dismiss="modal">取消</button>
                    </div>
                </div>
            </div>
        </div>
    </div>

JS:

$(function(){
        initCropperInModal($('#photo'),$('#photoInput'),$('#changeModal'));
    });
//進行模態框的初始化
var initCropperInModal = function(img, input, modal){
        var $image = img;
        var $inputImage = input;
        var $modal = modal;
        var options = {
            aspectRatio: 1, // 縱橫比,頭像採用1:1
            viewMode: 2, //cropper的視圖模式
            preview: '.img-preview' // 預覽圖的class名
        };
        // 模態框隱藏後須要保存的數據對象
        var saveData = {};
        var URL = window.URL || window.webkitURL;
        var blobURL;
        $modal.on('shown.bs.modal', function () {
            // 從新建立
            $image.cropper( $.extend(options, {
                ready: function () {
                    // 當剪切界面就緒後,恢復數據
                    if(saveData.canvasData){
                        $image.cropper('setCanvasData', saveData.canvasData);
                        $image.cropper('setCropBoxData', saveData.cropBoxData);
                    }
                }
            }));
        }).on('hidden.bs.modal', function () {
            // 保存相關數據
            saveData.cropBoxData = $image.cropper('getCropBoxData');
            saveData.canvasData = $image.cropper('getCanvasData');
            // 銷燬並將圖片保存在img標籤
            $image.cropper('destroy').attr('src',blobURL);
        });
        if (URL) {
            //檢測用戶上傳了圖片,將圖片顯示到裁剪框中,而後處理相關的內容,如預覽圖和提示語句
            $inputImage.change(function() {
                var files = this.files;
                var file;
                if (!$image.data('cropper')) {
                    return;
                }
                if (files && files.length) {
                    file = files[0];
                    //驗證文件是否爲圖片文件
                    if (/^image\/\w+$/.test(file.type)) {

                        if(blobURL) {
                            URL.revokeObjectURL(blobURL);
                        }
                        blobURL = URL.createObjectURL(file);
                        // 重置cropper,將圖像替換
                        $image.cropper('reset').cropper('replace', blobURL);
                        // 選擇文件後,顯示和隱藏相關內容
                        //bootstrap4取消了.hidden,所以採用JQ的show()和hide()來實現,等同於css中的display屬性
                        $('.img-container').show();
                        $('.img-preview-box').show();
                        $('#changeModal .disabled').removeAttr('disabled').removeClass('disabled');
                        $('#changeModal .tip-info').hide();

                    } else {
                        window.alert('請選擇一個圖像文件!');
                    }
                }
            });
        } else {
            //沒有上傳頭像時是沒法提交的
            $inputImage.prop('disabled', true).addClass('disabled');
        }
    }

這樣,就可以在彈窗中實現預覽圖的加載,並對圖片進行裁剪了,最終的效果圖:

上傳前:

1558525220483.png

上傳並調整了裁剪範圍後:

1558525199120.png

裁剪完後每每須要上傳,這個時候就又須要對裁剪後的圖片進行必定的操做。

var sendPhoto = function(){
    //獲取到圖片的內容,採用toBlob()生成Blob對象,再將Blob對象添加到formData對象中去,最終實現上傳,也能夠採用toDataURL()來獲取BASE64對象,若是服務器支持BASE64的話
    var photo = $('#photo').cropper('getCroppedCanvas', {
        width: 300,
        height: 300
    }).toBlob(function (blob) {
        formData=new FormData();
        formData.append('smfile',blob);
        $.ajax({
            type:"POST",
            url:url,
            data:formData,
            cache: false,
            contentType: false,
            processData: false,
            success: function (data) {
                //do something
            },
            error: function (data) {
                //do something
            }
        });
    });
}

遇到的問題

  • 最後上傳時,getCropperedCanvas裏的長寬就是最終生成的圖片長寬,不能過低,太低會致使裁剪出來的圖片嚴重失真,儘管在預覽圖中看着並不模糊。早期爲了簡單快捷採用了100x100,致使最後頭像很是模糊,低分辨的圖片裁剪後尚可,高分辨率圖片慘不忍睹。若是支持的話,仍是調高一點,300x300的大小還算比較合適。
  • 瀏覽器適配問題,部分瀏覽器可能不支持toBlob()方法,點名Edge瀏覽器,其他瀏覽器暫時不清楚,其解決辦法是再引入一個JS,定義toBlob()方法就能夠了,這裏我採用的是canvas-to-blob,其他部分均不做改動,就能在Edge裏進行圖片的上傳了。
相關文章
相關標籤/搜索