<canvas width="600" height="600"></canvas>
<input id="blk" type="number" style="display:none" min="0"/>
<script id="preview" mint="MINT_INSCRIPTION_ID">
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
let branch = 0;
let blockNumber = '0';
const branchColorMap = {
0: "#585663", // Grey
1: "#6D2BF8", // Purple
2: "#AF89FE", // Lilac
3: "#FDF64D", // Yellow
4: "#2067F0", // Blue
5: "#976F53", // Brown
6: "#CBC7E3", // Light Grey
7: "#15D96F", // Green
8: "#FF64C1", // Pink
9: "#F95E3C", // Orange
}
const leavesColorMap = {
0: "#EC5331", // Orange
1: "#403F4A", // Dark Grey
2: "#F343AC", // Pink
3: "#8F8DA5", // Light Grey
4: "#725540", // Brown
5: "#1C54C0", // Blue
6: "#17B35F", // Green
7: "#FDE14D", // Yellow
8: "#9C6EFE", // Lilac
9: "#5922CD", // Purple
}
const backgroundColorMap = {
0: '#ECE6FFFF', //Ivory
1: "#F9E6FFFF", //Misty Rose
2: "#FFE6E6FF", //Pink Quartz
3: "#FFF6E6FF", //Peach Cream
4: "#FAFFE6FF", //Lemon Sorbet
5: "#E7FFE6FF", //Spring Green
6: "#E6FFEFFF", //Sky Blue
7: "#E6FFFEFF", //Turquoise Water
8: "#AFA582FF", //Green Tea
9: "#AF8D82FF", //Dark Chestnut
}
const maxLen = {
1: 100, //Small
2: 115, //Medium
3: 130, //Large
4: 140, //Giant
}
// Traits
let treeHeight;
let branchCount;
let apple;
let bird;
let backgroundColor;
let branchColor;
let leavesColor;
let leavesRadius;
let branchCurve;
let trunkCurve;
let branchWidth;
// Retrieve content inscription id
let mintText = document.getElementById('preview').getAttribute('mint')
// Check no mint provided
if(mintText.includes('MINT_INSCRIPTION_ID')) {
let input = document.getElementById('blk');
input.style.display = 'block';
input.style.position = 'absolute';
input.style.fontSize = '20px';
input.style.margin = '20px';
input.style.top = '0';
input.value = blockNumber;
input.addEventListener('input',(event) => {
blockNumber = input.value;
generateTree();
})
generateTree();
}
// Mint was provided
else {
const request = new XMLHttpRequest()
try {
request.open('GET', '/content/' + mintText);
request.responseType = 'text';
request.addEventListener('load', () => initialize(request.response));
request.addEventListener('error', () => console.error('XHR error'));
request.send();
} catch (error) {
console.error(`XHR error ${request.status}`);
}
}
function initialize(result) {
if(result) {
console.log('Result', result);
data = JSON.parse(result);
blockNumber = data.blk;
}
generateTree();
}
function getTreeHeight(lastThreeDigits) {
if (lastThreeDigits < 400) {
return maxLen[1];
} else if (lastThreeDigits >= 400 && lastThreeDigits <= 600) {
return maxLen[2];
} else if (lastThreeDigits > 600 && lastThreeDigits <= 900) {
return maxLen[3];
} else {
return maxLen[4];
}
}
function getBranchCurve(lastTwoDigits) {
/*
BranchCurve <= 15 = Light
15 < BranchCurve <= 26 = Medium
26 < BranchCurve <= 40 = Bushy
*/
if (lastTwoDigits <= 1) {
return 13 + lastTwoDigits;
} else if (lastTwoDigits < 7 && lastTwoDigits > 1) {
return lastTwoDigits * 4;
} else if (lastTwoDigits >= 7 && lastTwoDigits <= 40) {
return lastTwoDigits;
} else {
let t = lastTwoDigits / 25;
let p = lastTwoDigits - 25;
return Math.round(p / t);
}
}
function getApple(lastTwoDigits) {
return lastTwoDigits === 80 || lastTwoDigits === 90 || lastTwoDigits === 50;
}
function getBird(lastThreeDigits) {
return lastThreeDigits === 180 || lastThreeDigits === 116 || lastThreeDigits === 100;
}
function getLeavesColor() {
let number = blockNumber.toString().slice(-4);
let sum = number.split('').reduce((sum, digit) => sum + parseInt(digit, 10), 0);
if (sum > 9) {
return leavesColorMap[parseInt(sum.toString().slice(-1))];
}
return leavesColorMap[sum];
}
function getBackgroundColor() {
let number = blockNumber.toString().slice(-4);
let sum = number.split('').reduce((sum, digit) => sum + parseInt(digit, 10), 0);
if (sum > 9) {
return backgroundColorMap[parseInt(sum.toString().slice(-1))];
}
return backgroundColorMap[sum];
}
function isPalindrome(number) {
const numberStr = number.toString();
return numberStr === numberStr.split('').reverse().join('');
}
function getBranchCount() {
let lastThreeDigits = parseInt(blockNumber.toString().slice(-3));
let lastTwoDigits = parseInt(blockNumber.toString().slice(-2));
if (lastTwoDigits <= 10) {
return 2;
} else if (isPalindrome(lastTwoDigits)) {
return 4;
} else if (isPalindrome(lastThreeDigits)) {
return 3;
}
return 2;
}
function getLeavesRadius() {
if (blockNumber % 50 === 0) {
return 15; //Wide
} else if (blockNumber % 10 === 0) {
return 12; //Normal
}
return 10; //Narrow
}
function pow() {
let numberStr = blockNumber.toString()
let exponent = 7
let power = 1
while (true) {
let exponentStr = Math.pow(exponent, power).toString()
if (numberStr.includes(exponentStr)) {
return true
}
if (Math.pow(exponent, power) > blockNumber) break
power++
}
return false
}
function getTrunkCurve() {
if (parseInt(blockNumber.toString().slice(-3)) === 180) {
return 50; //Extra
} else if (pow()) {
return 5; //Light
}
return 0; //None
}
function calculateSumOfDigits(number) {
return number.toString().split('').reduce((sum, digit) => sum + parseInt(digit, 10), 0);
}
function getBranchWidth() {
const modifiedNumber = calculateSumOfDigits(blockNumber) ^ 123;
const weightedNumber = modifiedNumber % 100;
if (weightedNumber < 55) return 15; //Thin
else if (weightedNumber < 77) return 29; //Medium
else if (weightedNumber < 87) return 36; //Thick
else if (weightedNumber < 92) return 50; //Gigantic
else return 9.8; //Slender
}
function drawApple(x, y) {
ctx.beginPath();
ctx.fillStyle = 'red';
ctx.arc(x, y, 10, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
}
function drawBird(x, y) {
ctx.fillStyle = branchColor;
ctx.fillRect(x, y + 15, 10, 3);
// Body
ctx.fillStyle = 'brown';
ctx.fillRect(x, y, 13, 10);
// Head
ctx.fillStyle = 'brown';
ctx.fillRect(x + 13, y - 5, 10, 10);
// Eye
ctx.fillStyle = 'black';
ctx.fillRect(x + 20, y - 3, 2, 2);
// Beak
ctx.fillStyle = 'orange';
ctx.beginPath();
ctx.moveTo(x + 23, y - 5);
ctx.lineTo(x + 28, y);
ctx.lineTo(x + 23, y + 5);
ctx.fill();
ctx.save();
// Wing
ctx.translate(x + 3, y + 2);
let wingRotation = 2 * Math.PI;
ctx.rotate(wingRotation);
ctx.beginPath();
ctx.arc(0, 0, 5, 0, Math.PI/1.3);
ctx.fillStyle = 'black';
ctx.fill();
ctx.closePath();
ctx.restore();
// Legs
ctx.fillStyle = 'black';
ctx.fillRect(x + 5, y + 10, 2, 5);
}
function drawTree(x, y, len, angle, branchWidth) {
ctx.beginPath();
ctx.save();
ctx.strokeStyle = branchColor;
ctx.fillStyle = leavesColor;
ctx.shadowBlur = 2;
ctx.shadowColor = 'black';
ctx.lineWidth = branchWidth;
ctx.translate(x, y);
ctx.rotate(angle * Math.PI/180);
ctx.moveTo(0,0);
if (angle > 0){
ctx.bezierCurveTo(trunkCurve, -len/2, trunkCurve, -len/2, 0, -len);
} else {
ctx.bezierCurveTo(trunkCurve, -len/2, -trunkCurve, -len/2, 0, -len);
}
ctx.stroke();
if (len < 5) {
branch = branch + 1;
ctx.beginPath();
ctx.arc(0, -len, leavesRadius, 0, Math.PI/2);
ctx.fill();
ctx.restore();
if (branch % 60 === 0 && apple) {
drawApple(0, -len);
}
return;
}
drawTree(0, -len, len * 0.7, angle + branchCurve, branchWidth * 0.6);
drawTree(0, -len, len * 0.7, angle - branchCurve, branchWidth * 0.6);
if (len === treeHeight && branchCount === 3) {
drawTree(0, -len, len * 0.7, 0, branchWidth * 0.6);
} else if (len === treeHeight && branchCount === 4) {
drawTree(0, -len, len * 0.7, angle - branchCurve / 2, branchWidth * 0.6);
drawTree(0, -len, len * 0.7, angle + branchCurve / 2, branchWidth * 0.6);
}
ctx.restore();
}
function generateTree() {
const digits = blockNumber.padStart(7, '0').split('').map(Number).reverse();
ctx.clearRect(0,0,canvas.width, canvas.height);
// Traits
treeHeight = getTreeHeight(parseInt(blockNumber.toString().slice(-3)));
branchCount = getBranchCount();
apple = getApple(parseInt(blockNumber.toString().slice(-2)));
bird = getBird(parseInt(blockNumber.toString().slice(-3)));
backgroundColor = getBackgroundColor();
branchColor = branchColorMap[digits[0]];
leavesColor = getLeavesColor();
leavesRadius = getLeavesRadius();
branchCurve = getBranchCurve(parseInt(blockNumber.toString().slice(-2)));
trunkCurve = getTrunkCurve();
branchWidth = getBranchWidth();
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
let centerPointX = canvas.width/2;
branch = 0;
drawTree(centerPointX, canvas.height - 80, treeHeight, 0, branchWidth);
if (bird) {
drawBird(centerPointX + branchWidth/2, canvas.height - 150);
}
}
function resizeCanvas() {
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
const newWidth = windowWidth;
const newHeight = windowHeight;
canvas.width = newWidth;
canvas.height = newHeight;
canvas.style.position = 'absolute';
canvas.style.left = (windowWidth - newWidth) / 2 + 'px';
canvas.style.top = (windowHeight - newHeight) / 2 + 'px';
generateTree();
}
window.addEventListener('resize', resizeCanvas, true)
resizeCanvas()
</script>