html
head
title='Moe Counter!'
meta(name='viewport', content='width=device-width, initial-scale=1')
link(rel='icon', type='image/png', href='favicon.png')
link(rel='stylesheet', href='https://unpkg.com/normalize.css')
link(rel='stylesheet', href='https://unpkg.com/bamboo.css')
link(rel='stylesheet', href='style.css')
script(async, src='https://www.googletagmanager.com/gtag/js?id=G-2RLWN5JXRL')
script.
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-2RLWN5JXRL');
function _evt_push(type, category, label){
gtag('event', type, {
'event_category' : category,
'event_label' : label
});
}
script(async, src='https://unpkg.com/party-js@2/bundle/party.min.js')
style.
html {
scroll-padding: 50px 0;
}
body
h1#main_title(style='margin-top: 0.5em;')
i Moe Counter!
h3 How to use
p Set a unique id for your counter, replace
code :name
| in the url, That's it!
h5 SVG address
code #{site}/@:name
h5 Img tag
code <img src="#{site}/@:name" alt=":name" />
h5 Markdown
code ![:name](#{site}/@:name)
h5 e.g.
details#themes(style='margin-top: 2em;')
summary#more_theme(onclick='_evt_push("click", "normal", "more_theme")')
h3(style='display: inline-block; margin: 0; cursor: pointer;') More theme✨
p(style='margin: 0;') Just use the query parameters theme
, like this: #{site}/@:name?theme=moebooru
each theme in Object.keys(themeList)
h5 #{theme}
h3 Credits
ul
li
a(href='https://glitch.com/', target='_blank', rel='nofollow') Glitch
li
a(href='https://space.bilibili.com/703007996', target='_blank', title='A-SOUL_Official') A-SOUL
li
a(href='https://github.com/moebooru/moebooru', target='_blank', rel='nofollow') moebooru
li
a(href='javascript:alert("!!! NSFW LINK !!!\\nPlease enter the url manually")') gelbooru.com
| NSFW
li
a(href='https://icons8.com/icon/80355/star', target='_blank', rel='nofollow') Icons8
span
i And all booru site...
h3 Tool
.tool
table
thead
tr
th Param
th Description
th Value
tbody
tr
td
code name
td Unique counter name
td
input#name(type='text', placeholder=':name')
tr
td
code theme
td Select a counter image theme, default is
code moebooru
td
select#theme
option(value="random", selected) * random
each theme in Object.keys(themeList)
tr
td
code padding
td Set the minimum length, between 1-32, default is
code 7
td
input#padding(type='number', value='7', min='1', max='32', step='1', oninput='this.value = this.value.replace(/[^0-9]/g, "")')
tr
td
code offset
td Set the offset pixel value, between -500-500, default is
code 0
td
input#offset(type='number', value='0', min='-500', max='500', step='1', oninput='this.value = this.value.replace(/[^0-9|\-]/g, "")')
tr
td
code scale
td Set the image scale, between 0.1-2, default is
code 1
td
input#scale(type='number', value='1', min='0.1', max='2', step='0.1', oninput='this.value = this.value.replace(/[^0-9|\.]/g, "")')
tr
td
code pixelated
td Enable pixelated mode, Enum 0/1, default is
code 1
td
input#pixelated(type='checkbox', checked, style='margin: .5rem .75rem;')
tr
td
code darkmode
td Enable dark mode, Enum 0/1/auto, default is
code auto
td
select#darkmode(name="darkmode")
option(value="auto", selected) auto
option(value="1") yes
option(value="0") no
button#get(style='margin-bottom: 1em;', onclick='_evt_push("click", "normal", "get_counter")') Generate
div
code#code(style='visibility: hidden; display: inline-block; margin-bottom: 1em;')
img#result(style='display: block;')
p(style='margin-top: 2em;')
a(href='https://github.com/journey-ad/Moe-Counter', target='_blank', onclick='_evt_push("click", "normal", "go_github")') source code
div.back-to-top
script.
(function () {
var btn = document.getElementById('get'),
img = document.getElementById('result'),
code = document.getElementById('code')
btn.addEventListener('click', throttle(function() {
var $name = document.getElementById('name'),
$theme = document.getElementById('theme'),
$padding = document.getElementById('padding'),
$offset = document.getElementById('offset'),
$scale = document.getElementById('scale'),
$pixelated = document.getElementById('pixelated'),
$darkmode = document.getElementById('darkmode')
var name = $name.value ? $name.value.trim() : ''
if(!name) {
alert('Please input counter name.')
return
}
party.confetti(this, { count: party.variation.range(20, 40) });
var params = {
name: $name.value ? $name.value.trim() : '',
theme: $theme.value || 'moebooru',
padding: $padding.value || '7',
offset: $offset.value || '0',
scale: $scale.value || '1',
pixelated: $pixelated.checked ? '1' : '0',
darkmode: $darkmode.value || 'auto',
}
var query = new URLSearchParams(params).toString()
img.src = `#{site}/@${name}?${query}`
code.textContent = img.src
code.style.visibility = 'visible'
img.onload = function() {
img.scrollIntoView({block:'start', behavior: 'smooth'})
}
}, 500))
code.addEventListener('click', function(e) {
e.preventDefault()
e.stopPropagation()
var target = e.target
var range, selection
if (document.body.createTextRange) {
range = document.body.createTextRange()
range.moveToElementText(target)
range.select()
} else if (window.getSelection) {
selection = window.getSelection()
range = document.createRange()
range.selectNodeContents(target)
selection.removeAllRanges()
selection.addRange(range)
}
})
var $main_title = document.querySelector('#main_title i'),
$themes = document.querySelector('#themes'),
$more_theme = document.querySelector('#more_theme')
$main_title.addEventListener('click', throttle(function() {
party.sparkles(document.documentElement, { count: party.variation.range(40, 100) });
}, 1000))
$more_theme.addEventListener('click', function() {
if (!$themes.hasAttribute('open')) {
party.sparkles($more_theme.querySelector('h3'), { count: party.variation.range(20, 40) });
$themes.scrollIntoView({block:'start', behavior: 'smooth'})
}
})
function throttle(fn, threshhold, scope) {
threshhold || (threshhold = 250)
var last
var deferTimer
return function () {
var context = scope || this
var now = +new Date
var args = arguments
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer)
deferTimer = setTimeout(function () {
last = now
fn.apply(context, args)
}, threshhold)
} else {
last = now
fn.apply(context, args)
}
}
}
})();
script.
(function () {
var isShow = false, lock = false;
var btn = document.querySelector('.back-to-top');
window.addEventListener('scroll', function () {
if (lock) return;
if (document.body.scrollTop >= 1000) {
if (!isShow) btn.classList.add('load');
isShow = true;
} else {
if (isShow) {
btn.classList.remove('load');
isShow = false;
}
}
});
btn.addEventListener('click', function () {
lock = true;
btn.classList.add('ani-leave');
window.scrollTo({ top: 0, behavior: 'smooth' });
setTimeout(function () {
btn.classList.remove('ani-leave');
btn.classList.add('leaved');
}, 390);
setTimeout(function () {
btn.classList.add('ending');
}, 120);
setTimeout(function () {
btn.classList.remove('load');
}, 1500);
setTimeout(function () {
lock = false;
isShow = false;
btn.classList.remove('leaved', 'ending');
}, 2000);
});
})();