轉載:愛因斯坦密鋪

分享身边的点滴趣事
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3078
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 128 次
被圈友点赞: 129 次
联系:

首次玩烏龜

帖子 ejsoon »

玩玩
玩玩
2024_09_30_18.43.00.png (16.69 KiB) 查看 1745 次

代码: 全选

<svg id="etmain" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" width="100%" height="480"> <defs> <path id="tile0" fill="#ececec" d="M 0 15.588 L -9 31.176 L -27 31.176 L -45 31.176 L -54 15.588 L -27 0 L -27 -31.176 L -9 -31.176 L 0 -46.764 L 27 -31.176 L 27 0 L 45 0 L 54 15.588 L 27 31.176 Z"></path> <path id="tile1" fill="#54b0e8" d="M -27 31.176 L -54 15.588 L -45 0 L -27 0 L -27 -31.176 L 0 -46.764 L 9 -31.176 L 27 -31.176 L 27 0 L 54 15.588 L 45 31.176 L 27 31.176 L 9 31.176 L 0 15.588 Z"></path> <path id="tile2" fill="#f9d98d" d="M 0 31.177 L -27 46.765 L -36 31.177 L -27 15.588 L -54 0 L -54 -31.177 L -36 -31.177 L -27 -15.588 L 0 -31.177 L 27 -15.588 L 54 0 L 54 31.177 L 36 31.177 L 27 46.765 Z"></path> <path id="tile3" fill="#d25e5e" d="M -27 46.765 L -36 31.177 L -54 31.177 L -54 0 L -27 -15.588 L 0 -31.177 L 27 -15.588 L 36 -31.177 L 54 -31.177 L 54 0 L 27 15.588 L 36 31.177 L 27 46.765 L 0 31.177 Z"></path> </defs> <g id="etdrop" transform="translate(-83.651,318.568) scale(0.76)"><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(252.998,-27.297) rotate(59.998)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(171.998,-74.059) rotate(0)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(306.998,3.88) rotate(-120)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(306.994,-89.653) rotate(-60.003)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(388.001,50.653) rotate(-179.996)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(387.998,-11.707) rotate(-179.999)" class="tiledroped"></use><use href="#tile3" stroke="#777" stroke-width="2" transform="translate(387.995,-74.067) rotate(179.998)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(468.998,-152.003) rotate(59.999)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(387.992,-136.421) rotate(179.998)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(306.993,-152.006) rotate(119.999)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(225.995,-105.238) rotate(179.999)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(144.997,-152) rotate(-120.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(252.993,-183.182) rotate(120.001)" class="tiledroped"></use><use href="#tile3" stroke="#777" stroke-width="2" transform="translate(198.997,-214.354) rotate(120)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(252.994,-276.713) rotate(60)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(144.997,-245.531) rotate(120)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(171.994,-323.478) rotate(-0.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(90.998,-183.177) rotate(60.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(90.999,-89.647) rotate(120.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(90.998,-27.293) rotate(-60.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(144.997,3.883) rotate(-59.999)" class="tiledroped"></use><use href="#tile3" stroke="#777" stroke-width="2" transform="translate(198.999,35.058) rotate(-60.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(253,66.234) rotate(-60.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(144.996,97.414) rotate(-120)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(226.002,144.177) rotate(179.998)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(306.998,97.41) rotate(-59.999)" class="tiledroped"></use><use href="#tile3" stroke="#777" stroke-width="2" transform="translate(387.997,113.007) rotate(-179.996)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(387.994,175.36) rotate(-179.998)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(306.997,190.941) rotate(-120)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(468.996,128.6) rotate(120.003)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(469.002,35.07) rotate(60.004)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(522.997,-27.295) rotate(120.002)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(522.999,66.249) rotate(-119.996)" class="tiledroped"></use><use href="#tile3" stroke="#777" stroke-width="2" transform="translate(576.996,3.884) rotate(120.002)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(630.995,35.061) rotate(120)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(630.997,-58.469) rotate(60.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(603.996,113.019) rotate(-179.997)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(549.994,144.193) rotate(0.004)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(468.993,190.951) rotate(-59.997)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(387.99,237.712) rotate(-179.996)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(387.996,-198.766) rotate(179.998)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(306.99,-245.537) rotate(-120.002)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(468.999,-58.471) rotate(120)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(549.999,-105.24) rotate(-0.002)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(522.996,-183.179) rotate(60.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(603.998,-136.411) rotate(-179.998)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(468.997,-245.533) rotate(-60)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(414.994,-276.709) rotate(-60.001)" class="tiledroped"></use><use href="#tile3" stroke="#777" stroke-width="2" transform="translate(360.988,-307.893) rotate(-60.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(414.992,-370.24) rotate(59.998)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(306.992,-339.067) rotate(-60.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(333.99,-417.01) rotate(-0.002)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(252.994,-370.243) rotate(-59.999)" class="tiledroped"></use><use href="#tile3" stroke="#777" stroke-width="2" transform="translate(576.997,-214.355) rotate(60.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(630.997,-245.532) rotate(59.999)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(684.999,-183.174) rotate(120.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(549.998,-292.297) rotate(0.001)" class="tiledroped"></use><use href="#tile2" stroke="#777" stroke-width="2" transform="translate(468.996,-339.063) rotate(-120.001)" class="tiledroped"></use><use href="#tile2" stroke="#436" stroke-width="4" transform="translate(564.014,204.516) rotate(-120.001)" class="tilemoving"></use></g></svg>
https://ejsoon.win/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3078
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 128 次
被圈友点赞: 129 次
联系:

Re: 轉載:愛因斯坦密鋪

帖子 ejsoon »

图片
這些帽子上的曲線是啥原理?烏龜有沒有?幽靈有沒有?
https://ejsoon.win/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3078
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 128 次
被圈友点赞: 129 次
联系:

Re: 轉載:愛因斯坦密鋪

帖子 ejsoon »

图片

來自https://makerworld.com/en/models/634863?from=search#profileId-560115

這個線這樣畫對嗎?
https://ejsoon.win/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3078
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 128 次
被圈友点赞: 129 次
联系:

真線來了

帖子 ejsoon »

龜帽真線.png
龜帽真線.png (23.5 KiB) 查看 1612 次
https://ejsoon.win/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3078
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 128 次
被圈友点赞: 129 次
联系:

代碼寫上癮了咋整?臨時記錄一下代碼:愛因斯坦密鋪

帖子 ejsoon »

代码: 全选

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>ejtile91</title>
</head>
<body>
<p><style>
#etmainouter {position: relative;}
#etmain {width: 100%; display: block;}
#trbutton {position: absolute; top: 0; right: 0; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; font-size: 16px; color: #333; line-height: 20px;}
#trbutton span {cursor: pointer; display: inline-block; width: 16px; height: 16px; line-height: 16px; text-align: center;}
.etbtnline {margin: 7px 0;}
.btndotend {margin-left: 36px;}
.dcshort {width: 24px;}
.ilblk {display: inline-block;}
.hide {display: none;}
</style></p>
<div id="etmainouter">
	<svg id="etmain" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" width="480" height="480">
		<defs mode="0" rotatesnap="0" rotatestart="0" rotatestep="60" snapto="0" slopetype="int">
			<g id="tile0" frontfill="#ececec" backfill="#54b0e8">
				<path d="M 0,15.588 L -9,31.176 L -27,31.176 L -45,31.176 L -54,15.588 L -27,0 L -27,-31.176 L -9,-31.176 L 0,-46.764 L 27,-31.176 L 27,0 L 45,0 L 54,15.588 L 27,31.176 Z"/>
			</g>
			<g id="tile1" frontfill="#f9d98d" backfill="#d25e5e">
				<path d="M 0,31.177 L -27,46.765 L -36,31.177 L -27,15.588 L -54,0 L -54,-31.177 L -36,-31.177 L -27,-15.588 L 0,-31.177 L 27,-15.588 L 54,0 L 54,31.177 L 36,31.177 L 27,46.765 Z"/>
			</g>
		</defs>
	</svg>
	<div id="trbutton">
		<span onclick="undo()" id="ejtileundo" style="color: #777;"> ↶ </span>
		<span onclick="redo()" id="ejtileredo" style="color: #777;"> ↷ </span>
		<br>
		<span onclick="scaleButton(1)" id="scaleUp"> ⊕ </span>
		<span onclick="scaleButton(0)" id="scaleDown"> ⊖ </span>
		<span style="display: none;" id="displayscale"></span>
		<br>
		<span onclick="downloadSVG()"> ⍗ </span>
		<span onclick="uploadSVG()"> ⍐ </span>
	</div>
</div>
<div>
	<div id="defaultbtn">
	</div>
	<div id="settingarea" class="hide">
		<div class="editsetting">
			<div class="etbtnline">
				<button id="rotateSnapButton" type="button" onclick="toggleRotateSnap()">rotate snap</button>
				<span id="rotateSnapStartTXT" onclick="changeRotateStart()">start <span id="rotateSnapStartValue"></span></span>
				<span id="rotateSnapStepTXT" onclick="changeRotateStep()">step <span id="rotateSnapStepValue"></span></span>
			</div>
			<div class="etbtnline">
				<span>snap to </span>
				<label for="snapto0"><input type="radio" name="snapto" id="snapto0" value="0" onchange="setSnapTo(this.value)" checked> side </label>
				<label for="snapto1"><input type="radio" name="snapto" id="snapto1" value="1" onchange="setSnapTo(this.value)"> dot </label>
			</div>
			<div class="etbtnline">
				<button class="btnconstruct" type="button">construct</button>
			</div>
			<div class="etbtnline">
				<button class="btnnew" type="button">new</button>
				<button class="btnedit" type="button">edit</button>
				<button class="btnup" type="button">up</button>
				<button class="btndown" type="button">down</button>
				<button class="btndelete" type="button">delete</button>
				<button class="btncopy" type="button">copy</button>
			</div>
			<div class="etbtnline">
				<button class="btndotstart" type="button">x,y</button>
				<button class="btndotend" type="button">x,y</button>
			</div>
			<div class="etbtnline">
				<label for="dotcalculate">
					<input type="radio" name="dotcalculate" value="0" checked>
					<input id="dcuxi" class="dcshort" type="input">
					+
					<input id="dcuxsi" class="dcshort" type="input">
					√
					<input id="dcuxs" class="dcshort" type="input">
					,
					<input id="dcuyi" class="dcshort" type="input">
					+
					<input id="dcuysi" class="dcshort" type="input">
					√
					<input id="dcuys" class="dcshort" type="input">
				</label>
			</div>
			<div class="etbtnline">
				<label for="dotcalculate">
					<input type="radio" name="dotcalculate" value="1">
					<input id="dcuxr" class="dcshort" type="input">
					° ;
					<input id="dcuyi" class="dcshort" type="input">
					+
					<input id="dcuysi" class="dcshort" type="input">
					√
					<input id="dcuys" class="dcshort" type="input">
				</label>
			</div>
		</div>
	</div>
	<div class="etbtnline">
		<button id="settingbtn" type="button" onclick="toggleEditTiles()">setting</button>
	</div>
</div>
<p><script>
// handle
var etmain, etdefs, etdrop, etwait;
var tilewaiting = document.getElementsByClassName("tilewaiting");
var tilemoving = document.getElementsByClassName("tilemoving");
var tilesnapped = document.getElementsByClassName("tilesnapped");
var tiledropped = document.getElementsByClassName("tiledropped");
var rotatecirlce = document.getElementsByClassName("rotatecirlce");
var waitactive = document.getElementsByClassName("waitactive");
const scaleUp = document.getElementById("scaleUp");
const scaleDown = document.getElementById("scaleDown");
const btnundo = document.getElementById("ejtileundo");
const btnredo = document.getElementById("ejtileredo");
const defaultbtn = document.getElementById("defaultbtn");
const settingbtn = document.getElementById("settingbtn");
const settingarea = document.getElementById("settingarea");
const rsbtn = document.getElementById("rotateSnapButton");
const rsstart = document.getElementById("rotateSnapStartValue");
const rsstep = document.getElementById("rotateSnapStepValue");
// static data
const rotatepadding = 20;
const currentscale = 0.12;
const snapratio = 2 / 3;
const snapradian = 24;
const snapradius = 0.01;
const clicktime = 777;
const clickradius = 144;
const snapdotradius = 12;
const history_length = 24;
const colormove = "#436";
const colorsnap = "green";
const colordrop = "#777";
const strokewidthmove = 4;
const strokewidthdrop = 2;
// tile data
var dotmax, dotaver;
var dotxy, dotmid, dotlen, dotslope;
// state
// 1 move drop, 2 move tile, 3 rotate tile, 4 two figure
// -1 edit tiles
var state = 0;
// mode
// 0 drop mode, 1 move mode
var mode = 0;
// mouse cursor
var startx, starty, startr, starttime;
var runx, runy;
var endx, endy, endtime;
var start2x, start2y, run2x, run2y;
var clickt, clickm, lastclickt, lastclickm;
var doubleclick = false;
// element attribute
var dropx = 0, dropy = 0, drops = 1;
var movex = 0, movey = 0, mover = 0, moven = 0, movef = 1;
// history
var history_array = new Array(history_length).fill("");
var history_point = 0, history_start = 0, history_end = 0;
// window onload
window.addEventListener("load", function () {
	etinit();
	// record history
	history_array[history_point] = etmain.outerHTML;
});
// button START
// toggleEditTiles
function toggleEditTiles () {
	// back to default
	if (-1 == state) {
		state = 0;
		settingbtn.innerHTML = "setting";
		settingarea.classList.add("hide");
		defaultbtn.classList.remove("hide");
	}
	// setting
	else {
		state = -1;
		settingbtn.innerHTML = "finish setting";
		settingarea.classList.remove("hide");
		defaultbtn.classList.add("hide");
	}
};
// change rotate step
function changeRotateStep () {
	let stepvalue = prompt("Input the new step degree:");
	if (null == stepvalue) return;
	stepvalue = parseInt(stepvalue);
	if (stepvalue >= 0 && stepvalue <= 180) {
		setRotateStep(stepvalue);
	} else {
		alert("The new step degree must between 0 to 180");
	}
};
// change rotate start
function changeRotateStart () {
	let startvalue = prompt("Input the new start degree:");
	if (null == startvalue) return;
	startvalue = parseInt(startvalue);
	if (startvalue >= -90 && startvalue <= 90) {
		setRotateStart(startvalue);
	} else {
		alert("The new start degree must between -90 to 90");
	}
};
// toggle rotate snap
function toggleRotateSnap () {
	if (getRotateSnap()) {
		setRotateSnap(0);
	} else {
		setRotateSnap(1);
	}
};
// download
function downloadSVG () {
	let etmainclone = etmain.cloneNode(true);
	let etmaincwait = etmainclone.querySelector(".etwait");
	etmaincwait.setAttribute("display", "none");
	let data = etmainclone.outerHTML;
	let file = new Blob([data], {type: "data:image/svg+xml"});
	let ejrealdl = document.createElement("a");
	ejrealdl.href = URL.createObjectURL(file);
	ejrealdl.download = "ejtile.svg";
	ejrealdl.click();
	ejrealdl.remove();
};
// testupload
function uploadSVG () {
	let ejuploadinput = document.getElementsByClassName("ejuploadinput")[0];
	ejuploadinput.click();
};
// scale Button
function scaleButton (uod = 1) {
	let dropsbk = drops;
	if (uod) {
		drops = round3(drops + currentscale);
	} else {
		drops = round3(drops - currentscale);
	}
	if (drops < 0 || drops > 4) {
		drops = dropsbk;
	}
	dropx = 0 - (0 - dropx) * drops / dropsbk;
	dropy = 0 - (0 - dropy) * drops / dropsbk;
	setDropXY(dropx, dropy);
	setDropScale(drops);
	setDropTransform();
};
// toggleScaleUp
function toggleScaleUp () {
	scaleButton(true);
};
// toggleScaleDown
function toggleScaleDown () {
	scaleButton(false);
};
// record history
function recordHistory () {
	if (etmain.outerHTML == history_array[history_point]) return;
	if (history_point + 1 < history_length) {
		history_point++;
	} else {
		history_point = 0;
	}
	history_end = history_point;
	if (history_start == history_end) {
		history_start++;
		if (history_start == history_length) {
			history_start = 0;
		}
	}
	history_array[history_point] = etmain.outerHTML;
	btnundo.style.color = "#333";
	btnredo.style.color = "#777";
};
// undo
function undo () {
	if (history_point != history_start) {
		if (history_point - 1 < 0) {
			history_point = history_length - 1;
		} else {
			history_point = history_point - 1;
		}
	}
	btnredo.style.color = "#333";
	if (history_point == history_start) {
		btnundo.style.color = "#777";
	} else {
		btnundo.style.color = "#333";
	}
	let dropxbk = dropx, dropybk = dropy, dropsbk = drops;
	let movenbk = moven, movefbk = movef, moverbk = mover;
	etmain.outerHTML = history_array[history_point];
	etinit();
	setDropXY(dropxbk, dropybk);
	setDropScale(dropsbk);
	setDropTransform();
	if (tilemoving.length) return;
	setMoveNumber(movenbk);
	setMoveFlip(movefbk);
	setMoveRotate(moverbk);
	setMoveTransform();
};
// redo
function redo () {
	if (history_point != history_end) {
		if (history_point + 1 == history_length) {
			history_point = 0;
		} else {
			history_point++;
		}
	}
	btnundo.style.color = "#333";
	if (history_point == history_end) {
		btnredo.style.color = "#777";
	} else {
		btnredo.style.color = "#333";
	}
	let dropxbk = dropx, dropybk = dropy, dropsbk = drops;
	let movenbk = moven, movefbk = movef, moverbk = mover;
	etmain.outerHTML = history_array[history_point];
	etinit();
	setDropXY(dropxbk, dropybk);
	setDropScale(dropsbk);
	setDropTransform();
	if (tilemoving.length) return;
	setMoveNumber(movenbk);
	setMoveFlip(movefbk);
	setMoveRotate(moverbk);
	setMoveTransform();
};
// button END
// get and set START
// get slope type
function getSlopeType () {
	if (etdefs.hasAttribute("slopetype")) {
		return etdefs.getAttribute("slopetype");
	}
	return "int";
};
// set slope type
function setSlopeType (v) {
	etdefs.setAttribute("slopetype", v);
};
// get Wait Rotate
function getTileWaitRotate () {
	let waittransform = tilewaiting[moven].getAttribute("transform");
	let waittilef = waittransform.replace(/.*rotate\((.*?)\).*/, "$1");
	return parseFloat(waittilef);
};
// get Wait Flip
function getTileWaitFlip () {
	let waittransform = tilewaiting[moven].getAttribute("transform");
	let waittilef = waittransform.replace(/.*scale\((.*?),.*/, "$1");
	if (parseFloat(waittilef) < 0) {
		return -1;
	}
	return 1;
};
// get Wait stroke-width
function getWaitStrokeWidth (waitscale, width) {
	return width / waitscale;
};
// get Wait scale
function getWaitScale (n) {
	return 36 / (dotmax[n] * 2);
};
// get snap to
function getSnapTo () {
	if (etdefs.hasAttribute("snapto")) {
		return parseInt(etdefs.getAttribute("snapto"));
	}
	return 0;
};
// set snap to
function setSnapTo (v) {
	etdefs.setAttribute("snapto", v);
};
// get rotate snap
function getRotateSnap () {
	if (etdefs.hasAttribute("rotatesnap")) {
		let rotatesnap = etdefs.getAttribute("rotatesnap");
		return parseInt(rotatesnap);
	}
	return 0;
};
// set rotate snap
function setRotateSnap (snap) {
	etdefs.setAttribute('rotatesnap', snap);
	if (snap) {
		rsbtn.innerHTML = "[rotate snap]";
		setMoveRotate(getRotateStart() * movef);
		setMoveTransform();
		cancelSnap();
	} else {
		rsbtn.innerHTML = "rotate snap";
	}
};
// get rotate start
function getRotateStart () {
	if (etdefs.hasAttribute("rotatestart")) {
		let rotatestart = etdefs.getAttribute("rotatestart");
		return parseInt(rotatestart);
	}
	return 0;
};
// set rotate start
function setRotateStart (start) {
	etdefs.setAttribute('rotatestart', start);
	rsstart.innerHTML = start;
	if (getRotateSnap()) {
		setMoveRotate(start);
		setMoveTransform();
		cancelSnap();
	}
};
// get rotate step
function getRotateStep () {
	if (etdefs.hasAttribute("rotatestep")) {
		let rotatestep = etdefs.getAttribute("rotatestep");
		return parseInt(rotatestep);
	}
	return 0;
};
// set rotate step
function setRotateStep (step) {
	etdefs.setAttribute('rotatestep', step);
	rsstep.innerHTML = step;
};
// get drop tile number
function getDropTileNumber (droppedtile) {
	if (droppedtile.hasAttribute("href")) {
		let etdrophref = droppedtile.getAttribute("href");
		return parseInt(etdrophref.replace("#tile", ""));
	}
	return 0;
};
// get drop tile flip
function getDropTileFlip (droppedtile) {
	if (droppedtile.hasAttribute("transform")) {
		let droptiletransform = droppedtile.getAttribute("transform");
		let droptilef = droptiletransform
			.replace(/.*scale\((.*?),.*/, "$1");
		return parseInt(droptilef);
	}
	return 1;
};
// get drop tile rotate
function getDropTileRotate (droppedtile) {
	if (droppedtile.hasAttribute("transform")) {
		let droptiletransform = droppedtile.getAttribute("transform");
		let droptiler = droptiletransform
			.replace(/.*rotate\((.*?)\).*/, "$1");
		return parseFloat(droptiler);
	}
	return 0;
};
// get drop tile xy
function getDropTileXY (droppedtile) {
	if (droppedtile.hasAttribute("transform")) {
		let etdroptransform = droppedtile.getAttribute("transform");
		let dropxy = etdroptransform
			.replace(/.*translate\((.*?)\).*/, "$1");
		let dropxyarr = dropxy.split(",");
		return [parseFloat(dropxyarr[0]), parseFloat(dropxyarr[1])];
	}
	return [0, 0];
};
// getDrop transform
function getDropTransform () {
	if (etdrop.hasAttribute('transform')) {
		return etdrop.getAttribute('transform');
	}
	return "";
};
// setDrop transform
function setDropTransform (x = dropx, y = dropy, s = drops) {
	etdrop.setAttribute('transform',
		'translate(' + x + ',' + y + ') ' +
		'scale(' + s + ')'
	);
};
// getDropXY
function getDropXY () {
	return getDropTileXY(etdrop);
};
// setDropXY
function setDropXY (x, y) {
	dropx = round3(x);
	dropy = round3(y);
};
// getDropScale
function getDropScale () {
	if (etdrop.hasAttribute("transform")) {
		let etdroptransform = getDropTransform();
		let getdrops = etdroptransform
			.replace(/.*scale\((.*?)\).*/, "$1");
		return round3(parseFloat(getdrops));
	}
	return 1;
};
// setDropScale
function setDropScale (v) {
	drops = round3(v);
	document.getElementById("displayscale").innerHTML = drops;
};
// get move transform
function getMoveTransform () {
	if (tilemoving.length && tilemoving[0].hasAttribute('transform')) {
		return tilemoving[0].getAttribute('transform');
	}
	return "";
};
// set move transform
function setMoveTransform (x = movex, y = movey, f = movef, r = mover) {
	if (tilemoving.length) {
		tilemoving[0].setAttribute('transform',
			'translate(' + x + ',' + y + ') ' +
			'scale(' + f + ',1) ' +
			'rotate(' + r + ')'
		);
		// tilewaiting transform
		let waitscale = getWaitScale(moven);
		tilewaiting[moven].setAttribute('transform',
			'translate(' + 20 + ',' + (20 + moven * 40) + ') ' +
			'scale(' + (f * waitscale) + ',' + (waitscale) + ') ' +
			'rotate(' + r + ')'
		);
	}
};
// get movexy
function getMoveXY () {
	if (tilemoving.length) {
		let etmovetransform = getMoveTransform();
		let movexy = etmovetransform
			.replace(/.*translate\((.*?)\).*/, "$1");
		let movexyarr = movexy.split(",");
		let movexyarrx = round3(parseFloat(movexyarr[0]));
		let movexyarry = round3(parseFloat(movexyarr[1]));
		return [movexyarrx, movexyarry];
	}
	return [0, 0];
};
// set movexy
function setMoveXY (x, y) {
	if (tilemoving.length) {
		movex = round3(x);
		movey = round3(y);
	}
};
// get move rotate
function getMoveRotate () {
	if (tilemoving.length) {
		let etmovetransform = getMoveTransform();
		let etmovescale = etmovetransform
			.replace(/.*rotate\((.*?)\).*/, "$1");
		return parseFloat(etmovescale);
	}
	return 0;
};
// set move rotate
function setMoveRotate (r) {
	mover = round3(degree180(r));
};
// get move flip
function getMoveFlip () {
	if (tilemoving.length) {
		let etmovetransform = getMoveTransform();
		let etmovescale = etmovetransform
			.replace(/.*scale\((.*?),.*/, "$1");
		return parseFloat(etmovescale);
	}
	return 1;
};
// set move flip
function setMoveFlip (f) {
	movef = parseInt(f);
};
// get move number
function getMoveNumber () {
	if (tilemoving.length) {
		let movehref = tilemoving[0].getAttribute("href");
		return parseInt(movehref.replace("#tile", ""));
	}
	return 0;
};
// set move number
function setMoveNumber (n = moven) {
	moven = parseInt(n);
	if (tilemoving.length) {
		tilemoving[0].setAttribute("href", "#tile" + moven);
	}
	toggleWaitActive(n);
};
// get and set END
// standard START
// create circle
// createCircle(mx, my, 3, "blue").classList.add("testcenter");
/*
// remove testcenter
let testcenter = document.getElementsByClassName("testcenter");
while (testcenter.length) {
	testcenter[0].remove();
}
*/
function createCircle (x, y, radius, fill = "transparent",
	stroke = "none", sw = 7, layer = "d") {
	let rocle = document.createElementNS(
		'http://www.w3.org/2000/svg', 'circle');
	rocle.setAttribute("r", radius);
	rocle.setAttribute("cx", x);
	rocle.setAttribute("cy", y);
	rocle.setAttribute("fill", fill);
	rocle.setAttribute("stroke", stroke);
	rocle.setAttribute("stroke-width", sw);
	if ("m" == layer) {
		etmain.appendChild(rocle);
	} else if ("d" == layer) {
		etdrop.appendChild(rocle);
	}
	return rocle;
};
// create tile
function createTile (n = 0, x = 0, y = 0, f = 1, r = 0,
	fill = "blue", stroke = colormove, sw = strokewidthmove, layer = etdrop) {
	let tile = document.createElementNS(
		"http://www.w3.org/2000/svg", "use");
	tile.setAttribute("href", "#tile" + n);
	tile.setAttribute("fill", fill);
	tile.setAttribute("stroke", stroke);
	tile.setAttribute("stroke-width", sw);
	tile.setAttribute("transform",
		"translate(" + x + "," + y + ") " +
		'scale(' + f + ',1) ' +
		"rotate(" + r + ")"
	);
	layer.appendChild(tile);
	return tile;
};
// degree 180
function degree180 (r) {
	if (r > 180) {
		r = r - 360;
	} else if (r <= -180) {
		r = r + 360;
	}
	return round3(r);
};
// math round 1000
function round3 (num) {
	return Math.round(num * 1000) / 1000;
};
// standard END
// mouse START
// ejtileWaitClick
function ejtileWaitClick (e) {
	if (state != -1) {
		let moden;
		for (let i = 0; i < tilewaiting.length; i++) {
			if (
				tilewaiting[i] == e.target ||
				(null != e.target.nextElementSibling &&
				tilewaiting[i] == e.target.nextElementSibling)
			) {
				if (mode) {
					moden = i;
				}
				else {
					setMoveNumber(i);
					setMoveFlip(getTileWaitFlip());
					setMoveRotate(getTileWaitRotate());
					if (tilemoving.length) {
						tilemoving[0].setAttribute('fill', getTileFill());
						setMoveTransform();
					}
				}
			}
		}
		if (mode) {
			// remove tilemoving
			if (tilemoving.length) {
				tilemoving[0].removeAttribute("stroke");
				tilemoving[0].removeAttribute("stroke-width");
				tilemoving[0].classList.add("tiledropped");
				tilemoving[0].classList.remove("tilemoving");
			}
			// add tilemoving
			for (let i = 0; i < tiledropped.length; i++) {
				if (moden == getDropTileNumber(tiledropped[i])) {
					let modet = tiledropped[i];
					modet.setAttribute("stroke", colormove);
					modet.setAttribute("stroke-width", strokewidthmove);
					modet.classList.remove("tiledropped");
					modet.classList.add("tilemoving", "wait2move");
					while (modet != etdrop.lastChild) {
						etdrop.insertBefore(etdrop.lastChild, modet);
					}
					let movexy = getMoveXY();
					mover = getMoveRotate();
					setMoveXY(movexy[0], movexy[1]);
					setMoveNumber(getMoveNumber());
				}
			}
		}
	}
};
// mouse wheel
function ejtileMouseWheel (e) {
	e.preventDefault();
	let dropsbk = drops;
	drops = e.deltaY * -0.01 + drops;
	if (drops < 0 || drops > 4) {
		drops = dropsbk;
	}
	let movetox = e.offsetX - (e.offsetX - dropx) * drops / dropsbk;
	let movetoy = e.offsetY - (e.offsetY - dropy) * drops / dropsbk;
	// set drop value
	setDropXY(movetox, movetoy);
	setDropScale(drops);
	setDropTransform();
};
// set end xy
function setEndXY (e) {
	if (ifNotGaming()) return;
	// PC client
	if (e.offsetX) {
		endx = e.offsetX;
		endy = e.offsetY;
	}
	// mobile client
	if (e.touches) {
		let ejtile_rect = etmain.getBoundingClientRect();
		let rtx = e.changedTouches[0].pageX - ejtile_rect.x - window.scrollX;
		let rty = e.changedTouches[0].pageY - ejtile_rect.y - window.scrollY;
		endx = Math.round(rtx);
		endy = Math.round(rty);
	}
};
// set start xy
function setStartXY (e) {
	// PC client
	if (e.offsetX) {
		startx = e.offsetX;
		starty = e.offsetY;
	}
	// mobile client
	if (e.touches) {
		let ejtile_rect = etmain.getBoundingClientRect();
		if (e.touches.length > 2) {
			state = 0;
		}
		if (e.touches.length > 1) {
			let rtx = e.touches[1].pageX - ejtile_rect.x - window.scrollX;
			let rty = e.touches[1].pageY - ejtile_rect.y - window.scrollY;
			run2x = start2x = Math.round(rtx);
			run2y = start2y = Math.round(rty);
			// set dropxy
			let movetox = round3(runx - startx + dropx);
			let movetoy = round3(runy - starty + dropy);
			setDropXY(movetox, movetoy);
		}
		if (e.touches.length > 0) {
			let rtx = e.touches[0].pageX - ejtile_rect.x - window.scrollX;
			let rty = e.touches[0].pageY - ejtile_rect.y - window.scrollY;
			runx = startx = Math.round(rtx);
			runy = starty = Math.round(rty);
		}
	}
};
// set run XY
function setRunXY (e) {
	if (ifNotGaming()) return;
	// PC client
	if (e.offsetX) {
		runx = e.offsetX;
		runy = e.offsetY;
	}
	// mobile client
	if (e.touches) {
		let ejtile_rect = etmain.getBoundingClientRect();
		let rectx = ejtile_rect.x + window.scrollX;
		let recty = ejtile_rect.y + window.scrollY;
		if (e.touches.length > 1) {
			let rtx = e.touches[1].pageX - rectx;
			let rty = e.touches[1].pageY - recty;
			run2x = Math.round(rtx);
			run2y = Math.round(rty);
			if (
				e.touches[1].pageX < rectx ||
				e.touches[1].pageY < recty ||
				e.touches[1].pageX > ejtile_rect.width + rectx ||
				e.touches[1].pageY > ejtile_rect.height + recty
			) {
				ejtileMouseUp(e);
			}
		}
		if (e.touches.length > 0) {
			let rtx = e.touches[0].pageX - rectx;
			let rty = e.touches[0].pageY - recty;
			runx = Math.round(rtx);
			runy = Math.round(rty);
			if (
				e.touches[0].pageX < rectx ||
				e.touches[0].pageY < recty ||
				e.touches[0].pageX > ejtile_rect.width + rectx ||
				e.touches[0].pageY > ejtile_rect.height + recty
			) {
				ejtileMouseUp(e);
			}
		}
	}
};
// set state
function addNewTile () {
	if (ifNotGaming()) return;
	if (
		mode == 0 &&
		!tilemoving.length && clickt == etmain && !doubleclick
	) {
		movex = (startx - dropx) / drops;
		movey = (starty - dropy) / drops;
		createTile(moven, movex, movey, movef, mover, getTileFill())
			.classList.add("tilemoving");
		setMoveXY(movex, movey);
		setMoveRotate(mover);
		state = 2; // move tile
	}
};
// moveTileEnd
function moveTileEnd () {
	if (tilemoving.length && state == 2) {
		let movetox = endx - startx + movex * drops;
		let movetoy = endy - starty + movey * drops;
		movetox = movetox / drops;
		movetoy = movetoy / drops;
		setMoveXY(movetox, movetoy);
	}
};
// rotateSnap
function rotateSnap (rvalue) {
	if (getRotateSnap()) {
		let rotatestart = getRotateStart() * movef;
		let rotatestep = getRotateStep();
		let rn = Math.floor((rvalue - rotatestart) / rotatestep);
		if (
			rvalue - (rn * rotatestep + rotatestart) <
			((rn + 1) * rotatestep + rotatestart) - rvalue
		) {
			rvalue = rn * rotatestep + rotatestart;
		} else {
			rvalue = (rn + 1) * rotatestep + rotatestart;
		}
	}
	return rvalue;
};
// rotateTileEnd
function rotateTileEnd () {
	if (tilemoving.length && state == 3) {
		let centerx = movex * drops + dropx;
		let centery = movey * drops + dropy;
		let dx = endx - centerx;
		let dy = endy - centery;
		let endr = Math.atan2(dy, dx) / Math.PI * 180;
		endr = degree180((endr - startr) * movef + mover);
		// rotate snap
		endr = rotateSnap(endr);
		setMoveRotate(endr);
		while (rotatecirlce.length) {
			rotatecirlce[0].remove();
		}
	}
};
// rotateTile
function rotateTile () {
	if (tilemoving.length && state == 3) {
		let centerx = movex * drops + dropx;
		let centery = movey * drops + dropy;
		let dx = runx - centerx;
		let dy = runy - centery;
		let runr = Math.atan2(dy, dx) / Math.PI * 180;
		runr = (runr - startr) * movef + mover;
		// rotate snap
		runr = rotateSnap(runr);
		// rotate
		setMoveTransform(movex, movey, movef, runr);
	}
};
// moveTile
function moveTile () {
	if (tilemoving.length && state == 2) {
		let movetox = runx - startx + movex * drops;
		let movetoy = runy - starty + movey * drops;
		movetox = round3(movetox / drops);
		movetoy = round3(movetoy / drops);
		setMoveTransform(movetox, movetoy, movef, mover);
	}
};
// set state by distance
function setState () {
	let centerx = movex * drops + dropx;
	let centery = movey * drops + dropy;
	let dx = startx - centerx;
	let dy = starty - centery;
	let dxy = Math.sqrt(dx * dx + dy * dy);
	// move tile
	if (dxy < dotaver[moven] * drops) {
		state = 2;
	}
	// rotate tile
	else if (dxy < dotmax[moven] * drops) {
		state = 3;
	}
	// move etdrop
	else {
		state = 1;
	}
}
// setStartValue
function setStartValue (e) {
	if (ifNotGaming()) return;
	// mobile client two figures
	if (e.touches && e.touches.length == 2 && state == 1) {
		state = 4;
		return;
	}
	// doubleclick
	doubleclick = false;
	if (Date.now() - starttime < clicktime &&
		Math.pow(endx - startx, 2) + Math.pow(endy - starty, 2) < clickradius
	) {
		doubleclick = true;
	}
	// start value
	starttime = Date.now();
	lastclickt = clickt;
	clickt = e.target;
	lastclickm = clickm;
	clickm = tilemoving.length + tilesnapped.length;
	// state
	if (
		clickt.classList.contains("tilewaiting") ||
		(null != clickt.nextElementSibling &&
		clickt.nextElementSibling.classList.contains("tilewaiting"))
	) {
		state = 0;
	} else if (tilemoving.length) {
		setState();
	} else {
		state = 1;
	}
};
// scaleDropEnd
function scaleDropEnd () {
	if (state != 4) return;
	// find center
	let startcx = (startx + start2x) / 2;
	let startcy = (starty + start2y) / 2;
	let runcx = (runx + run2x) / 2;
	let runcy = (runy + run2y) / 2;
	// scale
	let startlen = Math.sqrt(
		Math.pow(start2x - startx, 2) + Math.pow(start2y - starty, 2)
	);
	let runlen = Math.sqrt(
		Math.pow(run2x - runx, 2) + Math.pow(run2y - runy, 2)
	);
	let runscale = round3(drops * runlen / startlen);
	// translate
	let movetox = round3(runcx - startcx + dropx);
	let movetoy = round3(runcy - startcy + dropy);
	movetox = runcx - (runcx - movetox) * runscale / drops;
	movetoy = runcy - (runcy - movetoy) * runscale / drops;
	// set drop value
	setDropXY(movetox, movetoy);
	setDropScale(runscale);
	setDropTransform();
};
// scale drop
function scaleDrop () {
	if (state != 4) return;
	// find center
	let startcx = (startx + start2x) / 2;
	let startcy = (starty + start2y) / 2;
	let runcx = (runx + run2x) / 2;
	let runcy = (runy + run2y) / 2;
	// scale
	let startlen = Math.sqrt(
		Math.pow(start2x - startx, 2) + Math.pow(start2y - starty, 2)
	);
	let runlen = Math.sqrt(
		Math.pow(run2x - runx, 2) + Math.pow(run2y - runy, 2)
	);
	let runscale = round3(drops * runlen / startlen);
	// translate
	let movetox = round3(runcx - startcx + dropx);
	let movetoy = round3(runcy - startcy + dropy);
	movetox = runcx - (runcx - movetox) * runscale / drops;
	movetoy = runcy - (runcy - movetoy) * runscale / drops;
	setDropTransform(movetox, movetoy, runscale);
};
// setRotate
function setRotate () {
	if (tilemoving.length && state == 3) {
		createCircle(movex, movey, dotmax[moven], "transparent", "#fc7")
			.classList.add("rotatecirlce");
		let centerx = movex * drops + dropx;
		let centery = movey * drops + dropy;
		let dx = startx - centerx;
		let dy = starty - centery;
		startr = Math.atan2(dy, dx) / Math.PI * 180;
	}
};
// cancel wait active tile
function cancelWaitActive () {
	if (waitactive.length) {
		waitactive[0].setAttribute("stroke", colordrop);
		let waitscale = getWaitScale(moven);
		let waitstrokewidth = getWaitStrokeWidth(waitscale, 1);
		waitactive[0].setAttribute("stroke-width", waitstrokewidth);
		waitactive[0].classList.remove("waitactive");
	}
};
// cancel snap tile
function cancelSnap () {
	if (tilesnapped.length) {
		tilesnapped[0].setAttribute("stroke", colormove);
		tilesnapped[0].classList.remove("tilesnapped");
		waitactive[0].setAttribute("stroke", colormove);
	}
};
// set snap tile
function setSnap () {
	if (tilemoving.length) {
		tilemoving[0].setAttribute("stroke", colorsnap);
		tilemoving[0].classList.add("tilesnapped");
		toggleWaitActive(moven);
		waitactive[0].setAttribute("stroke", colorsnap);
		setMoveTransform();
	}
};
// drop snap Tile or cancel snap
function dropSnap () {
	if (ifNotGaming()) return;
	if (tilemoving.length && tilesnapped.length) {
		// cancel snap
		cancelSnap();
		if (
			state == 1 &&
			!clickt.classList.contains("tilewaiting") &&
			!clickt.nextElementSibling.classList.contains("tilewaiting")
		) {
			tilemoving[0].removeAttribute("stroke");
			tilemoving[0].removeAttribute("stroke-width");
			tilemoving[0].classList.add("tiledropped");
			tilemoving[0].classList.remove("tilemoving");
			// recordHistory
			recordHistory();
		}
	}
};
// calculate dot x
function cDotX (x, y, r, tx) {
	let rt = r / 180 * Math.PI;
	return x * Math.cos(rt) - y * Math.sin(rt) + tx;
};
// calculate dot y
function cDotY (x, y, r, ty) {
	let rt = r / 180 * Math.PI;
	return x * Math.sin(rt) + y * Math.cos(rt) + ty;
};
// get mid By tilen, XY and Radian
function getMidByNXYRF (n, x, y, r, f) {
	return midFlip(dotmid[n], f).map((xy) => {
		let midx = round3(cDotX(xy[0], xy[1], r, x));
		let midy = round3(cDotY(xy[0], xy[1], r, y));
		return [midx, midy];
	});
};
// getDots By tilen, XY and Radian
function getDotsByNXYRF (n, x, y, r, f) {
	return midFlip(dotxy[n], f).map((xy) => {
		let dotx = round3(cDotX(xy[0], xy[1], r, x));
		let doty = round3(cDotY(xy[0], xy[1], r, y));
		return [dotx, doty];
	});
};
// isIntersect after snapping
function isIntersect (neardropped, tmovex, tmovey, tmover) {
	// tilemoving dots
	let movedotxy = getDotsByNXYRF(moven, tmovex, tmovey, tmover, movef);
	let movedotmid = getMidByNXYRF(moven, tmovex, tmovey, tmover, movef);
	for (let k = 0; k < neardropped.length; k++) {
		let i = neardropped[k];
		// find every dropped tile center
		let ddotn = getDropTileNumber(tiledropped[i]);
		let ddotf = getDropTileFlip(tiledropped[i]);
		let dmids = midFlip(dotmid[ddotn], ddotf);
		let dlens = lenFlip(dotlen[ddotn], ddotf);
		let dslopes = slopeFlip(dotslope[ddotn], ddotf);
		// dropped xy and dropped radian
		let tiledroppedxy = getDropTileXY(tiledropped[i]);
		let tiledroppedx = tiledroppedxy[0];
		let tiledroppedy = tiledroppedxy[1];
		let tiledroppedr = getDropTileRotate(tiledropped[i]) * ddotf;
		// actually drop dotxy
		let dropdotxy = getDotsByNXYRF(ddotn,
			tiledroppedx, tiledroppedy, tiledroppedr, ddotf);
		let dropdotmid = getMidByNXYRF(ddotn,
			tiledroppedx, tiledroppedy, tiledroppedr, ddotf);
		// tilemoving and dropped is dumplicate
		if (
			ddotn == moven && ddotf == movef && tmover == tiledroppedr &&
			Math.pow(tmovex - tiledroppedx, 2)
			+ Math.pow(tmovey - tiledroppedy, 2)
			< snapradius
		) {
			return true;
		}
		// tilemoving dots is in dropped
		for (let j = 0; j < movedotxy.length; j++) {
			let mx = movedotxy[j][0];
			let my = movedotxy[j][1];
			let isA1InA2 = false;
			for (let i = 0; i < dropdotxy.length; i++) {
				if (
					Math.pow(mx - dropdotxy[i][0], 2)
					+ Math.pow(my - dropdotxy[i][1], 2)
					< snapradius
				) {
					isA1InA2 = true;
					break;
				}
			}
			if (isA1InA2) {
				continue;
			}
			if (isPointInsidePolygon(mx, my, dropdotxy)) {
				return true;
			}
		}
		// tilemoving dotmid is in dropped
		for (let j = 0; j < movedotmid.length; j++) {
			let mx = movedotmid[j][0];
			let my = movedotmid[j][1];
			let isA1InA2 = false;
			for (let i = 0; i < dropdotmid.length; i++) {
				if (
					Math.pow(mx - dropdotmid[i][0], 2)
					+ Math.pow(my - dropdotmid[i][1], 2)
					< snapradius
				) {
					isA1InA2 = true;
					break;
				}
			}
			if (isA1InA2) {
				continue;
			}
			if (isPointInsidePolygon(mx, my, dropdotxy)) {
				return true;
			}
		}
		// tiledropped dots is in tilemoving
		for (let j = 0; j < dropdotxy.length; j++) {
			let dx = dropdotxy[j][0];
			let dy = dropdotxy[j][1];
			let isA1InA2 = false;
			for (let i = 0; i < movedotxy.length; i++) {
				if (Math.pow(dx - movedotxy[i][0], 2)
					+ Math.pow(dy - movedotxy[i][1], 2)
					< snapradius
				) {
					isA1InA2 = true;
					break;
				}
			}
			if (isA1InA2) {
				continue;
			}
			if (isPointInsidePolygon(dx, dy, movedotxy)) {
				return true;
			}
		}
		// tiledropped dotmid is in tilemoving
		for (let j = 0; j < dropdotmid.length; j++) {
			let dx = dropdotmid[j][0];
			let dy = dropdotmid[j][1];
			let isA1InA2 = false;
			for (let i = 0; i < movedotmid.length; i++) {
				if (Math.pow(dx - movedotmid[i][0], 2)
					+ Math.pow(dy - movedotmid[i][1], 2)
					< snapradius
				) {
					isA1InA2 = true;
					break;
				}
			}
			if (isA1InA2) {
				continue;
			}
			if (isPointInsidePolygon(dx, dy, movedotxy)) {
				return true;
			}
		}
	}
	return false;
};
// snap to dot
function snapTileToDot (neardropped) {
	// dropped tile dotmid
	for (let k = 0; k < neardropped.length; k++) {
		let i = neardropped[k];
		// find every dropped tile center
		let ddotn = getDropTileNumber(tiledropped[i]);
		let ddotf = getDropTileFlip(tiledropped[i]);
		let ddotxy = midFlip(dotxy[ddotn], ddotf);
		// dropped xy and dropped radian
		let tiledroppedxy = getDropTileXY(tiledropped[i]);
		let tiledroppedx = parseFloat(tiledroppedxy[0]);
		let tiledroppedy = parseFloat(tiledroppedxy[1]);
		let tiledroppedr = getDropTileRotate(tiledropped[i]) * ddotf;
		for (let j = 0; j < ddotxy.length; j++) {
			let ddotx = ddotxy[j][0];
			let ddoty = ddotxy[j][1];
			let drx = cDotX(ddotx, ddoty, tiledroppedr, tiledroppedx);
			let dry = cDotY(ddotx, ddoty, tiledroppedr, tiledroppedy);
			// this moving tile dotmid
			let dotxys = midFlip(dotxy[moven], movef);
			for (let i = 0; i < dotxys.length; i++) {
				let dotx = dotxys[i][0];
				let doty = dotxys[i][1];
				let rx = cDotX(dotx, doty, mover * movef, movex);
				let ry = cDotY(dotx, doty, mover * movef, movey);
				// calculate distance
				let dotsdx = Math.pow(drx - rx, 2);
				let dotsdy = Math.pow(dry - ry, 2);
				if (Math.sqrt(dotsdx + dotsdy) > snapdotradius) {
					continue;
				}
				// snap if not intersect
				let tmovex = round3(movex + drx - rx);
				let tmovey = round3(movey + dry - ry);
				if (isIntersect(neardropped,
					tmovex, tmovey, mover * movef)) {
					continue;
				}
				setMoveXY(tmovex, tmovey);
				setSnap();
				break;
			}
			if (tilesnapped.length) {
				break;
			}
		}
		if (tilesnapped.length) {
			break;
		}
	}
};
// slopeFlip
function slopeFlip (slope, flip) {
	let newslope = slope.map((x) => {
		return x * flip;
	});
	if (-1 == flip) {
		newslope.reverse();
	}
	return newslope;
};
// lenFlip
function lenFlip (len, flip) {
	let newlen = len.slice();
	if (-1 == flip) {
		newlen.reverse();
	}
	return newlen;
};
// midFlip
function midFlip (mid, flip) {
	let newmid = mid.map((x) => {
		return [x[0] * flip, x[1]];
	});
	if (-1 == flip) {
		newmid.reverse();
	}
	return newmid;
};
// move and rotate snap tile
function snapTileToSide (neardropped) {
	// dropped tile dotmid
	for (let k = 0; k < neardropped.length; k++) {
		let i = neardropped[k];
		// find every dropped tile center
		let ddotn = getDropTileNumber(tiledropped[i]);
		let ddotf = getDropTileFlip(tiledropped[i]);
		let dmids = midFlip(dotmid[ddotn], ddotf);
		let dlens = lenFlip(dotlen[ddotn], ddotf);
		let dslopes = slopeFlip(dotslope[ddotn], ddotf);
		// dropped xy and dropped radian
		let tiledroppedxy = getDropTileXY(tiledropped[i]);
		let tiledroppedx = parseFloat(tiledroppedxy[0]);
		let tiledroppedy = parseFloat(tiledroppedxy[1]);
		let tiledroppedr = getDropTileRotate(tiledropped[i]) * ddotf;
		for (let j = 0; j < dmids.length; j++) {
			let dmidx = dmids[j][0];
			let dmidy = dmids[j][1];
			let drx = cDotX(dmidx, dmidy, tiledroppedr, tiledroppedx);
			let dry = cDotY(dmidx, dmidy, tiledroppedr, tiledroppedy);
			// this moving tile dotmid
			let mids = midFlip(dotmid[moven], movef);
			let lens = lenFlip(dotlen[moven], movef);
			let slopes = slopeFlip(dotslope[moven], movef);
			for (let i = 0; i < mids.length; i++) {
				let midx = mids[i][0];
				let midy = mids[i][1];
				let rx = cDotX(midx, midy, mover * movef, movex);
				let ry = cDotY(midx, midy, mover * movef, movey);
				// calculate distance
				let dotsdx = Math.pow(drx - rx, 2);
				let dotsdy = Math.pow(dry - ry, 2);
				let dotsd = Math.sqrt(dotsdx + dotsdy);
				if (dlens[j] != lens[i] || dotsd > lens[i] * snapratio) {
					continue;
				}
				// calculate ratio
				let snapr = 180;
				snapr += dslopes[j] + tiledroppedr;
				snapr -= slopes[i] + mover * movef;
				snapr = degree180(snapr);
				if (snapr > snapradian || snapr < -snapradian) {
					continue;
				}
				// snap if not intersect
				let tmover = mover + snapr * movef;
				let snapx = cDotX(midx, midy, tmover * movef, movex);
				let snapy = cDotY(midx, midy, tmover * movef, movey);
				let tmovex = round3(movex + drx - snapx);
				let tmovey = round3(movey + dry - snapy);
				if (isIntersect(neardropped,
					tmovex, tmovey, tmover * movef)) {
					continue;
				}
				setMoveXY(tmovex, tmovey);
				setMoveRotate(tmover);
				setSnap();
				break;
			}
			if (tilesnapped.length) {
				break;
			}
		}
		if (tilesnapped.length) {
			break;
		}
	}
};
// snapTile
function snapTile () {
	if (ifNotGaming()) return;
	if (!tiledropped.length && mode == 0) {
		setSnap();
	} else if (state == 2 || state == 3) {
		// collect near dropped tile
		let neardropped = [];
		for (let i = 0; i < tiledropped.length; i++) {
			// find every dropped tile center
			let ddotn = getDropTileNumber(tiledropped[i]);
			let ddotf = getDropTileFlip(tiledropped[i]);
			// dropped xy and dropped radian
			let tiledroppedxy = getDropTileXY(tiledropped[i]);
			let tiledroppedx = tiledroppedxy[0];
			let tiledroppedy = tiledroppedxy[1];
			let tiledroppedr = getDropTileRotate(tiledropped[i]) * ddotf;
			// search nearby
			if (Math.pow(movex - tiledroppedx, 2)
				+ Math.pow(movey - tiledroppedy, 2)
				< Math.pow(dotmax[moven] + dotaver[ddotn], 2)
			) {
				neardropped.push(i);
			}
		}
		// snap to dot
		if (getSnapTo()) {
			snapTileToDot(neardropped);
		}
		// snap to side
		else {
			snapTileToSide(neardropped);
		}
	}
};
// if not gaming state
function ifNotGaming () {
	if (state == -1) return true;
	return false;
};
// set state to 0
function setEndValue (e) {
	if (ifNotGaming()) return;
	endtime = Date.now();
	if (state == 4) {
		let ejtile_rect = etmain.getBoundingClientRect();
		let rectx = ejtile_rect.x + window.scrollX;
		let recty = ejtile_rect.y + window.scrollY;
		let rtx = e.touches[0].pageX - rectx;
		let rty = e.touches[0].pageY - recty;
		startx = Math.round(rtx);
		starty = Math.round(rty);
		state = 1;
		starttime -= clicktime;
	} else {
		state = 0;
	}
	// remove wait2move if mode 1
	if (mode) {
		let wait2move = document.getElementsByClassName("wait2move");
		while (wait2move.length) {
			wait2move[0].classList.remove("wait2move");
		}
	}
};
// moveDropEnd
function moveDropEnd () {
	if (state != 1) return;
	let movetox = round3(endx - startx + dropx);
	let movetoy = round3(endy - starty + dropy);
	setDropXY(movetox, movetoy);
	setDropTransform();
};
// moveDrop
function moveDrop () {
	if (state != 1) return;
	let movetox = round3(runx - startx + dropx);
	let movetoy = round3(runy - starty + dropy);
	setDropTransform(movetox, movetoy);
};
// clickEventUP
function clickEventUP () {
	if (ifNotGaming()) return;
	if (Date.now() - starttime < clicktime &&
		Math.pow(endx - startx, 2) + Math.pow(endy - starty, 2) < clickradius
	) {
		// moving mode
		if (mode) {
			if (clickt == tilemoving[0]) {
				if (clickt.classList.contains("wait2move")) {
					clickt.classList.remove("wait2move");
				} else {
					flipTile();
				}
			}
			return;
		}
		// flip tile
		if (!doubleclick && (clickm == 1 || clickm == 2) && 
			clickt == tilemoving[0]
		) {
			flipTile();
		}
		// remove dropped tile
		if (!doubleclick && clickm == 1 &&
			clickt.classList.contains("tiledropped")
		) {
			clickt.remove();
			// recordHistory
			recordHistory();
		}
		// move tile here
		if (
			!doubleclick && clickm == 1 && clickt == etmain &&
			state != 3 && state != 4
		) {
			setMoveXY((endx - dropx) / drops, (endy - dropy) / drops);
			setMoveTransform();
			state = 2;
		}
		// next tile
		if (doubleclick && (lastclickm == 1 || lastclickm == 2) &&
			lastclickt == tilemoving[0] && clickt == tilemoving[0]
		) {
			flipTile();
			moven += 1;
			if (moven == etdefs.children.length) {
				moven = 0;
			}
			setMoveNumber();
			setMoveRotate(getTileWaitRotate());
			setMoveFlip(getTileWaitFlip());
			setMoveFill();
			setMoveTransform();
		}
		// remove moving tile
		if (doubleclick && clickm == 1 &&
			lastclickm == 1 && lastclickt == etmain
		) {
			if (tilemoving.length) {
				tilemoving[0].remove();
			}
		}
		// remove dropped tile
		if (clickm == 0 && clickt.classList.contains("tiledropped")) {
			clickt.remove();
			// recordHistory
			recordHistory();
		}
	}
};
// clickEventDown
function clickEventDown () {
	if (ifNotGaming()) return;
	if (mode) return;
	if (Date.now() - endtime < clicktime &&
		Math.pow(endx - startx, 2) + Math.pow(endy - starty, 2) < clickradius
	) {
		// flip moving tile
		if (
			doubleclick && state == 2 &&
			(lastclickm == 0 || lastclickm == 2) &&
			lastclickt == etmain
		) {
			flipTile();
		}
		// undo Rmove Drop with double click
		if (doubleclick && (lastclickm == 1 || lastclickm == 0) &&
			lastclickt.classList.contains("tiledropped")
		) {
			etdrop.appendChild(lastclickt);
			if (tilemoving.length) {
				etdrop.appendChild(tilemoving[0]);
			}
			// recordHistory
			recordHistory();
		}
	}
};
// isPointInsidePolygon
function isPointInsidePolygon(x, y, vertices) {
	let inside = false;
	for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) {
		const xi = vertices[i][0], yi = vertices[i][1];
		const xj = vertices[j][0], yj = vertices[j][1];
		const intersect = ((yi > y) !== (yj > y)) &&
			(x < (xj - xi) * (y - yi) / (yj - yi) + xi);
		if (intersect) inside = !inside;
	}
	return inside;
};
// set move fill
function setMoveFill (fill = getTileFill()) {
	if (tilemoving.length) {
		tilemoving[0].setAttribute('fill', fill);
		tilewaiting[moven].setAttribute('fill', fill);
	}
};
// get tile fill
function getTileFill (n = moven) {
	let movet = etdefs.children[n];
	let fill = "blue";
	if (movef == 1) {
		fill = movet.getAttribute("frontfill");
	} else {
		fill = movet.getAttribute("backfill");
	}
	return fill;
};
// flip tile
function flipTile () {
	movef *= -1;
	mover *= -1;
	setMoveFill();
	setMoveTransform();
};
// active waiting tile
function moveMode () {
	if (ifNotGaming()) return;
	if (mode) {
		if (clickt.classList.contains("tiledropped")) {
			// remove rotatecirlce
			while (rotatecirlce.length) {
				rotatecirlce[0].remove();
			}
			// remove tilemoving
			if (tilemoving.length) {
				tilemoving[0].removeAttribute("stroke");
				tilemoving[0].removeAttribute("stroke-width");
				tilemoving[0].classList.add("tiledropped");
				tilemoving[0].classList.remove("tilemoving");
			}
			clickt.setAttribute("stroke", colormove);
			clickt.setAttribute("stroke-width", strokewidthmove);
			clickt.classList.remove("tiledropped");
			clickt.classList.add("tilemoving", "wait2move");
			while (clickt != etdrop.lastChild) {
				etdrop.insertBefore(etdrop.lastChild, clickt);
			}
			setMoveNumber(getMoveNumber());
			setMoveXY(getMoveXY()[0], getMoveXY()[1]);
			setMoveRotate(getMoveRotate());
			setState();
		}
		// drop moving
		else if (
			state != 2 && state != 3 &&
			tilemoving.length && clickt != tilemoving[0] &&
			!clickt.classList.contains("tilewaiting") &&
			(null == clickt.nextElementSibling ||
			!clickt.nextElementSibling.classList.contains("tilewaiting"))
		) {
			if (tilemoving.length) {
				tilemoving[0].removeAttribute("stroke");
				tilemoving[0].removeAttribute("stroke-width");
				tilemoving[0].classList.add("tiledropped");
				tilemoving[0].classList.remove("tilemoving");
			}
			cancelSnap();
			cancelWaitActive();
		}
	}
};
// mouse END
// init START
// get defs children's dots
function getDots (path) {
	let pathd = path.getAttribute("d");
	pathd = pathd.replace(/^M /, "").replace(/ Z.*$/, "");
	let pathdarr = pathd.split(" L ");
	let pathdarrmap = pathdarr.map((x) => {
		let xsplit = x.split(",");
		return [parseFloat(xsplit[0]), parseFloat(xsplit[1])];
	});
	return pathdarrmap;
};
// calculateDots
function calculateDots () {
	dotmax = [], dotaver = [];
	dotxy = [], dotmid = [], dotlen = [], dotslope = [];
	for (let i = 0; i < etdefs.children.length; i++) {
		let dots = getDots(etdefs.children[i].firstElementChild);
		// dot xy
		dotxy.push(dots);
		let thisdotmax = 0, thisdotaver = 0, thisdotsum = 0;
		let thisdotmid = [], thisdotlen = [], thisdotslope = [];
		for (let i = 0; i < dots.length; i++) {
			// dotmax, dotaver
			let thisdot = dots[i];
			let thisdl = Math.pow(thisdot[0], 2) + Math.pow(thisdot[1], 2);
			thisdl = round3(Math.sqrt(thisdl));
			thisdotsum += thisdl;
			if (thisdl > thisdotmax) {
				thisdotmax = thisdl;
			}
			// dotmid
			let crtdot, nxtdot;
			if (i < dots.length - 1) {
				crtdot = dots[i];
				nxtdot = dots[i + 1];
			} else {
				crtdot = dots[dots.length - 1];
				nxtdot = dots[0];
			}
			let midx = round3((crtdot[0] + nxtdot[0]) / 2);
			let midy = round3((crtdot[1] + nxtdot[1]) / 2);
			thisdotmid.push([midx, midy]);
			// dotlen
			let lenx = (crtdot[0] - nxtdot[0]) * (crtdot[0] - nxtdot[0]);
			let leny = (crtdot[1] - nxtdot[1]) * (crtdot[1] - nxtdot[1]);
			let len = Math.round(Math.sqrt(lenx + leny));
			thisdotlen.push(len);
			// dotslope
			let slopex = crtdot[0] - nxtdot[0];
			let slopey = crtdot[1] - nxtdot[1];
			let slopev = Math.atan2(slopey, slopex) / Math.PI * 180;
			if ("int" == getSlopeType()) {
				slopev = Math.round(slopev);
			}
			thisdotslope.push(slopev);
		}
		// dotmax
		dotmax.push(thisdotmax + rotatepadding);
		// dotaver
		thisdotaver = round3(thisdotsum / dots.length);
		dotaver.push(thisdotaver);
		// dotmid
		dotmid.push(thisdotmid);
		// dotlen
		dotlen.push(thisdotlen);
		// dotslope
		dotslope.push(thisdotslope);
	}
};
// createUploadForm
function createUploadForm () {
	if (null == document.getElementById("uploadform")) {
		let ejform = document.createElement("form");
		ejform.setAttribute("id", "uploadform");
		let ejuploadinput = document.createElement("input");
		ejuploadinput.setAttribute("type", "file");
		ejuploadinput.classList.add("ejuploadinput");
		ejform.appendChild(ejuploadinput);
		ejform.style.display = "none";
		let ejbody = document.getElementsByTagName("body")[0];
		ejbody.appendChild(ejform);
		ejuploadinput.onchange = function (e) {
			let reader = new FileReader(); 
			reader.readAsText(e.target.files[0]);
			reader.onload = function(){ 
				etmain.outerHTML = this.result;
				etinit();
				// recordHistory
				recordHistory();
			};
		};
	}
};
// mode init
function modeInit () {
	mode = parseInt(etdefs.getAttribute("mode"));
	if (!mode) return;
	if (tiledropped.length) return;
	for (let i = 0; i < etdefs.children.length; i++) {
		let thisdotmax = dotmax[i];
		let rotatestart = getRotateStart();
		createTile(
			i,
			thisdotmax + rotatepadding + 80,
			thisdotmax + rotatepadding,
			1, rotatestart, getTileFill(i), colordrop, strokewidthdrop
		).classList.add("tiledropped");
	}
};
// toggle Wait Active
function toggleWaitActive (n) {
	for (let i = 0; i < tilewaiting.length; i++) {
		let waitscale = getWaitScale(i);
		if (i == n) {
			tilewaiting[i].setAttribute("stroke", colormove);
			tilewaiting[i].classList.add("waitactive");
			tilewaiting[i].setAttribute("stroke-width", 
				getWaitStrokeWidth(waitscale, 2)
			);
		} else {
			tilewaiting[i].setAttribute("stroke", colordrop);
			tilewaiting[i].classList.remove("waitactive");
			tilewaiting[i].setAttribute("stroke-width", 
				getWaitStrokeWidth(waitscale, 1)
			);
		}
	}
};
// add tile waiting
function addTileWaiting () {
	for (let i = 0; i < dotmax.length; i++) {
		// outer and rect
		let waitouter = document.createElementNS(
			'http://www.w3.org/2000/svg', 'g');
		let waitbg = document.createElementNS(
			'http://www.w3.org/2000/svg', 'rect');
		waitbg.setAttribute("x", "0");
		waitbg.setAttribute("y", i * 40);
		waitbg.setAttribute("width", "40");
		waitbg.setAttribute("height", "40");
		waitbg.setAttribute("fill", "white");
		waitouter.appendChild(waitbg);
		// add waitile
		let waitscale = getWaitScale(i);
		let waitstrokewidth = getWaitStrokeWidth(waitscale, 1);
		let newtilewaiting = createTile(i, 20, 20 + 40 * i, 1, 0,
			getTileFill(i), colormove, waitstrokewidth, waitouter);
		newtilewaiting.classList.add("tilewaiting");
		let waittransform = newtilewaiting.getAttribute("transform")
			.replace(/(.*scale\().*?(\).*)/, "$1" + waitscale + "$2");
		newtilewaiting.setAttribute("transform", waittransform);
		if (mode == 0) {
			if (i == moven) {
				newtilewaiting.setAttribute("stroke", colormove);
				newtilewaiting.classList.add("waitactive");
				newtilewaiting.setAttribute("stroke-width", 
					getWaitStrokeWidth(waitscale, 2)
				);
			} else {
				newtilewaiting.setAttribute("stroke", colordrop);
				newtilewaiting.setAttribute("stroke-width", 
					getWaitStrokeWidth(waitscale, 1)
				);
			}
		}
		waitouter.onclick = ejtileWaitClick;
		waitouter.ontouchstart = function (e) {
			e.preventDefault();
			ejtileWaitClick(e);
		};
		etwait.appendChild(waitouter);
	}
};
// create etwait
function createWait () {
	etwait = etmain.querySelector(".etwait");
	if (etwait) {
		etwait.removeAttribute("display");
	} else {
		etwait = document.createElementNS(
			'http://www.w3.org/2000/svg', 'g');
		etwait.classList.add("etwait");
		etmain.appendChild(etwait);
		addTileWaiting();
	}
};
// create etdrop
function createDrop () {
	etdrop = etmain.querySelector(".etdrop");
	if (null == etdrop) {
		etdrop = document.createElementNS(
			'http://www.w3.org/2000/svg', 'g');
		etdrop.classList.add("etdrop");
		etdrop.setAttribute("stroke", colordrop);
		etdrop.setAttribute("stroke-width", strokewidthdrop);
		etmain.appendChild(etdrop);
	}
};
// init ejtile 
function etinit () {
	// handle element
	etmain = document.getElementById("etmain");
	etdefs = etmain.getElementsByTagName("defs")[0];
	createDrop();
	// mouse event
	etmain.onmousedown = ejtileMouseDown;
	etmain.onmousemove = ejtileMouseMove;
	etmain.onmouseup = ejtileMouseUp;
	etmain.onmouseleave = ejtileMouseUp;
	etmain.onwheel = ejtileMouseWheel;
	etmain.ontouchstart = function (e) {
		e.preventDefault();
		ejtileMouseDown(e);
	};
	etmain.ontouchmove = function (e) {
		e.preventDefault();
		ejtileMouseMove(e);
	};
	etmain.ontouchend = function (e) {
		e.preventDefault();
		ejtileMouseUp(e);
	};
	// calculate radius for dotmax and dotaver
	calculateDots();
	// get and set
	setDropXY(getDropXY()[0], getDropXY()[1]);
	setDropScale(getDropScale());
	setMoveXY(getMoveXY()[0], getMoveXY()[1]);
	setMoveRotate(getMoveRotate());
	setMoveFlip(getMoveFlip());
	setMoveNumber(getMoveNumber());
	setRotateSnap(getRotateSnap());
	setRotateStart(getRotateStart());
	setRotateStep(getRotateStep());
	// createUploadForm
	createUploadForm();
	// ejtile mode
	modeInit();
	// createWait and add tile waiting
	createWait();
};
// etmain Mouse Down
function ejtileMouseDown (e) {
	setStartXY(e);
	setStartValue(e);
	moveMode();
	setRotate();
	dropSnap();
	addNewTile();
	clickEventDown()
};
// etmain Mouse Move
function ejtileMouseMove (e) {
	setRunXY(e);
	moveDrop();
	moveTile();
	rotateTile();
	scaleDrop();
};
// etmain Mouse Up
function ejtileMouseUp (e) {
	setEndXY(e);
	moveDropEnd();
	moveTileEnd();
	rotateTileEnd();
	scaleDropEnd();
	clickEventUP();
	snapTile();
	setEndValue(e);
};
// init END
</script></p>
</body>
</html>
上次由 ejsoon 在 2024年 11月 2日 03:24,总共编辑 29 次。
https://ejsoon.win/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3078
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 128 次
被圈友点赞: 129 次
联系:

九個烏龜:愛因斯坦密鋪

帖子 ejsoon »

九個烏龜,找找規律
ejtile(8).png
ejtile(8).png (7.43 KiB) 查看 1499 次

代码: 全选

<svg id="etmain" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" width="480" height="480"> <defs mode="0" rotatesnap="0" rotatestart="0" rotatestep="60"> <g id="tile0" frontfill="#ececec" backfill="#54b0e8"> <path d="M 0 15.588 L -9 31.176 L -27 31.176 L -45 31.176 L -54 15.588 L -27 0 L -27 -31.176 L -9 -31.176 L 0 -46.764 L 27 -31.176 L 27 0 L 45 0 L 54 15.588 L 27 31.176 Z"></path> </g> <g id="tile1" frontfill="#f9d98d" backfill="#d25e5e"> <path d="M 0 31.177 L -27 46.765 L -36 31.177 L -27 15.588 L -54 0 L -54 -31.177 L -36 -31.177 L -27 -15.588 L 0 -31.177 L 27 -15.588 L 54 0 L 54 31.177 L 36 31.177 L 27 46.765 Z"></path> </g> </defs> <g class="etdrop" transform="translate(17.375,307.982) scale(0.4)"><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(205,98) scale(1,1) rotate(-33.975)" class="tiledropped"></use><use href="#tile1" fill="#d25e5e" stroke="#777" stroke-width="2" transform="translate(170.155,46.291) scale(-1,1) rotate(33.975)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(246.038,13.953) scale(1,1) rotate(86.024)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(193.769,-63.609) scale(1,1) rotate(26.023)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(135.309,-5.417) scale(1,1) rotate(-33.977)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(94.272,78.63) scale(1,1) rotate(-93.976)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(146.54,156.193) scale(1,1) rotate(-153.976)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(255.972,-67.932) scale(1,1) rotate(-153.975)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(321.919,-18.388) scale(1,1) rotate(-33.977)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(280.883,65.663) scale(1,1) rotate(-93.974)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(239.844,149.709) scale(1,1) rotate(-33.973)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(333.15,143.227) scale(1,1) rotate(-153.975)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(360.509,87.197) scale(1,1) rotate(-153.973)" class="tiledropped"></use><use href="#tile1" fill="#d25e5e" stroke="#777" stroke-width="2" transform="translate(387.867,31.159) scale(-1,1) rotate(153.976)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(415.225,-24.874) scale(1,1) rotate(-153.976)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(453.815,80.716) scale(1,1) rotate(146.026)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(494.852,-3.344) scale(1,1) rotate(86.023)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(426.455,136.742) scale(1,1) rotate(-33.976)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(349.278,-74.417) scale(1,1) rotate(146.024)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(442.583,-80.905) scale(1,1) rotate(-153.974)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(535.887,-87.392) scale(1,1) rotate(146.024)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(570.734,-35.686) scale(1,1) rotate(146.022)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(529.698,48.379) scale(1,1) rotate(-93.973)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(519.761,130.258) scale(1,1) rotate(26.025)" class="tiledropped"></use><use href="#tile1" fill="#d25e5e" stroke="#777" stroke-width="2" transform="translate(605.582,16.021) scale(-1,1) rotate(-146.022)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(640.431,67.727) scale(1,1) rotate(146.02)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(681.463,-16.322) scale(1,1) rotate(86.021)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(629.192,-93.877) scale(1,1) rotate(26.025)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(581.964,125.944) scale(1,1) rotate(-153.974)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(675.279,119.432) scale(1,1) rotate(146.022)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(716.311,35.382) scale(1,1) rotate(-93.979)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(757.343,-48.664) scale(1,1) rotate(-33.978)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(722.495,-100.371) scale(1,1) rotate(-33.978)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(656.551,-149.906) scale(1,1) rotate(26.027)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(576.922,-171.44) scale(1,1) rotate(-93.977)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(514.721,-167.116) scale(1,1) rotate(-93.975)" class="tiledropped"></use><use href="#tile1" fill="#d25e5e" stroke="#777" stroke-width="2" transform="translate(452.521,-162.791) scale(-1,1) rotate(93.973)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(390.313,-158.465) scale(1,1) rotate(-93.977)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(462.453,-244.679) scale(1,1) rotate(26.024)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(369.144,-238.189) scale(1,1) rotate(-33.978)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(328.112,-154.141) scale(1,1) rotate(-93.975)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(524.651,-249) scale(1,1) rotate(-153.978)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(617.958,-255.488) scale(1,1) rotate(-33.976)" class="tiledropped"></use><use href="#tile1" fill="#d25e5e" stroke="#777" stroke-width="2" transform="translate(683.91,-205.937) scale(-1,1) rotate(-26.025)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(749.852,-156.402) scale(1,1) rotate(146.024)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(711.264,-261.972) scale(1,1) rotate(26.025)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(790.888,-240.45) scale(1,1) rotate(86.023)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(815.8,-106.86) scale(1,1) rotate(26.021)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(825.734,-188.741) scale(1,1) rotate(-93.975)" class="tiledropped"></use><use href="#tile1" fill="#d25e5e" stroke="#777" stroke-width="2" transform="translate(265.908,-149.818) scale(-1,1) rotate(93.974)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(275.845,-231.704) scale(1,1) rotate(26.025)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(203.703,-145.494) scale(1,1) rotate(-93.976)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(182.539,-225.22) scale(1,1) rotate(-33.976)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(141.5,-141.172) scale(1,1) rotate(-93.974)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(100.464,-57.122) scale(1,1) rotate(-33.978)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(303.194,-287.732) scale(1,1) rotate(26.021)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(396.505,-294.225) scale(1,1) rotate(146.025)" class="tiledropped"></use><use href="#tile1" fill="#d25e5e" stroke="#777" stroke-width="2" transform="translate(330.549,-343.765) scale(-1,1) rotate(-26.021)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(357.902,-399.799) scale(1,1) rotate(26.019)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(264.598,-393.307) scale(1,1) rotate(-33.98)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(223.578,-309.267) scale(1,1) rotate(-93.974)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(472.388,-326.564) scale(1,1) rotate(-93.975)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(437.542,-378.272) scale(1,1) rotate(86.024)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(583.109,-307.195) scale(1,1) rotate(-33.977)" class="tiledropped"></use><use href="#tile1" fill="#d25e5e" stroke="#777" stroke-width="2" transform="translate(548.271,-358.902) scale(-1,1) rotate(33.974)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(624.144,-391.243) scale(1,1) rotate(86.022)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(658.993,-339.536) scale(1,1) rotate(-93.977)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(738.621,-318.004) scale(1,1) rotate(26.023)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(513.427,-410.61) scale(1,1) rotate(-33.974)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(571.872,-468.803) scale(1,1) rotate(26.021)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(478.582,-462.318) scale(1,1) rotate(-33.976)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(385.256,-455.832) scale(1,1) rotate(26.021)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(700.025,-423.584) scale(1,1) rotate(-33.977)" class="tiledropped"></use><use href="#tile1" fill="#d25e5e" stroke="#777" stroke-width="2" transform="translate(765.978,-374.036) scale(-1,1) rotate(-26.023)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(831.923,-324.498) scale(1,1) rotate(146.024)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(793.331,-430.07) scale(1,1) rotate(26.024)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(872.959,-408.546) scale(1,1) rotate(86.023)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(866.769,-272.791) scale(1,1) rotate(146.022)" class="tiledropped"></use><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="2" transform="translate(665.178,-475.291) scale(1,1) rotate(-33.977)" class="tiledropped"></use></g></svg>
https://ejsoon.win/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3078
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 128 次
被圈友点赞: 129 次
联系:

Re: 轉載:愛因斯坦密鋪,帶條紋

帖子 ejsoon »

代码: 全选

<svg id="etmain" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" width="480" height="480"> <defs mode="0" rotatesnap="0" rotatestart="0" rotatestep="60" snapto="0"> <g id="tile0" frontfill="#ececec" backfill="#54b0e8"> <path d="M 0,15.588 L -9,31.176 L -27,31.176 L -45,31.176 L -54,15.588 L -27,0 L -27,-31.176 L -9,-31.176 L 0,-46.764 L 27,-31.176 L 27,0 L 45,0 L 54,15.588 L 27,31.176 Z"></path>
<path fill="none" stroke="#69eaa5" stroke-width="2" d="
M -27,-15.588 A 46.764 46.764 0 0 0 13.5,-38.97
M -40.5,7.794 A 15.588 15.588 0 0 0 -13.5,7.79
A 46.764 46.764 0 0 1 27,-15.588
M 13.5,23.382 A 15.588 15.588 0 0 1 40.5,23.382
"></path>
</g> <g id="tile1" frontfill="#f9d98d" backfill="#d25e5e"> <path d="M 0,31.177 L -27,46.765 L -36,31.177 L -27,15.588 L -54,0 L -54,-31.177 L -36,-31.177 L -27,-15.588 L 0,-31.177 L 27,-15.588 L 54,0 L 54,31.177 L 36,31.177 L 27,46.765 Z"></path> </g> </defs> <g class="etdrop" stroke="#777" stroke-width="2" transform="translate(18.523,65.914) scale(0.661)"><use href="#tile0" fill="#ececec" transform="translate(141,240) scale(1,1) rotate(0)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(141,302.352) scale(1,1) rotate(0)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(141,177.648) scale(1,1) rotate(0)" class="tiledropped"></use><use href="#tile0" fill="#54b0e8" transform="translate(154.499,356.911) scale(-1,1) rotate(59.999)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(194.997,395.883) scale(1,1) rotate(0.002)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(194.995,458.235) scale(1,1) rotate(0.002)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(100.498,388.087) scale(1,1) rotate(120.001)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(127.496,450.439) scale(1,1) rotate(60.001)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(235.498,341.323) scale(1,1) rotate(-59.999)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(208.501,278.971) scale(1,1) rotate(-120.001)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(208.499,201.028) scale(1,1) rotate(119.999)" class="tiledropped"></use><use href="#tile0" fill="#54b0e8" transform="translate(100.501,138.677) scale(-1,1) rotate(59.999)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(181.499,123.089) scale(1,1) rotate(-60.001)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(46.501,169.853) scale(1,1) rotate(120.001)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(73.5,232.207) scale(1,1) rotate(60)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(73.501,310.146) scale(1,1) rotate(-59.999)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(87.002,84.118) scale(1,1) rotate(0)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(154.498,60.736) scale(1,1) rotate(-120.002)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(248.999,146.467) scale(1,1) rotate(179.998)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(262.5,232.205) scale(1,1) rotate(120)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(289.498,294.558) scale(1,1) rotate(60)" class="tiledropped"></use><use href="#tile0" fill="#54b0e8" transform="translate(316.499,216.618) scale(-1,1) rotate(-60.001)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(370.497,232.207) scale(1,1) rotate(120)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(424.495,263.383) scale(1,1) rotate(120)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(356.997,302.352) scale(1,1) rotate(-0.001)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(316.5,154.259) scale(1,1) rotate(-120.003)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(302.997,364.707) scale(1,1) rotate(-179.998)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(262.496,419.267) scale(1,1) rotate(120.001)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(370.498,372.499) scale(1,1) rotate(-120)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(424.496,341.325) scale(1,1) rotate(-120.001)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(478.493,310.148) scale(1,1) rotate(-119.999)" class="tiledropped"></use><use href="#tile0" fill="#54b0e8" transform="translate(356.995,427.061) scale(-1,1) rotate(179.998)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(316.494,466.033) scale(1,1) rotate(-119.998)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(262.494,497.208) scale(1,1) rotate(-119.999)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(410.994,458.239) scale(1,1) rotate(0.002)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(451.496,403.675) scale(1,1) rotate(-60.001)" class="tiledropped"></use><use href="#tile0" fill="#ececec" transform="translate(87.002,21.766) scale(1,1) rotate(0)" class="tiledropped"></use></g><g class="etwait" display="none"><g><rect x="0" y="0" width="40" height="40" fill="white" class="waitbg"></rect><use href="#tile0" fill="#ececec" stroke="#436" stroke-width="8.475" transform="translate(20,20) scale(0.236,0.236) rotate(0)" class="tilewaiting waitactive"></use></g><g><rect x="0" y="40" width="40" height="40" fill="white" class="waitbg"></rect><use href="#tile1" fill="#f9d98d" stroke="#777" stroke-width="4.566" transform="translate(20,60) scale(0.219,0.219) rotate(-13.411)" class="tilewaiting"></use></g></g></svg>
https://ejsoon.win/
弈趣極光:享受思維樂趣
头像
ejsoon
圈圈精英
圈圈精英
帖子: 3078
注册时间: 2022年 11月 18日 17:36
为圈友点赞: 128 次
被圈友点赞: 129 次
联系:

Re: 轉載:愛因斯坦密鋪:幽靈

帖子 ejsoon »

图片
https://ejsoon.win/
弈趣極光:享受思維樂趣
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 9 访客