diff --git a/dist/jquery.star-rating-svg.js b/dist/jquery.star-rating-svg.js index 33571f4..0a2138d 100644 --- a/dist/jquery.star-rating-svg.js +++ b/dist/jquery.star-rating-svg.js @@ -1,5 +1,5 @@ /* - * jQuery StarRatingSvg v1.2.0 + * jQuery StarRatingSvg v1.1.0 * * http://github.com/nashio/star-rating-svg * Author: Ignacio Chavez @@ -7,316 +7,311 @@ * 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: 'orange', - activeColor: 'gold', - ratedColor: 'crimson', - 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 +;(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: 'orange', + activeColor: 'gold', + 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 _readOnly; + 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; + _readOnly = this.$el.data('readonly') || this.settings.readOnly; + + this._state = { + // round to the nearest half + rating: (Math.round(_rating * 2) / 2).toFixed(1), + readOnly: _readOnly + }; + + // 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(); }; - // 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; - - $.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); - - }.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 = '
' + - - this.getLinearGradient(this._uid + '_SVGID_1_', s.emptyColor, s.emptyColor, s.starShape) + - this.getLinearGradient(this._uid + '_SVGID_2_', s.hoverColor, s.hoverColor, s.starShape) + - this.getLinearGradient(this._uid + '_SVGID_3_', s.starGradient.start, s.starGradient.end, s.starShape) + - this.getVectorPath(this._uid, { - starShape: s.starShape, - strokeWidth: s.strokeWidth, - strokeColor: s.strokeColor - } ) + - '
'; - - // 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 '' + - '' + - ''; - }, - - getRoundedVectorPath: function(id, attrs){ - var fullPoints = 'M520.9,336.5c-3.8-11.8-14.2-20.5-26.5-22.2l-140.9-20.5l-63-127.7 c-5.5-11.2-16.8-18.2-29.3-18.2c-12.5,0-23.8,7-29.3,18.2l-63,127.7L28,314.2C15.7,316,5.4,324.7,1.6,336.5S1,361.3,9.9,370 l102,99.4l-24,140.3c-2.1,12.3,2.9,24.6,13,32c5.7,4.2,12.4,6.2,19.2,6.2c5.2,0,10.5-1.2,15.2-3.8l126-66.3l126,66.2 c4.8,2.6,10,3.8,15.2,3.8c6.8,0,13.5-2.1,19.2-6.2c10.1-7.3,15.1-19.7,13-32l-24-140.3l102-99.4 C521.6,361.3,524.8,348.3,520.9,336.5z'; - - return ''; - }, - - getSvgDimensions: function(starShape){ - return (starShape === 'rounded') ? 'width="550px" height="500.2px" viewBox="0 146.8 550 500.2" style="enable-background:new 0 0 550 500.2;' : 'x="0px" y="0px" width="305px" height="305px" viewBox="60 -62 309 309" style="enable-background:new 64 -59 305 305;'; - }, - - getLinearGradient: function(id, startColor, endColor, starShape){ - var height = (starShape === 'rounded') ? 500 : 250; - return ' '; - }, - - executeCallback: function(rating, $el){ - var callback = this.settings.callback; - callback(rating, $el); - } - - }; - - var publicMethods = { - - unload: function() { - var _name = 'plugin_' + pluginName; - var $el = $(this); - var $starSet = $el.data(_name).$stars; - $starSet.off(); - $el.removeData(_name).remove(); - }, - - setRating: function(rating, round) { - var _name = 'plugin_' + pluginName; - var $el = $(this); - var $plugin = $el.data(_name); - if( rating > $plugin.settings.totalStars || rating < 0 ) { return; } - if( round ){ - rating = Math.round(rating); - } - $plugin.applyRating(rating); - }, - - getRating: function() { - var _name = 'plugin_' + pluginName; - var $el = $(this); - var $starSet = $el.data(_name); - return $starSet._state.rating; - }, - - resize: function(newSize) { - var _name = 'plugin_' + pluginName; - var $el = $(this); - var $starSet = $el.data(_name); - var $stars = $starSet.$stars; - - if(newSize <= 1 || newSize > 200) { - console.log('star size out of bounds'); - return; - } - - $stars = Array.prototype.slice.call($stars); - $stars.forEach(function(star){ - $(star).css({ - 'width': newSize + 'px', - 'height': newSize + 'px' + var methods = { + init: function () { + this.renderMarkup(); + this.addListeners(); + this.initRating(); + }, + + addListeners: function () { + if (this._state.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, 'active'); + this._state.rating = index + 1; + }, + + restoreState: function (e) { + var index = this.getIndex(e); + var rating = this._state.rating || -1; + this.paintStars(rating - 1, 'active'); + 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'); + + // 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; + 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; + + $.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); + + }.bind(this)); + }, + + renderMarkup: function () { + var s = this.settings; + var baseUrl = s.baseUrl ? location.href : ''; + + // inject an svg manually to have control over attributes + var star = '
' + + + this.getLinearGradient(this._uid + '_SVGID_1_', s.emptyColor, s.emptyColor, s.starShape) + + this.getLinearGradient(this._uid + '_SVGID_2_', s.hoverColor, s.hoverColor, s.starShape) + + this.getLinearGradient(this._uid + '_SVGID_3_', s.starGradient.start, s.starGradient.end, s.starShape) + + this.getVectorPath(this._uid, { + starShape: s.starShape, + strokeWidth: s.strokeWidth, + strokeColor: s.strokeColor + }) + + '
'; + + // 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 '' + + '' + + ''; + }, + + getRoundedVectorPath: function (id, attrs) { + var fullPoints = 'M520.9,336.5c-3.8-11.8-14.2-20.5-26.5-22.2l-140.9-20.5l-63-127.7 c-5.5-11.2-16.8-18.2-29.3-18.2c-12.5,0-23.8,7-29.3,18.2l-63,127.7L28,314.2C15.7,316,5.4,324.7,1.6,336.5S1,361.3,9.9,370 l102,99.4l-24,140.3c-2.1,12.3,2.9,24.6,13,32c5.7,4.2,12.4,6.2,19.2,6.2c5.2,0,10.5-1.2,15.2-3.8l126-66.3l126,66.2 c4.8,2.6,10,3.8,15.2,3.8c6.8,0,13.5-2.1,19.2-6.2c10.1-7.3,15.1-19.7,13-32l-24-140.3l102-99.4 C521.6,361.3,524.8,348.3,520.9,336.5z'; + + return ''; + }, + + getSvgDimensions: function (starShape) { + return (starShape === 'rounded') ? 'width="550px" height="500.2px" viewBox="0 146.8 550 500.2" style="enable-background:new 0 0 550 500.2;' : 'x="0px" y="0px" width="305px" height="305px" viewBox="60 -62 309 309" style="enable-background:new 64 -59 305 305;'; + }, + + getLinearGradient: function (id, startColor, endColor, starShape) { + var height = (starShape === 'rounded') ? 500 : 250; + return ' '; + }, + + executeCallback: function (rating, $el) { + var callback = this.settings.callback; + callback(rating, $el); + } + + }; + + var publicMethods = { + + unload: function () { + var _name = 'plugin_' + pluginName; + var $el = $(this); + var $starSet = $el.data(_name).$stars; + $starSet.off(); + $el.removeData(_name).remove(); + }, + + setRating: function (rating, round) { + var _name = 'plugin_' + pluginName; + var $el = $(this); + var $plugin = $el.data(_name); + if (rating > $plugin.settings.totalStars || rating < 0) { + return; + } + if (round) { + rating = Math.round(rating); + } + $plugin.applyRating(rating); + }, + + getRating: function () { + var _name = 'plugin_' + pluginName; + var $el = $(this); + var $starSet = $el.data(_name); + return $starSet._state.rating; + }, + + resize: function (newSize) { + var _name = 'plugin_' + pluginName; + var $el = $(this); + var $starSet = $el.data(_name); + var $stars = $starSet.$stars; + + if (newSize <= 1 || newSize > 200) { + console.log('star size out of bounds'); + return; + } + + $stars = Array.prototype.slice.call($stars); + $stars.forEach(function (star) { + $(star).css({ + 'width': newSize + 'px', + 'height': newSize + 'px' + }); + }); + }, + + setReadOnly: function (flag) { + var _name = 'plugin_' + pluginName; + var $el = $(this); + var $plugin = $el.data(_name); + if (flag === true) { + $plugin.$stars.off('mouseover mouseout click'); + } else { + $plugin.settings.readOnly = readOnly; + $plugin.addListeners(); + } + } + + }; + + + // Avoid Plugin.prototype conflicts + $.extend(Plugin.prototype, methods); + + $.fn[pluginName] = function (options) { + + // if options is a public method + if (!$.isPlainObject(options)) { + if (publicMethods.hasOwnProperty(options)) { + return publicMethods[options].apply(this, Array.prototype.slice.call(arguments, 1)); + } else { + $.error('Method ' + options + ' does not exist on ' + pluginName + '.js'); + } + } + + return this.each(function () { + // preventing against multiple instantiations + if (!$.data(this, 'plugin_' + pluginName)) { + $.data(this, 'plugin_' + pluginName, new Plugin(this, options)); + } }); - }); - }, - - setReadOnly: function(flag) { - var _name = 'plugin_' + pluginName; - var $el = $(this); - var $plugin = $el.data(_name); - if(flag === true){ - $plugin.$stars.off('mouseover mouseout click'); - } else { - $plugin.settings.readOnly = false; - $plugin.addListeners(); - } - } - - }; - - - // Avoid Plugin.prototype conflicts - $.extend(Plugin.prototype, methods); - - $.fn[ pluginName ] = function ( options ) { - - // if options is a public method - if( !$.isPlainObject(options) ){ - if( publicMethods.hasOwnProperty(options) ){ - return publicMethods[options].apply(this, Array.prototype.slice.call(arguments, 1)); - } else { - $.error('Method '+ options +' does not exist on ' + pluginName + '.js'); - } - } - - return this.each(function() { - // preventing against multiple instantiations - if ( !$.data( this, 'plugin_' + pluginName ) ) { - $.data( this, 'plugin_' + pluginName, new Plugin( this, options ) ); - } - }); - }; - -})( jQuery, window, document ); + }; + +})(jQuery, window, document);