/* * jQuery StarRatingSvg v1.2.0 * * http://github.com/nashio/star-rating-svg * Author: Ignacio Chavez * hello@ignaciochavez.com * Licensed under MIT */ ;(function ( $, window, document, undefined ) { 'use strict'; // Create the defaults once var pluginName = 'starRating'; var noop = function(){}; var defaults = { totalStars: 5, useFullStars: false, starShape: 'straight', emptyColor: 'lightgray', hoverColor: '#f1c40f', activeColor: '#f1c40f', ratedColor: '#f1c40f', useGradient: true, readOnly: false, disableAfterRate: true, baseUrl: false, starGradient: { start: '#FEF7CD', end: '#FF9511' }, strokeWidth: 4, strokeColor: 'black', initialRating: 0, starSize: 40, callback: noop, onHover: noop, onLeave: noop }; // The actual plugin constructor var Plugin = function( element, options ) { var _rating; var newRating; var roundFn; this.element = element; this.$el = $(element); this.settings = $.extend( {}, defaults, options ); // grab rating if defined on the element _rating = this.$el.data('rating') || this.settings.initialRating; // round to the nearest half roundFn = this.settings.forceRoundUp ? Math.ceil : Math.round; newRating = (roundFn( _rating * 2 ) / 2).toFixed(1); this._state = { rating: newRating }; // create unique id for stars this._uid = Math.floor( Math.random() * 999 ); // override gradient if not used if( !options.starGradient && !this.settings.useGradient ){ this.settings.starGradient.start = this.settings.starGradient.end = this.settings.activeColor; } this._defaults = defaults; this._name = pluginName; this.init(); }; var methods = { init: function () { this.renderMarkup(); this.addListeners(); this.initRating(); }, addListeners: function(){ if( this.settings.readOnly ){ return; } this.$stars.on('mouseover', this.hoverRating.bind(this)); this.$stars.on('mouseout', this.restoreState.bind(this)); this.$stars.on('click', this.handleRating.bind(this)); }, // apply styles to hovered stars hoverRating: function(e){ var index = this.getIndex(e); this.paintStars(index, 'hovered'); this.settings.onHover(index + 1, this._state.rating, this.$el); }, // clicked on a rate, apply style and state handleRating: function(e){ var index = this.getIndex(e); var rating = index + 1; this.applyRating(rating, this.$el); this.executeCallback( rating, this.$el ); if(this.settings.disableAfterRate){ this.$stars.off(); } }, applyRating: function(rating){ var index = rating - 1; // paint selected and remove hovered color this.paintStars(index, 'rated'); this._state.rating = index + 1; this._state.rated = true; }, restoreState: function(e){ var index = this.getIndex(e); var rating = this._state.rating || -1; // determine star color depending on manually rated var colorType = this._state.rated ? 'rated' : 'active'; this.paintStars(rating - 1, colorType); this.settings.onLeave(index + 1, this._state.rating, this.$el); }, getIndex: function(e){ var $target = $(e.currentTarget); var width = $target.width(); var side = $(e.target).attr('data-side'); var minRating = this.settings.minRating; // hovered outside the star, calculate by pixel instead side = (!side) ? this.getOffsetByPixel(e, $target, width) : side; side = (this.settings.useFullStars) ? 'right' : side ; // get index for half or whole star var index = $target.index() - ((side === 'left') ? 0.5 : 0); // pointer is way to the left, rating should be none index = ( index < 0.5 && (e.offsetX < width / 4) ) ? -1 : index; // force minimum rating index = ( minRating && minRating <= this.settings.totalStars && index < minRating ) ? minRating - 1 : index; return index; }, getOffsetByPixel: function(e, $target, width){ var leftX = e.pageX - $target.offset().left; return ( leftX <= (width / 2) && !this.settings.useFullStars) ? 'left' : 'right'; }, initRating: function(){ this.paintStars(this._state.rating - 1, 'active'); }, paintStars: function(endIndex, stateClass){ var $polygonLeft; var $polygonRight; var leftClass; var rightClass; var s = this.settings; $.each(this.$stars, function(index, star){ $polygonLeft = $(star).find('[data-side="left"]'); $polygonRight = $(star).find('[data-side="right"]'); leftClass = rightClass = (index <= endIndex) ? stateClass : 'empty'; // has another half rating, add half star leftClass = ( index - endIndex === 0.5 ) ? stateClass : leftClass; $polygonLeft.attr('class', 'svg-' + leftClass + '-' + this._uid); $polygonRight.attr('class', 'svg-' + rightClass + '-' + this._uid); // get color for level var ratedColorsIndex = endIndex >= 0 ? Math.ceil(endIndex) : 0; var ratedColor; if (s.ratedColors && s.ratedColors.length && s.ratedColors[ratedColorsIndex]) { ratedColor = s.ratedColors[ratedColorsIndex]; } else { ratedColor = this._defaults.ratedColor; } // only override colors in rated stars and when rated number is valid if (stateClass === 'rated' && endIndex > -1) { // limit to painting only to rated stars, and specific case for half star if (index <= Math.ceil(endIndex) || (index < 1 && endIndex < 0)) { $polygonLeft.attr('style', 'fill:'+ratedColor); } if (index <= endIndex) { $polygonRight.attr('style', 'fill:'+ratedColor); } } }.bind(this)); }, renderMarkup: function () { var s = this.settings; var baseUrl = s.baseUrl ? location.href.split('#')[0] : ''; // inject an svg manually to have control over attributes var star = '
'; // inject svg markup var starsMarkup = ''; for( var i = 0; i < s.totalStars; i++){ starsMarkup += star; } this.$el.append(starsMarkup); this.$stars = this.$el.find('.jq-star'); }, getVectorPath: function(id, attrs){ return (attrs.starShape === 'rounded') ? this.getRoundedVectorPath(id, attrs) : this.getSpikeVectorPath(id, attrs); }, getSpikeVectorPath: function(id, attrs){ return '