由于做的一个页面需要根据用户评分的不同,显示对应的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,仅供参考与交流!