Greasy Fork

Greasy Fork is available in English.

Gartic Phone Avatar Chooser

Adds every Avatar to a Selectionscreen. Now you can Select the Avatar you want

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Gartic Phone Avatar Chooser
// @namespace   Violentmonkey Scripts
// @match       *://garticphone.com/*
// @grant       none
// @version     1.3.1
// @author      Der_Floh
// @icon        https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://garticphone.com&size=128
// @homepageURL http://greasyfork.icu/de/scripts/468787-gartic-phone-avatar-chooser
// @supportURL  http://greasyfork.icu/de/scripts/468787-gartic-phone-avatar-chooser/feedback
// @license     MIT
// @description Adds every Avatar to a Selectionscreen. Now you can Select the Avatar you want
// ==/UserScript==

// jshint esversion: 8

class AvatarChooser {
	constructor(container, activationElem) {
		this.images;
		this.container = container;

		this.avatarChooserContainer = document.createElement("div");
		this.avatarChooserContainer.style.display = "none";
		this.container.parentNode.appendChild(this.avatarChooserContainer);

		this.imgElem = activationElem.querySelector("span");
		this.randomImageButton = activationElem.querySelector("button");
		this.randomImageButton.addEventListener("click", () => {
			setTimeout(() => {
				this.jsx  = this.randomImageButton.className;
				this.updateImagesClasses();
			}, 10);
		});
		this.jsx = this.randomImageButton.className;
		this.avatarChooserContainer.className = this.jsx + " avatar-chooser-flex-container";

		const activeTextJsx = this.container.querySelector('span[class*="active"]');

		addCustomStyle(`
			.avatar-hover-target:hover {
  			background-color: rgba(28, 28, 28, 0.8);
			}

			.avatar-text-overlay {
  			display: block;
  			position: absolute;
  			top: 50%;
  			left: 50%;
  			transform: translate(-50%, -50%);
				width: 100%;
				padding-top: 10px;
				padding-bottom: 12px;
				text-align: center;
				font-weight: bold;
				background-color: rgba(28, 28, 28, 0.6);
				border-radius: 7px;
			}

			.avatar-chooser-flex-container {
				display: flex;
				flex-wrap: wrap;
				width: 100%;
				height: 100%;
				align-items: stretch;
        overflow: scroll;
        padding: 20px;
			}

			.avatar-chooser-flex-item {
				flex: 1 1 auto;
        margin: 6px !important;
			}

			.avatar-chooser-flex-item span {
				width: 100%;
				height: 100%;
				background-size: cover;
				background-position: center;
			}

			.avatar-chooser-image-scale-transition {
				transition: transform 0.05s;
			}

			.avatar-chooser-image-scaled {
				transform: scale(0.9);
			}
		`);

		const textElem = document.createElement("p");
		textElem.className = "avatar-text-overlay avatar-hover-target " + activeTextJsx.className;
		textElem.style.cursor = "pointer";
		textElem.textContent = "Choose Avatar";
		textElem.onclick = this.choose.bind(this);
		activationElem.appendChild(textElem);

		this.loadImages();
	}

	async choose() {
		this.container.style.display = "none";
		this.avatarChooserContainer.style.display = "flex";
	}

	async selectImage(imageSrc) {
		let style = window.getComputedStyle(this.imgElem);
		let attributeValue = style.getPropertyValue("background-image");

		while (attributeValue != imageSrc) {
			this.randomImageButton.click();
			style = window.getComputedStyle(this.imgElem);
			attributeValue = style.getPropertyValue("background-image");
		}
		this.updateImagesClasses();
	}

	async updateImagesClasses() {
		this.avatarChooserContainer.className = this.jsx + " avatar-chooser-flex-container";
		for (const div of this.avatarChooserContainer.getElementsByTagName("div"))
			div.className = this.jsx + " avatar avatar-chooser-flex-item";
		for (const span of this.avatarChooserContainer.getElementsByTagName("span")) {
			let classString = this.jsx + " avatar-chooser-image-scale-transition";
			if (span.classList.contains("avatar-chooser-image-scaled"))
				classString += " avatar-chooser-image-scaled";
			span.className = classString;
		}
	}

	async loadImages() {
		this.images = await this.createImages();
		for (const image of this.images) {
			this.avatarChooserContainer.appendChild(image);
		}
	}

	async createImages() {
		const link = "https://garticphone.com/images/avatar/";
		const images = [];
		let i = 0;
		let svg;
		do {
			svg = await this.checkSVGExists(link + i + ".svg");
			if (svg) {
				const image = await this.createImage(i);
				images.push(image);
			}
			i++;
		} while (svg);
		return images;
	}

	async createImage(i) {
		const imageSrc = `url("https://garticphone.com/images/avatar/${i}.svg")`;
		const imgContainer = document.createElement("div");
		imgContainer.className = this.jsx + " avatar avatar-chooser-flex-item";
		//imgContainer.style.margin = "2px";
		imgContainer.style.maxWidth = "158px";
		const image = document.createElement("span");
		image.id = "accountimage-" + i;
		image.className = this.jsx + " avatar-chooser-image-scale-transition";
		image.style.backgroundImage = imageSrc;
		image.style.cursor = "pointer";

		const onImageSelect = () => {
			image.classList.remove("avatar-chooser-image-scaled");
			this.avatarChooserContainer.style.display = "none";
			this.container.style.display = "flex";
		};

		image.onclick = () => {
			event.preventDefault();
			image.classList.add("avatar-chooser-image-scaled");
			image.addEventListener('transitionend', () => {
				setTimeout(() => {
					image.classList.remove("avatar-chooser-image-scaled");
					setTimeout(() => {
						this.selectImage(imageSrc);
						onImageSelect();
					}, 200);
				}, 200);
			}, { once: true });
		};
		imgContainer.appendChild(image);
		return imgContainer;
	}

	async checkSVGExists(url) {
		try {
			const response = await fetch(url, { method: "HEAD" });
			return response.ok;
		} catch (error) {
			console.error("Error checking SVG existence:", error);
			return response.error;
		}
	}
}

if (slashCount(window.location.toString()) > 3)
  return;

window.addEventListener("load", async () => {
	const content = await waitForElementToExistId("content");
	const gameContainer = await waitForElementToExistQuery(content, 'div[class*="start"]');
	const avatarContainer = await waitForElementToExistQuery(content, 'div[class*="avatar"]');

	const avatarChooser = new AvatarChooser(gameContainer, avatarContainer);
});

async function waitForElementToExistQuery(baseNode, query) {
  return new Promise(async (resolve) => {
    async function checkElement() {
      const element = baseNode.querySelector(query);
      if (element !== null)
        resolve(element);
      else
        setTimeout(checkElement, 100);
    }
    await checkElement();
  });
}

async function waitForElementToExistId(elementId) {
  return new Promise(async (resolve) => {
    async function checkElement() {
      const element = document.getElementById(elementId);
      if (element !== null)
        resolve(element);
      else
        setTimeout(checkElement, 100);
    }
    await checkElement();
  });
}

function addCustomStyle(cssString) {
  const style = document.createElement('style');
	style.type = "text/css";
  style.innerHTML = cssString;
  document.head.appendChild(style);
}

function slashCount(str) {
  const regex = /\//g;
  const matches = str.match(regex);
  return matches ? matches.length : 0;
}