由於做的一個頁面需要根據用戶評分的不同,顯示對應的star。如果評分是帶有小數部分的的話,star除了顯示對應整數個star,還需要用star部分“亮起”來顯示小數部分(如下圖)。本來頁面是基於BootStrap做的,里面有star icon,可以整個顯示,無論用元素遮蔽還是其他方法,都不能很好的滿足需求。而網絡上現有實現方式使用的是雪碧圖,也就是半顆星亮起時是用圖片展示的。經過思考,就想起了HTML5中的Canvas,使用Canvas畫出star,然后在填充顏色時使用漸變色,應該就可以實現star部分點亮了。
下面就是具體的實現方式,已經把實現封裝成了一個函數,使用時直接傳參調用就行啦。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="author" content="Jeri qcloud.js@gmail.com" /> <title>showRatingStars</title> </head> <body> <canvas width="250" height="40" id="myCanvas"></canvas> <script> /** * showRatingStars 顯示評分星級 * @param {Object} myCanvas 畫布對象 * @param {Number} rating 評分 * @param {Number} counts star個數 * @param {Number} size star大小 * @param {Object} style star樣式 * Example: style = { * borderColor:"#21DEEF", * fillColor:"#21DEEF", * spaceColor:"#FFFFFF" * } * @return none */ function showRatingStars(myCanvas, rating, counts, size, style) { // 檢測rating與star數目是否合適 if (rating > counts) { alert("Please set suitable rating and counts!"); return; } // 檢測大小設置是否合適 if (myCanvas.offsetWidth < size * counts || myCanvas.offsetHeight < size) { alert("Please set suitable size and myCanvas' size!"); return; } var context = myCanvas.getContext('2d'); var xStart = rating * size; var yStart = 0; var xEnd = (Math.ceil(rating) + 1) * size; var yEnd = 0; var radius = size / 2; // 線性漸變,由左至右 var linear = context.createLinearGradient(xStart, yStart, xEnd, yEnd); linear.addColorStop(0, style.fillColor); linear.addColorStop(0.01, style.spaceColor); linear.addColorStop(1, style.spaceColor); context.fillStyle = linear; // star邊框顏色設置 context.strokeStyle = style.borderColor; context.lineWidth = 1; // 繪制star的頂點坐標 var x = radius, y = 0; for (var i = 0; i < counts; i++) { // star繪制 context.beginPath(); var x1 = size * Math.sin(Math.PI / 10); var h1 = size * Math.cos(Math.PI / 10); var x2 = radius; var h2 = radius * Math.tan(Math.PI / 5); context.lineTo(x + x1, y + h1); context.lineTo(x - radius, y + h2); context.lineTo(x + radius, y + h2); context.lineTo(x - x1, y + h1); context.lineTo(x - x1, y + h1); context.lineTo(x, y); context.closePath(); context.stroke(); context.fill(); x = (i + 1.5) * size; y = 0; context.moveTo(x, y); } } // 參數設置與函數調用 var size = 25; var rating = 4.57; var counts = 10; var style = { borderColor: "#21DEEF", fillColor: "#21DEEF", spaceColor: "#FFFFFF" }; var myCanvas = document.getElementById("myCanvas"); showRatingStars(myCanvas, rating, counts, size, style); </script> </body> </html>
運行結果如圖:
注:示例已經進行了簡單測試,是可以正常運行的。但不敢保證是否還有bug,僅供參考與交流!