CLIENT SIDE ICONS LETS FUCKING GOOOO

This commit is contained in:
Colon 2022-05-19 22:30:54 -04:00
parent 862f9d7e11
commit 73bbf64e91
2422 changed files with 16031 additions and 2349 deletions

View file

@ -1,3 +1,9 @@
hi, this is colon from the future.
what the FUCK was wrong with me back then???? seriously this is some of the worst code i've ever seen
welp, here's the readme. but you've been warned,,,
# GDBrowser # GDBrowser
@ -84,9 +90,6 @@ This is where all the backend stuff happens! Yipee!
They're all fairly similar. Fetch something, parse the response, and serve it in a crisp and non-intimidating JSON. This is probably what you came for. They're all fairly similar. Fetch something, parse the response, and serve it in a crisp and non-intimidating JSON. This is probably what you came for.
The odd one out is icon.js, which is for generating GD icons. The code here is horrendous, so apologies in advance. Improvements to it would be greatly appreciated! (and i will love you forever)
@ -126,20 +129,6 @@ XOR.js encrypts/decrypts stuff like GD passwords
The HTML files! Nothing too fancy, since it can all be seen directly from gdbrowser. Note that profile.html and level.html (and some parts of home.html) have [[VARIABLES]] (name, id, etc) replaced by the server when they're sent. The HTML files! Nothing too fancy, since it can all be seen directly from gdbrowser. Note that profile.html and level.html (and some parts of home.html) have [[VARIABLES]] (name, id, etc) replaced by the server when they're sent.
comingsoon.html was used while the site was still in development, I just left it in there as a nice little throwback
## Icons
It's GJ_Gamesheet02 but split into a much more intimidating cluster of a million files. These icons are put together and colored in the monstrosity that is icon.js
| name | description |
|:----:|:-----------:|
|`parseIconPlist.js`| Reads GJ_GameSheet02-uhd.plist and magically transforms it into gameSheet.json. Props to 101arrowz for helping make this |
| `colors.json` | List of the player colors in GD. Fairly straight forward |
| `forms.json` | List of the different icon forms, their ingame filenames, and their index in responses from the GD servers
| `offsets.json` | A bunch of hardcoded offsets. Desperate times call for desperate measures |
## Misc ## Misc
@ -169,15 +158,10 @@ Inevitable misc folder
| `achievementTypes.json` | An object containing different categories of achievements (stars, shards, vault, etc) and how to identify them | | `achievementTypes.json` | An object containing different categories of achievements (stars, shards, vault, etc) and how to identify them |
| `credits.json` | Credits! (shown on the homepage) | | `credits.json` | Credits! (shown on the homepage) |
| `dragscroll.js` | Used on several pages for drag scrolling | | `dragscroll.js` | Used on several pages for drag scrolling |
| `global.js` | Excecuted on most pages. Used for the 'page isn't wide enough' message, back button, icons, and a few other things |
| `music.json` | An array of the official GD tracks (name, artist) | | `music.json` | An array of the official GD tracks (name, artist) |
| `parseAchievementPlist.js` | A script that reads GD's achievement .plist files and converts it into achievements.json |
| `sampleIcons.json` | A pool of icons, one of which will randomly appear when visiting the icon kit. Syntax is [Name, ID, Col1, Col2, Glow] | | `sampleIcons.json` | A pool of icons, one of which will randomly appear when visiting the icon kit. Syntax is [Name, ID, Col1, Col2, Glow] |
| `secretStuff.json` | GJP goes here, needed for level leaderboards. Not included in the repo for obvious reasons | | `secretStuff.json` | GJP goes here, needed for level leaderboards. Not included in the repo for obvious reasons |
| `settings.js` | Tweak small settings here, mainly for local use or GDPS'es |
| `shops.js` | A hardcoded list of all the shop icons in GD |
| `sizecheck.js` | Excecuted on most pages. Used for the 'page isn't wide enough' message, back button, and a few other things |
--- ---

View file

@ -43,7 +43,7 @@ module.exports = async (app, req, res, api, ID, analyze) => {
if (err2 && (foundID || authorData)) { if (err2 && (foundID || authorData)) {
let authorInfo = foundID || authorData.split(":") let authorInfo = foundID || authorData.split(":")
level.author = authorInfo[1] || "-" level.author = authorInfo[1] || "-"
level.accountID = authorInfo[0].includes(",") ? "0" : authorInfo[0] level.accountID = authorInfo[0] && authorInfo[0].includes(",") ? "0" : authorInfo[0]
} }
else if (!err && b2 != '-1') { else if (!err && b2 != '-1') {

View file

@ -1,312 +0,0 @@
const sharp = require('sharp');
const Canvas = require('canvas')
const psd = require('ag-psd')
const fs = require('fs');
const mainPath = `../icons/`
const icons = require('../misc/icons/gameSheet.json');
const colors = require('../misc/icons/colors.json');
const forms = require('../misc/icons/forms.json')
const offsets = require('../misc/icons/offsets.json')
const legOffsets = require('../misc/icons/legOffsets.json')
let canvasSize = 300
let halfCanvas = canvasSize/2
let TRANSPARENT = {r: 0, g: 0, b: 0, alpha: 0}
let cache = {}
let partNames = {
"1": "Primary",
"2": "Secondary",
"3": "UFO Dome",
"glow": "Glow",
"extra": "White",
}
// convert hex to RGB
let hexRegex = /^[A-Fa-f0-9]{6}$/
function hexConvert(hex) { hex = hex.replace('#', ''); return {val: hex, r: '0x' + hex[0] + hex[1] | 0, g: '0x' + hex[2] + hex[3] | 0, b: '0x' + hex[4] + hex[5] | 0}; }
// get path name from icon form and ID
function getIconPath(icon, formName) {
return `${mainPath}${formName}_${icon < 10 ? "0" : ""}${icon}`
}
// get color from param input
function getColor(colInput, defaultCol) {
colInput = String(colInput)
let foundColor = colors[colInput]
if (foundColor) {
foundColor.val = colInput
return foundColor
}
else if (colInput.match(hexRegex)) { // custom hex code
let hexCol = hexConvert(colInput)
colors[colInput.toLowerCase()] = hexCol
return hexCol
}
else if (!foundColor && defaultCol) {
let def = colors[defaultCol]
def.val = defaultCol
return def
}
}
module.exports = async (app, req, res) => {
async function buildIcon(account=[], userCode) {
let form = forms[req.query.form] || forms["icon"]
let iconID = req.query.icon || account[form.index] || 1;
let col1 = getColor(req.query.col1 || account[10], "0")
let col2 = getColor(req.query.col2 || account[11], "3")
let colG = getColor(req.query.colG || req.query.colg)
let colW = getColor(req.query.colW || req.query.colw || req.query.col3)
let useGlow = req.query.glow || account[28] || false;
if (useGlow && ["false", "0"].includes(useGlow)) useGlow = false
if (col1.r == 0 && col1.g == 0 && col1.b == 0 ) useGlow = true
// bit of a hacky solution for glow color but whatev
let glowColor = colG || col2
if (glowColor.r == 0 && glowColor.g == 0 && glowColor.b == 0) glowColor = col1
if (glowColor.r == 0 && glowColor.g == 0 && glowColor.b == 0) glowColor = {r: 255, g: 255, b: 255}
let psdExport = req.query.psd || false
let topless = form.name == "UFO" ? req.query.topless || false : false
let customSize = req.query.size == "auto" ? "auto" : +req.query.size || null
let iconPath = getIconPath(iconID, form.form)
let iconCode = `${form.name}-${iconID}-${col1.val}-${col2.val}-${colG ? colG.val : "x"}-${colW ? colW.val : "x"}-${useGlow ? 1 : 0}`
let cachable = !topless && !customSize && !psdExport
if (cachable && cache[iconCode]) return res.end(cache[iconCode].buffer)
// default to 1 if icon ID does not exist
if (!fs.existsSync(getPartName(1).slice(1))) { // slice 1 from filename since fs reads paths differently
iconID = 1
iconPath = getIconPath(1, form.form)
}
// get path of icon 'part' (1: primary, 2: secondary, 3: ufo top, extra: white, glow: glow, )
function getPartName(part, robotPart) {
let path = iconPath
if (form.legs) path += `_0${robotPart || 1}`
if (!part || part == "1") return `${path}_001.png`
else return `${path}_${part}_001.png`
}
// recolor white parts of icon to specified color
async function recolor(img, col) {
let rawData = await img.raw().toBuffer({resolveWithObject: true})
for (let i=0; i<rawData.data.length; i += 4) { // [R, G, B, A]
if (rawData.data[i + 3] > 0) {
rawData.data[i] = col.r / (255 / rawData.data[i]);
rawData.data[i + 1] = col.g / (255 / rawData.data[i + 1]);
rawData.data[i + 2] = col.b / (255 / rawData.data[i + 2]);
}
}
return sharp(rawData.data, {raw: {width: rawData.info.width, height: rawData.info.height, channels: 4, background: TRANSPARENT}}).png()
}
// color icon part and add to layer list
async function addLayer(part, color, legSection) {
let leg = legSection ? legSection.leg : null
let partName = getPartName(part, leg)
let offsetData = icons[partName.slice(mainPath.length)]
if (!offsetData) return
let { spriteSize, spriteOffset } = offsetData
let builtPart = sharp(partName.slice(1)) // slice 1 from filename since sharp also reads paths differently
if (color) builtPart = await recolor(builtPart, color)
let left = halfCanvas - Math.floor(spriteSize[0] / 2) + spriteOffset[0]
let top = halfCanvas - Math.floor(spriteSize[1] / 2) - spriteOffset[1]
if (legSection) {
left += Math.floor(legSection.xPos)
top -= Math.floor(legSection.yPos)
// if (legSection.darken) builtPart.tint({r: 100, g: 100, b: 100})
if (legSection.rotation) {
builtPart.rotate(legSection.rotation, {background: TRANSPARENT})
if (part == "glow") { left--; top--; }
}
if (legSection.yScale) builtPart.resize({width: spriteSize[0], height: Math.floor(spriteSize[1] * legSection.yScale), fit: "fill"})
if (legSection.xFlip) builtPart.flop()
}
let layerData = {
partName, spriteOffset, spriteSize, leg,
layerName: partNames[part],
behind: legSection && legSection.darken,
isGlow: part == "glow",
input: await builtPart.toBuffer(),
left, top
}
if (legSection) {
if (!legLayers[legSection.leg]) legLayers[legSection.leg] = [layerData]
else legLayers[legSection.leg].push(layerData)
}
else layers.push(layerData)
}
// build all layers of icon segment (col1, col2, glow, extra)
async function buildFullLayer(legSection) {
let hasExtra = fs.existsSync(getPartName("extra", legSection ? legSection.leg : null).slice(1))
if (form.form == "bird" && !topless) await addLayer(3, null, legSection) // ufo top
await addLayer(2, col2, legSection) // secondary color
if (useGlow) await addLayer("glow", glowColor, legSection) // glow
await addLayer(1, col1, legSection) // primary color
if (hasExtra) await addLayer("extra", colW, legSection) // extra
// if (legSection) {
// let foundLeg = legLayers[legSection.leg]
// foundLeg.forEach(x => layers.push(x))
// }
}
let layers = []
let legLayers = []
let legData = form.legs ? legOffsets[form.form] || [] : []
let parentSize = icons[getPartName(1).slice(mainPath.length)].spriteSize
let canvas = sharp({create: {width: canvasSize, height: canvasSize, channels: 4, background: TRANSPARENT}})
// if (legData.length) {
// for (let i=0; i<legData.length; i++) {
// await buildFullLayer(legData[i])
// }
// }
await buildFullLayer()
// if (legData.length) layers = legLayers.flat().filter(x => x).sort((a, b) => !!b.behind - !!a.behind).sort((a, b) => !!b.isGlow - !!a.isGlow)
canvas.composite(layers)
let rawData = await canvas.toBuffer({resolveWithObject: true})
let minX = canvasSize; let maxX = 0;
let minY = canvasSize; let maxY = 0;
for (let i=0; i<rawData.data.length; i += 4) { // [R, G, B, A]
let pixelIndex = i/4
let x = pixelIndex % canvasSize;
let y = Math.floor(pixelIndex / canvasSize);
let alpha = rawData.data[i + 3];
if (alpha > 0) {
if (x < minX) minX = x
if (x > maxX) maxX = x
if (y < minY) minY = y
if (y > maxY) maxY = y
}
}
// need to make a new sharp instance so everything is merged. bit hacky but it works
let dimensions = [maxX - minX, maxY - minY]
if (!psdExport) {
let finalIcon = sharp(rawData.data, {raw: {width: canvasSize, height: canvasSize, channels: 4}})
.extract({left: minX, top: minY, width: dimensions[0], height: dimensions[1]})
if (customSize) {
let isThicc = dimensions[0] > dimensions[1]
let squareSize = req.query.size == "auto" ? (isThicc ? dimensions[0] : dimensions[1]) : Math.floor(req.query.size)
if (squareSize < 32) squareSize = 32
if (squareSize > 256) squareSize = 256
// use longest side to make square
if (isThicc) finalIcon.resize({
width: dimensions[isThicc ? 0 : 1],
height: dimensions[isThicc ? 0 : 1],
fit: "contain",
background: TRANSPARENT
})
finalIcon.resize({width: squareSize, height: squareSize, fit: "contain", background: TRANSPARENT})
}
finalIcon.png().toBuffer().then(x => {
res.end(x) // send file
if (cachable) { // cache for a bit
cache[iconCode] = { buffer: x, timeoutID: setTimeout(function() {delete cache[iconCode]}, 10000000) } // cache file for 3 hours
if (userCode) cache[userCode] = { buffer: x, timeoutID: setTimeout(function() {delete cache[userCode]}, 300000) } // 5 min cache for player icons
}
})
}
else {
let psdLayers = layers.map(x => {
let Image = Canvas.Image
let canvas = Canvas.createCanvas(...dimensions)
let ctx = canvas.getContext('2d');
const img = new Image()
img.onload = () => {
ctx.drawImage(img, 0 + x.left - minX, 0 + x.top - minY)
}
img.onerror = err => { throw err }
img.src = x.input
return {name: x.layerName, canvas, leg: x.leg}
})
if (form.legs) {
let legLayers = []
for (let i=1; i<=form.legs + 1; i++) legLayers.push({name: i == 1 ? "Base" : `Leg ${i}`, opened: true, children: []})
psdLayers.forEach(x => {
legLayers[x.leg-1].children.push(x)
})
psdLayers = legLayers.reverse()
}
const photoshop = {
width: dimensions[0],
height: dimensions[1],
children: psdLayers
};
const buffer = psd.writePsdBuffer(photoshop);
return res.end(buffer)
}
}
// ==================================== //
// OLD CODE IS BEING USED FOR ROBOTS AND SPIDERS
let formCheck = forms[req.query.form]
if (formCheck && formCheck.legs) return app.run.icon_old(app, req, res)
let username = req.params.text
let userCode;
res.contentType('image/png');
if (req.offline || req.query.hasOwnProperty("noUser") || req.query.hasOwnProperty("nouser") || username == "icon") return buildIcon()
else if (app.config.cachePlayerIcons && !Object.keys(req.query).filter(x => !["form", "forceGD"].includes(x)).length) {
userCode = `${req.id}u-${username.toLowerCase()}-${forms[req.query.form] ? req.query.form : 'cube'}`
if (cache[userCode]) return res.end(cache[userCode].value)
}
let accountMode = !req.query.hasOwnProperty("player") && Number(req.params.id)
let foundID = app.userCache(req.id, username)
let skipRequest = accountMode || foundID
let forceGD = req.query.hasOwnProperty("forceGD")
// skip request by causing fake error lmao
req.gdRequest(skipRequest ? "" : 'getGJUsers20', skipRequest ? {} : req.gdParams({ str: username, forceGD }, !forceGD), function (err1, res1, body1) {
let result = foundID ? foundID[0] : (accountMode || err1) ? username : app.parseResponse(body1)[16];
req.gdRequest('getGJUserInfo20', req.gdParams({ targetAccountID: result, forceGD }, !forceGD), function (err2, res2, body2) {
if (err2) return buildIcon();
let iconData = app.parseResponse(body2)
if (!foundID && !forceGD) app.userCache(req.id, iconData[16], iconData[2], iconData[1])
return buildIcon(iconData, userCode);
})
});
}

View file

@ -1,392 +0,0 @@
// this file is a potential candidate for worst code on github
// i advise you to turn back now
// seriously, it's not too late
// update: there is now a new system being used for icons, however, spiders and robots do not work
// this old code is being used in the meantime
const Jimp = require('jimp');
const fs = require('fs');
const icons = require('../misc/icons/gameSheet.json');
const colors = require('../misc/icons/colors.json');
const forms = require('../misc/icons/forms.json')
const offsets = require('../misc/icons/offsets.json');
let hexRegex = /^[A-Fa-f0-9]{6}$/
function hexConvert(hex) { hex = hex.replace('#', ''); return {r: '0x' + hex[0] + hex[1] | 0, g: '0x' + hex[2] + hex[3] | 0, b: '0x' + hex[4] + hex[5] | 0}; }
function recolor(img, col) {
return img.scan(0, 0, img.bitmap.width, img.bitmap.height, function (x, y, idx) {
if (img.bitmap.data.slice(idx, idx+3).every(function(val) {return val >= 20 && val <= 255})) { // If it's not "black, i.e. we want to recolor it"
this.bitmap.data[idx] = colors[col].r / (255 / this.bitmap.data[idx]);
this.bitmap.data[idx + 1] = colors[col].g / (255 / this.bitmap.data[idx + 1]);
this.bitmap.data[idx + 2] = colors[col].b / (255 / this.bitmap.data[idx + 2]);
}
})
}
/* Caveat of genFileName is that if there are any falsey values in the arguments they are ignored.
This is usually a good thing though - avoid issues by not putting something like 0 instead of '0' */
function genFileName(...args) { return args.filter(function(val) {return val}).join('_') +'_001.png' }
function fromIcons(filename) { return `./icons/${filename}` }
let cache = {};
module.exports = async (app, req, res) => {
function buildIcon(account=[], usercode) {
let { form, ind } = forms[req.query.form] || {};
form = form || 'player';
ind = ind || 21;
let iconID = req.query.icon || account[ind] || 1;
let col1 = req.query.col1 || account[10] || 0;
let col2 = req.query.col2 || account[11] || 3;
let colG = req.query.colG || req.query.colg
let colW = req.query.colW || req.query.colw || req.query.col3
let outline = req.query.glow || account[28] || "0";
let topless = form == "bird" && req.query.topless
let drawLegs = !(req.query.noLegs > 0)
let autoSize = req.query.size == "auto"
let sizeParam = autoSize || (req.query.size && !isNaN(req.query.size))
if (outline == "0" || outline == "false") outline = false;
if (iconID && iconID.toString().length == 1) iconID = "0" + iconID;
function genImageName(...args) { return genFileName(form, iconID, ...args) }
let icon, glow, extra;
function setBaseIcons() {
icon = genImageName(isSpecial && '01');
glow = genImageName(isSpecial && '01', '2');
extra = genImageName(isSpecial && '01', 'extra');
}
let isSpecial = ['robot', 'spider'].includes(form);
setBaseIcons();
if (!fs.existsSync(fromIcons(icon)) || (isSpecial && !fs.existsSync(fromIcons(genImageName('02'))))) {
iconID = '01';
setBaseIcons();
}
let ex = fromIcons(extra)
let hasExtra = fs.existsSync(ex)
let cols = [col1, col2, colG, colW]
cols.forEach(col => {
if (!col) return
col = col.toString()
if (col.match(hexRegex)) colors[col.toLowerCase()] = hexConvert(col)
})
if (!colors[col1] || isNaN(colors[col1].r)) col1 = colors[+col1] ? +col1 : 0
if (!colors[col2] || isNaN(colors[col2].r)) col2 = colors[+col2] ? +col2 : 3
if (!colors[colG] || isNaN(colors[colG].r)) colG = colors[+colG] ? +colG : null
if (!colors[colW] || isNaN(colors[colW].r)) colW = colors[+colW] ? +colW : null
if (colW && (!hasExtra || colW == 12)) colW = null
if (col1 == 15 || col1 === "000000") outline = true;
let iconCode = `${req.query.form == "cursed" ? "cursed" : form}${topless ? "top" : ""}-${iconID}-${col1}-${col2}-${colG || "x"}-${colW || "x"}-${outline ? 1 : 0}`
if (!sizeParam && (!isSpecial || drawLegs) && cache[iconCode]) return res.end(cache[iconCode].value)
let useExtra = false
let originalOffset = icons[icon].spriteOffset;
let minusOrigOffset = function(x, y) { return x - originalOffset[y] }
let offset = icons[glow].spriteOffset.map(minusOrigOffset);
let robotLeg1, robotLeg2, robotLeg3, robotLeg3b, robotLeg2b, robotLeg1b, robotLeg1c;
let robotOffset1, robotOffset2, robotOffset3, robotOffset1b, robotOffset2b, robotOffset3b;
let robotGlow1, robotGlow2, robotGlow3, glowOffset
let ufoTop, ufoOffset, ufoCoords, ufoSprite
let extrabit, offset2, size2;
if (isSpecial) {
const legs = [1,2,3].map(function(val) {return genImageName(`0${val+1}`)});
const glows = [1,2,3].map(function(val) {return genImageName(`0${val+1}`, '2')});
robotOffset1 = icons[legs[0]].spriteOffset.map(minusOrigOffset).concat(icons[legs[0]].spriteSize);
robotOffset2 = icons[legs[1]].spriteOffset.map(minusOrigOffset).concat(icons[legs[1]].spriteSize);
robotOffset3 = icons[legs[2]].spriteOffset.map(minusOrigOffset).concat(icons[legs[2]].spriteSize);
robotOffset1b = icons[glows[0]].spriteOffset.map(minusOrigOffset).concat(icons[glows[0]].spriteSize);
robotOffset2b = icons[glows[1]].spriteOffset.map(minusOrigOffset).concat(icons[glows[1]].spriteSize);
robotOffset3b = icons[glows[2]].spriteOffset.map(minusOrigOffset).concat(icons[glows[2]].spriteSize);
robotLeg1 = new Jimp(fromIcons(legs[0])); robotGlow1 = new Jimp(fromIcons(glows[0]))
robotLeg2 = new Jimp(fromIcons(legs[1])); robotGlow2 = new Jimp(fromIcons(glows[1]))
robotLeg3 = new Jimp(fromIcons(legs[2])); robotGlow3 = new Jimp(fromIcons(glows[2]))
glowOffset = offsets[form][+iconID] || []
}
Jimp.read(fromIcons(glow)).then(async function (image) {
let size = [image.bitmap.width, image.bitmap.height]
let glow = recolor(image, col2)
let imgOff = isSpecial ? 100 : 0
let eb = fromIcons(extra)
if (fs.existsSync(eb)) {
extrabit = icons[extra]
offset2 = extrabit.spriteOffset.map(minusOrigOffset);
size2 = extrabit.spriteSize;
extra = new Jimp(eb);
if (colW) await Jimp.read(eb).then(e => { extra = recolor(e, colW) })
useExtra = true
}
Jimp.read(fromIcons(icon)).then(async function (ic) {
let iconSize = [ic.bitmap.width, ic.bitmap.height]
recolor(ic, col1)
ic.composite(glow, (iconSize[0] / 2) - (size[0] / 2) + offset[0], (iconSize[1] / 2) - (size[1] / 2) - offset[1], { mode: Jimp.BLEND_DESTINATION_OVER })
if (form == "bird" && !topless) {
ufoTop = genImageName('3')
ufoOffset = icons[ufoTop].spriteOffset.map(minusOrigOffset).concat(icons[ufoTop].spriteSize);
ufoCoords = [imgOff + (iconSize[0] / 2) - (ufoOffset[2] / 2) + ufoOffset[0], (iconSize[1] / 2) - (ufoOffset[3] / 2) - ufoOffset[1] + 300 - iconSize[1]]
ufoSprite = fromIcons(ufoTop)
ic.contain(iconSize[0], 300, Jimp.HORIZONTAL_ALIGN_CENTER | Jimp.VERTICAL_ALIGN_BOTTOM)
// Only add dome if there's no glow, otherwise the dome will be outlined as well
if (!outline) ic.composite(await Jimp.read(ufoSprite), ufoCoords[0], ufoCoords[1], {mode: Jimp.BLEND_DESTINATION_OVER})
}
if (drawLegs && (form == "robot" || req.query.form == "cursed")) {
ic.contain(iconSize[0], 300, Jimp.HORIZONTAL_ALIGN_CENTER | Jimp.VERTICAL_ALIGN_TOP)
ic.contain(iconSize[0] + 200, 300, Jimp.HORIZONTAL_ALIGN_CENTER | Jimp.VERTICAL_ALIGN_TOP)
await Jimp.read(new Jimp(robotGlow1)).then(rob => {
rob.rotate(-45)
robotGlow1 = recolor(rob, col2)
})
await Jimp.read(new Jimp(robotGlow2)).then(rob => {
rob.rotate(45)
robotGlow2 = recolor(rob, col2)
})
await Jimp.read(new Jimp(robotGlow3)).then(rob => {
robotGlow3 = recolor(rob, col2)
})
await Jimp.read(new Jimp(robotLeg1)).then(rob => {
rob.rotate(-45)
recolor(rob, col1)
rob.composite(robotGlow1, (robotOffset1[2] - robotOffset1b[2]) + (glowOffset[0] || 1), ((robotOffset1[3] - robotOffset1b[3]) / 2) + (glowOffset[1] || 0), { mode: Jimp.BLEND_DESTINATION_OVER })
robotLeg1 = rob
})
await Jimp.read(new Jimp(robotLeg2)).then(rob => {
rob.rotate(45)
recolor(rob, col1)
rob.composite(robotGlow2, ((robotOffset2[2] - robotOffset2b[2]) / 4) + (glowOffset[4] || 0), ((robotOffset2[3] - robotOffset2b[3]) / 2) + (glowOffset[5] || 0), { mode: Jimp.BLEND_DESTINATION_OVER })
robotLeg2 = rob
})
await Jimp.read(new Jimp(robotLeg2)).then(rob => {
robotLeg2b = rob.color([{ apply: 'darken', params: [20] }]).rotate(-5)
})
await Jimp.read(new Jimp(robotLeg3)).then(rob => {
recolor(rob, col1)
rob.composite(robotGlow3, ((robotOffset3[2] - robotOffset3b[2]) / 2) + (glowOffset[2] || 0), ((robotOffset3[3] - robotOffset3b[3]) / 2) + (glowOffset[3] || 0), { mode: Jimp.BLEND_DESTINATION_OVER })
robotLeg3 = rob
})
await Jimp.read(new Jimp(robotLeg3)).then(rob => {
robotLeg3b = rob.color([{ apply: 'darken', params: [10] }])
})
ic.composite(robotLeg2b, 100 + (iconSize[0] / 2) - (robotOffset2[2]) + robotOffset2[0] - 31, (iconSize[1] / 2) - (robotOffset2[3]) - robotOffset2[1] + 73)
ic.composite(robotLeg3b, 100 + (iconSize[0] / 2) - (robotOffset3[2]) + robotOffset3[0] + 20, (iconSize[1] / 2) - (robotOffset3[3]) - robotOffset3[1] + 78)
ic.composite(robotLeg2, 100 + (iconSize[0] / 2) - (robotOffset2[2]) + robotOffset2[0] - 20, (iconSize[1] / 2) - (robotOffset2[3]) - robotOffset2[1] + 73)
ic.composite(robotLeg3, 100 + (iconSize[0] / 2) - (robotOffset3[2]) + robotOffset3[0] + 40, (iconSize[1] / 2) - (robotOffset3[3]) - robotOffset3[1] + 78)
ic.composite(robotLeg1, 100 + (iconSize[0] / 2) - (robotOffset1[2]) + robotOffset1[0] - 20, (iconSize[1] / 2) - (robotOffset1[3]) - robotOffset1[1] + 50)
}
else if (drawLegs && form == "spider") {
let spiderBody;
ic.contain(iconSize[0], 300, Jimp.HORIZONTAL_ALIGN_CENTER | Jimp.VERTICAL_ALIGN_TOP)
ic.contain(iconSize[0] + 200, 300, Jimp.HORIZONTAL_ALIGN_CENTER | Jimp.VERTICAL_ALIGN_TOP)
if (iconID == "07") {
robotOffset2[2] -= 10
robotOffset2[1] += 12
robotOffset1b[3] -= 105
robotOffset2b[3] -= 150
robotOffset2b[2] -= 60
}
if (iconID == "16") {
robotOffset1b[3] -= 100
robotOffset2b[3] -= 200
robotOffset2b[2] -= 30
}
await Jimp.read(new Jimp(robotGlow1)).then(rob => {
if (robotGlow1.bitmap.width < 10) robotGlow1.opacity(0)
else robotGlow1 = recolor(rob, col2)
})
await Jimp.read(new Jimp(robotGlow2)).then(rob => {
robotGlow2 = recolor(rob, col2)
})
await Jimp.read(new Jimp(robotGlow3)).then(rob => {
robotGlow3 = recolor(rob, col2)
})
await Jimp.read(new Jimp(robotLeg1)).then(rob => {
recolor(rob, col1)
rob.composite(robotGlow1, ((robotOffset1[2] - robotOffset1b[2]) / 2) + (glowOffset[2] || 0), ((robotOffset1[3] - robotOffset1b[3]) / 4) + (glowOffset[3] || 0), { mode: Jimp.BLEND_DESTINATION_OVER })
robotLeg1 = rob
})
await Jimp.read(new Jimp(robotLeg2)).then(rob => {
recolor(rob, col1)
rob.composite(robotGlow2, ((robotOffset2[2] - robotOffset2b[2]) / 6) + (glowOffset[0] || 0), ((robotOffset2[3] - robotOffset2b[3]) / 6) + (glowOffset[1] || 0), { mode: Jimp.BLEND_DESTINATION_OVER })
rob.rotate(-40)
robotLeg2 = rob
})
await Jimp.read(new Jimp(robotLeg1)).then(rob => {
robotLeg1b = rob.color([{ apply: 'darken', params: [20] }])
})
await Jimp.read(new Jimp(robotLeg1b)).then(rob => {
robotLeg1c = rob.mirror(true, false)
})
await Jimp.read(new Jimp(robotLeg3)).then(rob => {
recolor(rob, col1)
rob.composite(robotGlow3, ((robotOffset3[2] - robotOffset3b[2]) / 2) + (glowOffset[4] || 0), ((robotOffset3[3] - robotOffset3b[3]) / 2) + (glowOffset[5] || 0), { mode: Jimp.BLEND_DESTINATION_OVER })
robotLeg3 = rob
})
await Jimp.read(new Jimp(ic)).then(rob => {
spiderBody = rob
})
ic.composite(robotLeg3, 100 + (iconSize[0] / 2) - (robotOffset3[2]) + (robotOffset3[0]), (iconSize[1] / 2) - (robotOffset2[3]) - robotOffset2[1] + 77)
ic.composite(robotLeg1b, 100 + (iconSize[0] / 2) - (robotOffset1[2]) + robotOffset1[0] + 35, (iconSize[1] / 2) - (robotOffset1[3]) - robotOffset1[1] + 70)
ic.composite(robotLeg1c, 100 + (iconSize[0] / 2) - (robotOffset1[2]) + robotOffset1[0] + 75, (iconSize[1] / 2) - (robotOffset1[3]) - robotOffset1[1] + 70)
// ^ BELOW
ic.composite(spiderBody, 0, 0)
// v ABOVE
ic.composite(robotLeg2, 100 + (iconSize[0] / 2) - (robotOffset2[2]) + robotOffset2[0] - 60, (iconSize[1] / 2) - (robotOffset2[3]) - robotOffset2[1] + 75)
ic.composite(robotLeg1, 100 + (iconSize[0] / 2) - (robotOffset1[2]) + robotOffset1[0] + 7, (iconSize[1] / 2) - (robotOffset1[3]) - robotOffset1[1] + 70)
}
// every now and then jimp does a fucky wucky uwu and this line errors. seems to be an issue with the lib itself :v
try { if (useExtra) ic.composite(extra, imgOff + (iconSize[0] / 2) - (size2[0] / 2) + offset2[0], (iconSize[1] / 2) - (size2[1] / 2) - offset2[1] + (form == "bird" && !req.query.topless ? 300 - iconSize[1] : 0)) }
catch(e) {}
let finalSize = [ic.bitmap.width, ic.bitmap.height]
function finish(img) {
img.autocrop(0.01, false)
if (form == "swing") img.resize(120, 111)
if (img.bitmap.height == 300) ic.autocrop(1, false)
if (sizeParam) {
let thicc = img.bitmap.width > img.bitmap.height
let imgSize = req.query.size == "auto" ? (thicc ? img.bitmap.width : img.bitmap.height) : Math.round(req.query.size)
if (imgSize < 32) imgSize = 32
if (imgSize > 512) imgSize = 512
if (thicc) img.contain(img.bitmap.width, img.bitmap.width, Jimp.HORIZONTAL_ALIGN_CENTER | Jimp.VERTICAL_ALIGN_MIDDLE)
else img.contain(img.bitmap.height, img.bitmap.height, Jimp.HORIZONTAL_ALIGN_CENTER | Jimp.VERTICAL_ALIGN_MIDDLE)
img.resize(imgSize, Jimp.AUTO)
}
img.getBuffer(Jimp.AUTO, (err, buffer) => {
if (!sizeParam && drawLegs) {
cache[iconCode] = { value: buffer, timeoutID: setTimeout(function() {delete cache[iconCode]}, 10000000) } // 3 hour cache
if (usercode) cache[usercode] = { value: buffer, timeoutID: setTimeout(function() {delete cache[usercode]}, 300000) } // 5 min cache for player icons
}
return res.end(buffer, 'base64')
})
}
if (!outline) return finish(ic)
else {
ic.getBuffer(Jimp.AUTO, function (err, buff) {
const Canvas = require('canvas')
, Image = Canvas.Image
, canvas = Canvas.createCanvas(finalSize[0] + 10, finalSize[1] + 10)
, ctx = canvas.getContext('2d');
if (!colG) colG = (col2 == 15 || col2 == "000000" ? col1 : col2)
if (colG == 15 || colG == "000000") colG = 12
const img = new Image()
img.onload = () => {
var dArr = [-1, -1, 0, -1, 1, -1, -1, 0, 1, 0, -1, 1, 0, 1, 1, 1], // offset array
s = 2, i = 0, x = canvas.width / 2 - finalSize[0] / 2, y = canvas.height / 2 - finalSize[1] / 2;
for (; i < dArr.length; i += 2) ctx.drawImage(img, x + dArr[i] * s, y + dArr[i + 1] * s);
ctx.globalCompositeOperation = "source-in";
ctx.fillStyle = `rgba(${colors[colG].r}, ${colors[colG].g}, ${colors[colG].b}, 1})`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "source-over";
ctx.imageSmoothingEnabled = false;
// Add UFO top last so it doesn't get glow'd
if (form == "bird" && !topless) {
const dome = new Image()
dome.src = ufoSprite
ctx.drawImage(dome, ufoCoords[0]+5, ufoCoords[1]+5)
}
ctx.drawImage(img, x, y)
}
img.onerror = err => { throw err }
img.src = buff
Jimp.read(canvas.toBuffer()).then(b => {
return finish(b)
})
})
}
})
})
}
let username = req.params.text
let userCode;
res.contentType('image/png');
if (req.offline || req.query.hasOwnProperty("noUser") || req.query.hasOwnProperty("nouser") || username == "icon") return buildIcon()
else if (app.config.cachePlayerIcons && !Object.keys(req.query).filter(x => !["form", "forceGD"].includes(x)).length) {
userCode = `${req.id}u-${username.toLowerCase()}-${forms[req.query.form] ? req.query.form : 'cube'}`
if (cache[userCode]) return res.end(cache[userCode].value)
}
let accountMode = !req.query.hasOwnProperty("player") && Number(req.params.id)
let foundID = app.userCache(req.id, username)
let skipRequest = accountMode || foundID
let forceGD = req.query.hasOwnProperty("forceGD")
// skip request by causing fake error lmao
req.gdRequest(skipRequest ? "" : 'getGJUsers20', skipRequest ? {} : req.gdParams({ str: username, forceGD }, !forceGD), function (err1, res1, body1) {
let result = foundID ? foundID[0] : (accountMode || err1) ? username : app.parseResponse(body1)[16];
req.gdRequest('getGJUserInfo20', req.gdParams({ targetAccountID: result, forceGD }, !forceGD), function (err2, res2, body2) {
if (err2) return buildIcon();
let iconData = app.parseResponse(body2)
if (!foundID && !forceGD) app.userCache(req.id, iconData[16], iconData[2], iconData[1])
return buildIcon(iconData, userCode);
})
});
}

View file

@ -1,4 +1,4 @@
const colors = require('../../misc/icons/colors.json'); const colors = require('../../iconkit/sacredtexts/colors.json');
module.exports = async (app, req, res) => { module.exports = async (app, req, res) => {

BIN
assets/colU.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -726,10 +726,9 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
.commentPercent { .commentPercent {
vertical-align: top; vertical-align: top;
margin: 0 0 0 1vh; margin: 0 0 0 1.5vh;
font-size: 2vh; font-size: 2vh;
color: rgba(0, 0, 0, 0.5); color: rgba(0, 0, 0, 0.5);
transform: translateY(40%);
} }
.commentLikes { .commentLikes {
@ -743,8 +742,54 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
transform: translateY(-19%) transform: translateY(-19%)
} }
.commentIcon {
margin-right: 1.25%;
width: 3.5%;
}
.commentIcon img {
width: 100%;
}
.commentRow {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}
.creditsIcon {
height: 30%;
margin-bottom: 7%;
}
.creditsIcon img {
height: 100%;
}
.specialThanksIcon img {
width: 42%;
height: unset;
}
.leaderboardSlot { .leaderboardSlot {
height: 25%; height: 25%;
display: flex;
flex-direction: row;
align-items: flex-start;
padding-left: 0%;
width: 100%;
overflow: hidden;
}
.leaderboardName {
margin-right: 2.5%;
}
.leaderboardStars {
display: flex;
flex-direction: row;
align-items: center;
} }
.weeklyStuff { .weeklyStuff {
@ -752,10 +797,38 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
} }
.ranking { .ranking {
transform:scale(0.82) translate(-20.7vh, -20vh); display: flex;
position: absolute; padding-left: 5%;
height: 10%; padding-right: 2%;
width: 12.5%; flex-direction: column;
justify-content: center;
align-items: center;
height: 88%;
width: 10%
}
.ranking h2 {
width: 100%;
margin-top: 2%;
}
.leaderboardIcon {
height: 100%;
display: flex;
align-items: flex-end;
}
.leaderboardIcon img {
height: 80%;
max-width: 150%;
}
.leaderboardSide {
display: flex;
flex-direction: column;
align-items: flex-start;
width: 100%;
margin-top: 0.5%
} }
#collectibles, .leaderboardStats { #collectibles, .leaderboardStats {
@ -769,12 +842,16 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
} }
.leaderboardStats { .leaderboardStats {
display: flex;
margin-top: 2%; margin-top: 2%;
width: 100%;
align-items: center;
} }
.leaderboardStats img { .leaderboardStats img {
transform: translate(-20%, -7%);
width: 4.3%; width: 4.3%;
margin-left: 1%;
margin-right: 2.5%;
} }
#boomling { #boomling {

View file

@ -36,7 +36,7 @@ h1 {
text-shadow: 3px 3px 0.5px rgba(0, 0, 0, 0.3); text-shadow: 3px 3px 0.5px rgba(0, 0, 0, 0.3);
} }
h2 { h2, select, input[type=number] {
font-weight: normal; font-weight: normal;
margin: 0 0; margin: 0 0;
font-size: 35px; font-size: 35px;
@ -89,13 +89,6 @@ input:focus, select:focus, textarea:focus, button:focus {
outline: none; outline: none;
} }
input:not([type='checkbox']), select {
padding: 7 7 7 7;
font-size: 14px;
width: 15%;
border-style: 1px inset black;
}
input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:focus, input:-webkit-autofill:active { input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:focus, input:-webkit-autofill:active {
box-shadow: 0 0 0px 1000px #764F1A inset !important; box-shadow: 0 0 0px 1000px #764F1A inset !important;
-webkit-box-shadow: 0 0 0px 1000px #764F1A inset !important; -webkit-box-shadow: 0 0 0px 1000px #764F1A inset !important;
@ -116,6 +109,18 @@ input:focus, select:focus, textarea:focus, button:focus {
font-family: "Roboto"; font-family: "Roboto";
} }
#iconbox {
display: flex;
max-height: 175px;
justify-content: center;
align-items: flex-start;
}
#result {
object-fit: contain;
z-index: -1;
}
#textbox { #textbox {
text-transform: uppercase; text-transform: uppercase;
font-size: 22px; font-size: 22px;
@ -172,12 +177,6 @@ input:focus, select:focus, textarea:focus, button:focus {
text-transform: capitalize; text-transform: capitalize;
} }
.squareIcon {
background-color: rgba(0, 0, 0, 0.2);
padding: 5px 5px;
border-radius: 10px;
}
#url { #url {
width: 500px; width: 500px;
max-width: 90%; max-width: 90%;
@ -238,7 +237,7 @@ input:focus, select:focus, textarea:focus, button:focus {
#generate { #generate {
font-family: "Roboto"; font-family: "Roboto";
border: transparent; border: rgba(0, 0, 0, 0);
background-color: #88FF33; background-color: #88FF33;
box-shadow: 2px 2px 3px #66AA22; box-shadow: 2px 2px 3px #66AA22;
border-radius: 10px; border-radius: 10px;
@ -259,7 +258,7 @@ input:focus, select:focus, textarea:focus, button:focus {
.miniButton { .miniButton {
font-family: "Roboto"; font-family: "Roboto";
border: transparent; border: rgba(0, 0, 0, 0);
background-color: #88FF33; background-color: #88FF33;
box-shadow: 1.5px 1.5px 2px #66AA22; box-shadow: 1.5px 1.5px 2px #66AA22;
border-radius: 10px; border-radius: 10px;
@ -282,16 +281,36 @@ input:focus, select:focus, textarea:focus, button:focus {
width: 800px; width: 800px;
overflow-x: hidden; overflow-x: hidden;
display: block; display: block;
padding-bottom: 20px; padding-bottom: 10px;
margin: 0 auto 0 auto; margin: 0 auto 0 auto;
background-color: rgba(0, 0, 0, 0.3); background-color: rgba(0, 0, 0, 0.3);
border-radius: 8px; border-radius: 8px;
} }
.iconContainer {
display: flex;
flex-wrap: wrap;
justify-content: center;
padding: 0px 25px;
}
.iconContainer button {
width: 60px;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
}
.iconContainer button img {
width: 50px;
}
.iconKit button, .colTypes button { .iconKit button, .colTypes button {
margin: 0 0 0 0; margin: 0 0 0 0;
padding: 0 0 0 0; padding: 0px 0px;
border: 5px solid transparent; border: 5px solid rgba(0, 0, 0, 0); /* need this for border image to work */
user-select: none;
} }
.iconSelected { .iconSelected {
@ -301,6 +320,11 @@ input:focus, select:focus, textarea:focus, button:focus {
.iconTabButton, .glowToggle, .copyForm { .iconTabButton, .glowToggle, .copyForm {
margin: 0 5 0 5; margin: 0 5 0 5;
transition: transform .1s ease-in-out; transition: transform .1s ease-in-out;
user-select: none;
}
.iconTabButton:focus-visible, .glowToggle:focus-visible, .copyForm:focus-visible, .menuButton:focus-visible, .postButton:focus-visible {
transform: scale(1.1);
} }
.colorPicker { .colorPicker {
@ -342,6 +366,7 @@ input:focus, select:focus, textarea:focus, button:focus {
#colors { #colors {
width: 1000px; width: 1000px;
max-width: 90%;
overflow-x: auto; overflow-x: auto;
padding: 10 10 10 10; padding: 10 10 10 10;
background-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.7);
@ -349,7 +374,7 @@ input:focus, select:focus, textarea:focus, button:focus {
#colors::-webkit-scrollbar, #iconKitParent::-webkit-scrollbar { #colors::-webkit-scrollbar, #iconKitParent::-webkit-scrollbar {
width: 9px; width: 9px;
height: 9px; height: 10px;
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
} }
@ -358,30 +383,35 @@ input:focus, select:focus, textarea:focus, button:focus {
} }
#iconKitParent { #iconKitParent {
min-height: 90px;
max-height: 210px; max-height: 210px;
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5); box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
} }
#iconKitParent div {
margin-top: -5;
}
#colors div { #colors div {
display: flex; display: flex;
} }
.iconColor div {
width: 50px;
height: 50px;
}
#gdfloor { #gdfloor {
margin-bottom: 15px; margin-bottom: 15px;
margin-top: 0px; margin-top: 1px;
border: 0; border: 0;
height: 3px; height: 3px;
width: 80%; width: 80%;
background-image: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)); background-image: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
position: relative;
z-index: -10;
} }
.menuButton { .menuButton {
margin: 0 5 0 5; margin: 0 5 0 5;
transition: transform .15s ease-in-out; transition: transform .15s ease-in-out;
user-select: none;
} }
.menuButton:hover { .menuButton:hover {
@ -394,21 +424,23 @@ input:focus, select:focus, textarea:focus, button:focus {
#iconprogressbar { #iconprogressbar {
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
height: 12px; height: 7px;
margin-bottom: 12px;
} }
#iconloading { #iconloading {
background: rgba(255, 255, 255, 0.5); background: rgba(255, 255, 255, 0.5);
height: 12px; height: 7px;
width: 0%; width: 0%;
} }
.iconScroll::-webkit-scrollbar { body::-webkit-scrollbar {
display: none;
width: 0; width: 0;
background: transparent; background: rgba(0, 0, 0, 0);
} }
.iconHover { .iconHover, .iconButton:focus-visible, .iconColor:focus-visible {
transform: scale(1.075); transform: scale(1.075);
background-color: rgb(255, 255, 255, 0.2); background-color: rgb(255, 255, 255, 0.2);
border-radius: 10px; border-radius: 10px;
@ -425,7 +457,7 @@ input:focus, select:focus, textarea:focus, button:focus {
} }
.brownBox { .brownBox {
border: 17px solid transparent; border: 17px solid rgba(0, 0, 0, 0);
border-radius: 25px; border-radius: 25px;
background-color: #995533; background-color: #995533;
border-image: url('../../assets/brownbox.png') 10% round; border-image: url('../../assets/brownbox.png') 10% round;
@ -446,7 +478,7 @@ input[type=text] {
color: white; color: white;
letter-spacing: 0.02em; letter-spacing: 0.02em;
text-shadow: -0.2vh -0.2vh 0vh #000, 0.2vh -0.2vh 0vh #000, -0.2vh 0.2vh 0vh #000, 0.2vh 0.2vh 0vh #000; text-shadow: -0.2vh -0.2vh 0vh #000, 0.2vh -0.2vh 0vh #000, -0.2vh 0.2vh 0vh #000, 0.2vh 0.2vh 0vh #000;
border: 0 solid transparent; border: none;
border-radius: 15px; border-radius: 15px;
background-color: rgba(0, 0, 0, 0.3); background-color: rgba(0, 0, 0, 0.3);
white-space: nowrap; white-space: nowrap;
@ -458,6 +490,22 @@ input[type=text]::placeholder {
text-shadow: -0.15vh -0.15vh 0vh #000, 0.15vh -0.15vh 0vh #000, -0.15vh 0.15vh 0vh #000, 0.15vh 0.15vh 0vh #000; text-shadow: -0.15vh -0.15vh 0vh #000, 0.15vh -0.15vh 0vh #000, -0.15vh 0.15vh 0vh #000, 0.15vh 0.15vh 0vh #000;
} }
input[type=number] {
border: none;
border-radius: 7px;
height: 50px;
width: 100px;
text-align: center;
background-color: rgba(0, 0, 0, 0.3);
white-space: nowrap;
-moz-appearance: textfield;
}
input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type=checkbox] { input[type=checkbox] {
display: none; display: none;
} }
@ -478,12 +526,105 @@ input[type=checkbox]:checked + label.gdcheckbox {
background-image: url(../../assets/check-on.png); background-image: url(../../assets/check-on.png);
} }
#settingList {
display: flex;
justify-content: space-evenly;
align-items: flex-start;
}
#settingList div {
width: 200px;
}
#settingList .gdCheckbox {
margin: 0px 0px 5px 0px;
}
.animationSelector {
margin-top: 20px;
display: flex;
justify-content: center;
align-items: center;
}
.animationSelector select {
border-radius: 7px;
border: none;
outline: none;
background-color: rgba(0, 0, 0, 0.3);
width: 300px;
height: 45px;
font-size: 32px;
padding-left: 7px;
cursor: pointer;
}
.animationSelector option {
color: black;
font-size: 20px;
font-family: aller, helvetica, arial;
letter-spacing: unset;
-webkit-text-stroke-width: unset;
-webkit-text-stroke-color: unset;
text-shadow: unset;
}
.animationSelector h2 {
width: unset
}
input[type="range"] {
background-color: rgba(0, 0, 0, 0);
appearance: none !important;
height: 20px;
min-height: 20px;
border: 1px solid;
cursor: pointer;
border-image: url(../../assets/slider_track.png);
border-image-slice: 21 22 22 21;
border-image-width: 30px 30px 30px 30px;
margin-right: 20px;
}
input[type="range"]::-webkit-slider-thumb {
appearance: none !important;
height: 45px;
width: 45px;
background-image: url("../../assets/slider_thumb.png");
background-repeat: no-repeat;
background-size: 100%;
}
input[type="range"]::-webkit-slider-thumb:active { background-image: url("../../assets/slider_thumb_active.png"); }
#extraInfo {
display: flex;
flex-direction: column;
text-align: left;
min-width: 220px;
}
#extraInfo div {
display: flex;
flex-direction: row;
justify-content: left;
margin-bottom: 8px;
align-items: center;
}
#extraInfo p {
color: white;
font-size: 24px;
margin: 0px 0px 0px 0px;
}
.bounce { .bounce {
animation: boxAnimator 0.25s; animation: boxAnimator 0.25s;
} }
.grayscale { .greyedOut {
filter: grayscale(100%) brightness(0.7); filter: grayscale(100%) brightness(0.7);
pointer-events: none;
} }
.gold { .gold {
@ -502,6 +643,10 @@ input[type=checkbox]:checked + label.gdcheckbox {
display: inline-block; display: inline-block;
} }
@media screen and (max-width: 1100px) {
.hideIfSmall { display: none !important; }
}
.spin { .spin {
-webkit-animation: spin 2s linear infinite; -webkit-animation: spin 2s linear infinite;
-moz-animation: spin 2s linear infinite; -moz-animation: spin 2s linear infinite;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,020 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Some files were not shown because too many files have changed in this diff Show more