<div class="stars-container" id="stars-container">
<div data-uniq-token="star1" data-active="false" class='titanic titanic-star'></div>
<div data-uniq-token="star2" data-active="false" class='titanic titanic-star'></div>
<div data-uniq-token="star3" data-active="false" class='titanic titanic-star'></div>
<div data-uniq-token="star4" data-active="false" class='titanic titanic-star'></div>
<div data-uniq-token="star5" data-active="false" class='titanic titanic-star'></div>
</div>
.stars-container {
display: flex;
}
.titanic-star {
width : 50px;
cursor : pointer;
transition : all 0.2s;
color : #f47321;
}
.titanic-star path {
fill : #f47321;
stroke : #f47321;
}
.titanic-star[data-active="true"] path {
}
.titanic-star:hover {
transform : scale(1.1);
}
// eslint-disable-next-line no-unused-vars
var Titanic; // a global library container
//modified fork to run with uniqTokens
(function() {
var startAnimationIndex = 0;
var halfAnimationIndex = 13;
var endAnimationIndex = 27;
// --------- Titanic Item ---------- //
function playOn() {
this.anim.playSegments([startAnimationIndex, halfAnimationIndex], true);
this.state = 1;
}
function playOff() {
this.anim.playSegments([halfAnimationIndex + 1, endAnimationIndex], true);
this.state = 0;
}
function playAll() {
this.anim.playSegments([startAnimationIndex, endAnimationIndex], true);
this.state = 0;
}
function toggle() {
if (this.state === 0) {
this.on();
} else {
this.off();
}
}
var TitanicItem = function(element, token, options, baseURL) {
var self = this;
// props
self.titanicToken = token;
self.uniqToken = options.uniqToken;
self.state = 0;
// eslint-disable-next-line no-undef
self.anim = bodymovin.loadAnimation({
container: element,
renderer: "svg",
loop: false,
autoplay: false,
path: baseURL + token + ".json"
});
// methods
self.on = playOn.bind(self);
self.off = playOff.bind(self);
self.play = playAll.bind(self);
self.toggle = toggle.bind(self);
if (options.click) {
element.addEventListener("click", self.toggle);
}
if (options.hover) {
element.addEventListener("pointerenter", self.toggle);
element.addEventListener("pointerleave", self.toggle);
}
};
// --------- Titanic Library ---------- //
var titanicIcons = [];
var isInitialized = false;
function initialize(options, callback) {
var baseURL = options.baseURL;
document.addEventListener("DOMContentLoaded", function() {
var titanicElements = document.getElementsByClassName("titanic");
var i = titanicElements.length;
while (i) {
var element = titanicElements[--i];
var match = element.className.match(/titanic-([^\s]+)/);
options.uniqToken = element.dataset.uniqToken;
if (match && match.length && match[1]) {
titanicIcons.unshift(
new TitanicItem(element, match[1], options, baseURL)
);
}
}
isInitialized = true;
if (typeof callback === "function") {
callback();
}
});
}
function findItem(token) {
if (!isInitialized) {
return;
}
for (var i = titanicIcons.length - 1; i >= 0; i--) {
if (
titanicIcons[i].titanicToken === token ||
titanicIcons[i].uniqToken === token
) {
return titanicIcons[i];
}
}
}
function applyMethod(itemToken, methodToken) {
var titanicItem = findItem(itemToken);
if (titanicItem && typeof titanicItem[methodToken] === "function") {
titanicItem[methodToken]();
}
}
Titanic = function(options) {
this.options = {
baseURL:
options.baseURL ||
"https://cdn.rawgit.com/icons8/titanic/master/dist/icons/",
hover: options.hover !== undefined ? options.hover : true,
click: options.click !== undefined ? options.click : false
};
var self = this;
initialize(this.options, function() {
self.items = titanicIcons;
self.isInitialized = function() {
return isInitialized;
};
self.on = function(token) {
applyMethod(token, "on");
};
self.off = function(token) {
applyMethod(token, "off");
};
self.play = function(token) {
applyMethod(token, "play");
};
});
};
})();
var titanic = new Titanic({
hover: false, // auto animated on hover (default true)
click: false // auto animated on click/tap (default false)
});
var StarRating = (function() {
var self;
var delay = 100;
function getElementIndex(node) {
var index = 0;
while ((node = node.previousElementSibling)) {
index++;
}
return index;
}
var starRating = function(params) {
this.container = params.container;
this.currentRate = params.rate || -1;
self = this;
this.bindStars();
};
starRating.prototype = {
constructor: starRating,
bindStars: function() {
var stars = this.container.getElementsByClassName("titanic-star");
var that = this;
for (var i = 0, l = stars.length; i < l; ++i) {
stars[i].addEventListener("click", that.rate, false);
}
this.stars = stars;
},
star: function(index) {
return this.stars[index];
},
applyOnRange: function(start, end, func) {
if (func === "on") {
for (var i = start; i <= end; i++) {
self.changeState(i, func);
}
} else {
var i = end;
var reverseIndex = 0;
while (i >= start) {
self.changeState(i, func, reverseIndex);
--i;
++reverseIndex;
}
}
},
changeState: function(index, func, reverseIndex) {
var star = this.stars[index];
var uniqToken = star.dataset.uniqToken;
var indexDelay = typeof reverseIndex !== "undefined"
? reverseIndex
: index;
setTimeout(
function(index, uniqToken, star) {
titanic[func](uniqToken);
star.dataset.active = func === "on" ? "true" : "false";
}.bind(null, index, uniqToken, star),
indexDelay * delay
);
},
rate: function() {
//get el from event listner
var el = this;
var index = getElementIndex(el);
var func;
if (index > self.currentRate) {
var padd = self.currentRate >= -1 ? 1 : 0;
var indexPadd = 0;
//on passe en on tt depuis last index jusqu'a new index
self.applyOnRange(self.currentRate + padd, index, "on");
} else if (index < self.currentRate) {
self.applyOnRange(index, self.currentRate, "off");
indexPadd = -1;
} else if (index === self.currentRate) {
//on fait juste un toggle
if (el.dataset.active === "true") {
self.applyOnRange(index, self.currentRate, "off");
indexPadd = -1;
} else {
self.applyOnRange(index, self.currentRate, "on");
this.currentRate = index;
}
}
self.currentRate = index + indexPadd;
},
getRate: function() {
return this.currentRate + 1;
}
};
return starRating;
})();
new StarRating({ container: document.getElementById("stars-container") });
This Pen doesn't use any external CSS resources.