
Previous posting:
@morning/steemit-com-ui-ux-suggestions
I have mentioned some Fancy Upvote Effect and here it is.
http://coin-on.com:20000
No dependency.
Raw JavaScript and CSS3 used only.
To recap, some level-up feeling UX can be done in this way.
Full source below
/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Steemit Upvote Effect</title>
<link href="css/steemit.css" rel="stylesheet">
<script>
// Library
function $(fn) {
if (document.readyState != 'loading'){
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
function addClass(el, className) {
if (el.classList)
el.classList.add(className);
else
el.className += ' ' + className;
}
function removeClass(el, className) {
if (el.classList)
el.classList.remove(className);
else
el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
function hasClass(el, className) {
if (el.classList)
return el.classList.contains(className);
else
return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
}
function createDiv(classes) {
var div = document.createElement('div');
classes.forEach(function(c) {
addClass(div, c);
});
return div;
}
function appendChildren(parent, children) {
children.forEach(function (child) {
parent.appendChild(child);
});
}
function removeChildren(parent, children) {
children.forEach(function (child) {
parent.removeChild(child);
});
}
// Vote function
function vote() {
var t = this;
var p = t.parentNode;
var inner = p.parentNode;
var c = inner.querySelectorAll('.count')[0];
if (hasClass(t, 'votingUp')) return;
if (hasClass(t, 'Voting__button--upvoted')) return;
addClass(t, 'votingUp');
setTimeout(function() {
removeClass(t, 'votingUp');
addClass(t, 'Voting__button--upvoted');
// Update Vote Count Number
var voteCount = parseInt(c.textContent) + 1;
c.innerHTML = voteCount;
var booster1 = createDiv(['booster', 'red']);
var booster2 = createDiv(['booster', 'blue']);
var booster3 = createDiv(['booster', 'green']);
var booster4 = createDiv(['booster', 'yellow']);
var booster5 = createDiv(['booster', 'orange']);
var booster6 = createDiv(['booster', 'pink']);
appendChildren(p, [booster1, booster2, booster3, booster4, booster5, booster6]);
setTimeout(function() {
removeChildren(p, [booster1, booster2, booster3, booster4, booster5, booster6]);
}, 1000);
}, 1000);
}
// Reset vote status
function reset1() {
var a = document.querySelectorAll('.sample1 a');
removeClass(a[0], 'Voting__button--upvoted');
}
function reset2() {
var a = document.querySelectorAll('.sample2 a');
removeClass(a[0], 'Voting__button--upvoted');
}
function reset3() {
var a = document.querySelectorAll('.sample3 a');
removeClass(a[0], 'Voting__button--upvoted');
}
function reset4() {
var a = document.querySelectorAll('.sample4 a');
removeClass(a[0], 'Voting__button--upvoted');
}
function reset5() {
var a = document.querySelectorAll('.sample5 a');
removeClass(a[0], 'Voting__button--upvoted');
}
function reset6() {
var a = document.querySelectorAll('.sample6 a');
removeClass(a[0], 'Voting__button--upvoted');
}
$(function() {
// Get Vote button elements
var a = document.querySelectorAll('.Voting__button a');
// Click Event Handler for all Vote buttons
var i = a.length;
while(i--) {
a[i].addEventListener('click', vote);
}
});
</script>
</head>
<body>
<section>
<span class="Voting sample1">
<span class="Voting__inner">
<span class="Voting__button Voting__button-up">
<a href="#" title="Upvote">
<span class="Icon chevron-up-circle">
<svg enable-background="new 0 0 33 33" version="1.1" viewBox="0 0 33 33" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Chevron_Up_Circle">
<circle cx="16" cy="16" r="15" fill="none"></circle>
<path d="M16.699,11.293c-0.384-0.38-1.044-0.381-1.429,0l-6.999,6.899c-0.394,0.391-0.394,1.024,0,1.414 c0.395,0.391,1.034,0.391,1.429,0l6.285-6.195l6.285,6.196c0.394,0.391,1.034,0.391,1.429,0c0.394-0.391,0.394-1.024,0-1.414 L16.699,11.293z" fill="#8a8a8a"></path>
</g>
</svg>
</span>
</a>
</span>
<div class="count">1</div>
</span>
</span>
<div class="description">No Effect</div>
<div class="action"><button onclick="reset1()">Reset</button>div>
</section>
<section>
<span class="Voting sample2">
<span class="Voting__inner">
<span class="Voting__button Voting__button-up">
<a href="#" title="Upvote">
<span class="Icon chevron-up-circle">
<svg enable-background="new 0 0 33 33" version="1.1" viewBox="0 0 33 33" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Chevron_Up_Circle">
<circle cx="16" cy="16" r="15" fill="none"></circle>
<path d="M16.699,11.293c-0.384-0.38-1.044-0.381-1.429,0l-6.999,6.899c-0.394,0.391-0.394,1.024,0,1.414 c0.395,0.391,1.034,0.391,1.429,0l6.285-6.195l6.285,6.196c0.394,0.391,1.034,0.391,1.429,0c0.394-0.391,0.394-1.024,0-1.414 L16.699,11.293z" fill="#8a8a8a"></path>
</g>
</svg>
</span>
</a>
</span>
<div class="count">2</div>
</span>
</span>
<div class="description">Minimal for Dusts</div>
<div class="action"><button onclick="reset2()">Reset</button>div>
</section>
<section>
<span class="Voting sample3">
<span class="Voting__inner">
<span class="Voting__button Voting__button-up">
<a href="#" title="Upvote">
<span class="Icon chevron-up-circle">
<svg enable-background="new 0 0 33 33" version="1.1" viewBox="0 0 33 33" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Chevron_Up_Circle">
<circle cx="16" cy="16" r="15" fill="none"></circle>
<path d="M16.699,11.293c-0.384-0.38-1.044-0.381-1.429,0l-6.999,6.899c-0.394,0.391-0.394,1.024,0,1.414 c0.395,0.391,1.034,0.391,1.429,0l6.285-6.195l6.285,6.196c0.394,0.391,1.034,0.391,1.429,0c0.394-0.391,0.394-1.024,0-1.414 L16.699,11.293z" fill="#8a8a8a"></path>
</g>
</svg>
</span>
</a>
</span>
<div class="count">3</div>
</span>
</span>
<div class="description">A little more dynamic for Newbies</div>
<div class="action"><button onclick="reset3()">Reset</button>div>
</section>
<section>
<span class="Voting sample4">
<span class="Voting__inner">
<span class="Voting__button Voting__button-up">
<a href="#" title="Upvote">
<span class="Icon chevron-up-circle">
<svg enable-background="new 0 0 33 33" version="1.1" viewBox="0 0 33 33" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Chevron_Up_Circle">
<circle cx="16" cy="16" r="15" fill="none"></circle>
<path d="M16.699,11.293c-0.384-0.38-1.044-0.381-1.429,0l-6.999,6.899c-0.394,0.391-0.394,1.024,0,1.414 c0.395,0.391,1.034,0.391,1.429,0l6.285-6.195l6.285,6.196c0.394,0.391,1.034,0.391,1.429,0c0.394-0.391,0.394-1.024,0-1.414 L16.699,11.293z" fill="#8a8a8a"></path>
</g>
</svg>
</span>
</a>
</span>
<div class="count">4</div>
</span>
</span>
<div class="description">Fancier for Users</div>
<div class="action"><button onclick="reset4()">Reset</button>div>
</section>
<section>
<span class="Voting sample5">
<span class="Voting__inner">
<span class="Voting__button Voting__button-up">
<a href="#" title="Upvote">
<span class="Icon chevron-up-circle">
<svg enable-background="new 0 0 33 33" version="1.1" viewBox="0 0 33 33" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Chevron_Up_Circle">
<circle cx="16" cy="16" r="15" fill="none"></circle>
<path d="M16.699,11.293c-0.384-0.38-1.044-0.381-1.429,0l-6.999,6.899c-0.394,0.391-0.394,1.024,0,1.414 c0.395,0.391,1.034,0.391,1.429,0l6.285-6.195l6.285,6.196c0.394,0.391,1.034,0.391,1.429,0c0.394-0.391,0.394-1.024,0-1.414 L16.699,11.293z" fill="#8a8a8a"></path>
</g>
</svg>
</span>
</a>
</span>
<div class="count">5</div>
</span>
</span>
<div class="description">Superusers</div>
<div class="action"><button onclick="reset5()">Reset</button>div>
<section>
<span class="Voting sample6">
<span class="Voting__inner">
<span class="Voting__button Voting__button-up">
<a href="#" title="Upvote">
<span class="Icon chevron-up-circle">
<svg enable-background="new 0 0 33 33" version="1.1" viewBox="0 0 33 33" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Chevron_Up_Circle">
<circle cx="16" cy="16" r="15" fill="none"></circle>
<path d="M16.699,11.293c-0.384-0.38-1.044-0.381-1.429,0l-6.999,6.899c-0.394,0.391-0.394,1.024,0,1.414 c0.395,0.391,1.034,0.391,1.429,0l6.285-6.195l6.285,6.196c0.394,0.391,1.034,0.391,1.429,0c0.394-0.391,0.394-1.024,0-1.414 L16.699,11.293z" fill="#8a8a8a"></path>
</g>
</svg>
</span>
</a>
</span>
<div class="count">6</div>
</span>
</span>
<div class="description">Heroes</div>
<div class="action"><button onclick="reset6()">Reset</button>div>
</section>
</body>
</html>
/css/steemit.css
section{display:block;width:100%;float:left;}
.description{padding:22px;display:inline-block;}
.action{float:right;padding:20px;display:inline-block}
.Voting{padding:20px;float:left;}
.Voting__button{float:left;margin-right:5px;position:relative;}
.Voting a{float:left;color:#8a8a8a;}
.Voting a:hover{color:#333;}
.Voting__button circle, .Voting__button path{stroke:#8a8a8a;}
.Voting__button circle.booster{stroke:none;display:none;}
.Voting__button a:hover circle, .Voting__button a:hover path{stroke:#333;}
.Icon {display: inline-block; float:left;width: 25px; height: 25px;}
.count{display: inline-block;font-size:15px;padding:4px 0;color:#8a8a8a;}
.votingUp svg {
border: 1px solid #4BA2F2;
border-radius: 50%;
border-right-color: transparent;
border-top-color: transparent;
animation: loading 500ms infinite linear;
}
.votingUp circle, .votingUp path {
display:none;
}
.Voting__button--upvoted path {fill: #fff;stroke: transparent}
.Voting__button--upvoted circle {fill: #4BA2F2;stroke: transparent;}
.Voting__button a.Voting__button--upvoted:hover circle,
.Voting__button a.Voting__button--upvoted:hover path{stroke:transparent}
@keyframes loading {
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
.booster{display:none}
.sample2 .Voting__button--upvoted path {
animation: up 1000ms 1 ease-out;
}
@keyframes up {
0% {transform: none;opacity:1;}
20% {transform: translateY(-5px);opacity:0;}
30% {transform: translateY(5px);opacity:0;}
60% {transform: none;opacity:1;}
}
.sample3 .Voting__button--upvoted {
animation: newbie 1000ms 1 ease-out;
}
.sample3 .booster{
display:block;
position:absolute;
width:4px;
height:4px;
border-radius: 50%;
left:50%;
margin-left:-4px;
}
.sample3 .red { animation: newbieBooster1 1000ms 1 ease-out; background:#4BA2F2; transform:rotate(40deg) translateY(30px);}
.sample3 .blue { animation: newbieBooster2 1000ms 1 ease-out; background:#4BA2F2;transform:rotate(20deg) translateY(30px);}
.sample3 .green { animation: newbieBooster3 1000ms 1 ease-out; background:#4BA2F2;transform:rotate(0deg) translateY(30px);}
.sample3 .yellow { animation: newbieBooster4 1000ms 1 ease-out; background:#4BA2F2;transform:rotate(-20deg) translateY(30px);}
.sample3 .orange { animation: newbieBooster5 1000ms 1 ease-out; background:#4BA2F2;transform:rotate(-40deg) translateY(30px);}
@keyframes newbie {
0% {transform: none;}
20% {transform: translateY(-10%);}
40% {transform: translateY(0%);}
}
@keyframes newbieBooster1{
0% {transform: rotate(40deg) translateY(30px) scale(0.5);}
60% {transform: rotate(40deg) translateY(35px) scale(1);opacity:0;}
100% {opacity:0;}
}
@keyframes newbieBooster2{
0% {transform: rotate(20deg) translateY(30px) scale(0.5);}
60% {transform: rotate(20deg) translateY(35px) scale(1);opacity:0;}
100% {opacity:0;}
}
@keyframes newbieBooster3{
0% {transform: rotate(0deg) translateY(30px) scale(0.5);}
60% {transform: rotate(0deg) translateY(35px) scale(1);opacity:0;}
100% {opacity:0;}
}
@keyframes newbieBooster4{
0% {transform: rotate(-20deg) translateY(30px) scale(0.5);}
60% {transform: rotate(-20deg) translateY(35px) scale(1);opacity:0;}
100% {opacity:0;}
}
@keyframes newbieBooster5{
0% {transform: rotate(-40deg) translateY(30px) scale(0.5);}
60% {transform: rotate(-40deg) translateY(35px) scale(1);opacity:0;}
100% {opacity:0;}
}
.sample4 .Voting__button--upvoted {
animation: user 1000ms 1 ease-out;
}
.sample4 .booster{display:block;position:absolute;width:6px;height:6px;border-radius: 50%; left:50%;margin-left:-4px;}
.sample4 .red { animation: userBooster1 1000ms 1 ease-out; background:#4BA2F2; transform:rotate(40deg) translateY(30px);}
.sample4 .blue { animation: userBooster2 1000ms 1 ease-out; background:#e83434;transform:rotate(20deg) translateY(30px);}
.sample4 .green { animation: userBooster3 1000ms 1 ease-out; background:#a5bc37;transform:rotate(0deg) translateY(30px);}
.sample4 .yellow { animation: userBooster4 1000ms 1 ease-out; background:#e89116;transform:rotate(-20deg) translateY(30px);}
.sample4 .orange { animation: userBooster5 1000ms 1 ease-out; background:#a366e1;transform:rotate(-40deg) translateY(30px);}
@keyframes user {
0% {transform: none;}
10% {transform: translateY(-2px);}
40% {transform: translateY(0px);}
}
@keyframes userBooster1{
0% {transform: rotate(40deg) translateY(30px) scale(1);}
80% {transform: rotate(40deg) translateY(40px) scale(1.2);opacity:0;}
100% {opacity:0;}
}
@keyframes userBooster2{
0% {transform: rotate(20deg) translateY(30px) scale(1);}
80% {transform: rotate(20deg) translateY(40px) scale(1.2);opacity:0;}
100% {opacity:0;}
}
@keyframes userBooster3{
0% {transform: rotate(0deg) translateY(30px) scale(1);}
80% {transform: rotate(0deg) translateY(40px) scale(1.2);opacity:0;}
100% {opacity:0;}
}
@keyframes userBooster4{
0% {transform: rotate(-20deg) translateY(30px) scale(1);}
80% {transform: rotate(-20deg) translateY(40px) scale(1.2);opacity:0;}
100% {opacity:0;}
}
@keyframes userBooster5{
0% {transform: rotate(-40deg) translateY(30px) scale(1);}
80% {transform: rotate(-40deg) translateY(40px) scale(1.2);opacity:0;}
100% {opacity:0;}
}
.sample5 .Voting__button--upvoted {animation: su 1000ms 1 ease-out; }
.sample5 .booster{display:block;position:absolute;width:6px;height:6px;border-radius: 50%; top:50%;left:50%;margin-top:-3px;margin-left:-4px;}
.sample5 .red { animation: suBooster1 1000ms 1 ease-out; background:#4BA2F2; transform:rotate(40deg) translateY(30px);}
.sample5 .blue { animation: suBooster2 1000ms 1 ease-out; background:#e83434;transform:rotate(20deg) translateY(30px);}
.sample5 .green { animation: suBooster3 1000ms 1 ease-out; background:#a5bc37;transform:rotate(0deg) translateY(30px);}
.sample5 .yellow { animation: suBooster4 1000ms 1 ease-out; background:#e89116;transform:rotate(-20deg) translateY(30px);}
.sample5 .orange { animation: suBooster5 1000ms 1 ease-out; background:#a366e1;transform:rotate(-40deg) translateY(30px);}
.sample5 .pink { animation: suBooster6 1000ms 1 ease-out; background:pink;transform:rotate(-60deg) translateY(30px);}
@keyframes su {
0% {transform: none;}
5% {transform: scale(1.1);}
29% {transform: scale(1.1);}
30% {transform: scale(1);}
100% {transform: scale(1);}
}
@keyframes suBooster1{
0% {opacity:0;}
30% {opacity:0;}
31% {opacity:1;transform: rotate(0deg) translateY(10px) scale(1);}
100% {transform: rotate(0deg) translateY(30px) scale(2);opacity:0;}
}
@keyframes suBooster2{
0% {opacity:0;}
30% {opacity:0;}
31% {opacity:1;transform: rotate(60deg) translateY(10px) scale(1);}
100% {transform: rotate(60deg) translateY(30px) scale(2);opacity:0;}
}
@keyframes suBooster3{
0% {opacity:0;}
30% {opacity:0;}
31% {opacity:1;transform: rotate(120deg) translateY(10px) scale(1);}
100% {transform: rotate(120deg) translateY(30px) scale(2);opacity:0;}
}
@keyframes suBooster4{
0% {opacity:0;}
30% {opacity:0;}
31% {opacity:1;transform: rotate(180deg) translateY(10px) scale(1);}
100% {transform: rotate(180deg) translateY(30px) scale(2);opacity:0;}
}
@keyframes suBooster5{
0% {opacity:0;}
30% {opacity:0;}
31% {opacity:1;transform: rotate(240deg) translateY(10px) scale(1);}
100% {transform: rotate(240deg) translateY(30px) scale(2);opacity:0;}
}
@keyframes suBooster6{
0% {opacity:0;}
30% {opacity:0;}
31% {opacity:1;transform: rotate(300deg) translateY(10px) scale(1);}
100% {transform: rotate(300deg) translateY(30px) scale(2);opacity:0;}
}
/* Sample 6 */
.sample6 .Voting__button--upvoted {animation: hero 1000ms 1 ease-out; }
.sample6 .booster{display:block;position:absolute;width:6px;height:6px;border-radius: 50%; top:50%;left:50%;margin-top:-3px;margin-left:-4px;}
.sample6 .red { animation: heroBooster1 1000ms 1 ease-out; background:#4BA2F2; transform:rotate(40deg) translateY(30px);}
.sample6 .blue { animation: heroBooster2 1000ms 1 ease-out; background:#4BA2F2;transform:rotate(20deg) translateY(30px);}
.sample6 .green { animation: heroBooster3 1000ms 1 ease-out; background:#4BA2F2;transform:rotate(0deg) translateY(30px);}
.sample6 .yellow { animation: heroBooster4 1000ms 1 ease-out; background:#4BA2F2;transform:rotate(-20deg) translateY(30px);}
.sample6 .orange { animation: heroBooster5 1000ms 1 ease-out; background:#4BA2F2;transform:rotate(-40deg) translateY(30px);}
.sample6 .pink { animation: heroBooster6 1000ms 1 ease-out; background:#4BA2F2;transform:rotate(-60deg) translateY(30px);}
@keyframes hero {
0% {opacity:0;}
50% {opacity:0;}
80% {opacity:1;}
100% {opacity:1;}
}
@keyframes heroBooster1{
0% {transform: rotate(0deg) translateY(20px) scale(1);}
20% {transform: rotate(120deg) translateY(2px) scale(0.1);}
50% {transform: rotate(120deg) translateY(2px) scale(0.1);background:#4BA2F2;}
90% {opacity:1;}
100% {transform: rotate(120deg) translateY(30px) scale(3);opacity:0;background:#4BA2F2;}
}
@keyframes heroBooster2{
0% {transform: rotate(60deg) translateY(20px) scale(1);}
20% {transform: rotate(180deg) translateY(2px) scale(0.1);}
50% {transform: rotate(180deg) translateY(2px) scale(0.1);background:#4BA2F2;}
90% {opacity:1;}
100% {transform: rotate(180deg) translateY(30px) scale(3);opacity:0;background:#e83434;}
}
@keyframes heroBooster3{
0% {transform: rotate(120deg) translateY(20px) scale(1);}
20% {transform: rotate(240deg) translateY(2px) scale(0.1);}
50% {transform: rotate(240deg) translateY(2px) scale(0.1);background:#4BA2F2;}
90% {opacity:1;}
100% {transform: rotate(240deg) translateY(30px) scale(3);opacity:0;background:#a5bc37;}
}
@keyframes heroBooster4{
0% {transform: rotate(180deg) translateY(20px) scale(1);}
20% {transform: rotate(300deg) translateY(2px) scale(0.1);}
50% {transform: rotate(300deg) translateY(2px) scale(0.1);background:#4BA2F2;}
90% {opacity:1;}
100% {transform: rotate(300deg) translateY(30px) scale(3);opacity:0;background:#e89116;}
}
@keyframes heroBooster5{
0% {transform: rotate(240deg) translateY(20px) scale(1);}
20% {transform: rotate(360deg) translateY(2px) scale(0.1);}
50% {transform: rotate(360deg) translateY(2px) scale(0.1);background:#4BA2F2;}
90% {opacity:1;}
100% {transform: rotate(360deg) translateY(30px) scale(3);opacity:0;background:#a366e1;}
}
@keyframes heroBooster6{
0% {transform: rotate(300deg) translateY(20px) scale(1);}
20% {transform: rotate(420deg) translateY(2px) scale(0.1);}
50% {transform: rotate(420deg) translateY(2px) scale(0.1);background:#4BA2F2;}
90% {opacity:1;}
100% {transform: rotate(420deg) translateY(30px) scale(3);opacity:0;background:pink;}
}
Edit: I wrote this for Steemit commumity. Permission to use, copy, modify, and/or distribute this code for any purpose with or without fee is hereby granted to any Steemian.