2024-02-25 09:31:53 -05:00
|
|
|
let area = document.querySelector('#area-main');
|
|
|
|
const treeWidth = 2;
|
|
|
|
const treeHeight = 120;
|
|
|
|
const magConst = 150;
|
|
|
|
|
|
|
|
const itemWidth = 120;
|
|
|
|
const itemHeight = 90;
|
|
|
|
|
2024-10-18 23:27:11 -04:00
|
|
|
let cache = '';
|
|
|
|
|
|
|
|
function escapeHtml(unsafe) {
|
|
|
|
return (unsafe + '')
|
|
|
|
.replace(/&/g, "&")
|
|
|
|
.replace(/</g, "<")
|
|
|
|
.replace(/>/g, ">")
|
|
|
|
.replace(/"/g, """)
|
|
|
|
.replace(/'/g, "'");
|
|
|
|
}
|
2024-10-18 23:36:03 -04:00
|
|
|
function genElement(type, area, content, attribs, open = false) {
|
2024-02-25 09:31:53 -05:00
|
|
|
|
|
|
|
var directAttribs = attribs.direct || {};
|
|
|
|
var styleAttribs = attribs.style || {};
|
|
|
|
|
|
|
|
var fullStyle = "";
|
|
|
|
|
|
|
|
Object.keys(styleAttribs).forEach(function (attrib) {
|
|
|
|
fullStyle += `${attrib}: ${styleAttribs[attrib]};`
|
|
|
|
});
|
|
|
|
|
|
|
|
directAttribs.style = fullStyle;
|
|
|
|
|
2024-10-18 23:27:11 -04:00
|
|
|
var elem = '';
|
|
|
|
|
2024-02-25 09:31:53 -05:00
|
|
|
Object.keys(directAttribs).forEach(function (attrib) {
|
2024-10-18 23:27:11 -04:00
|
|
|
elem += `${escapeHtml(attrib)}="${escapeHtml(directAttribs[attrib])}" `;
|
2024-02-25 09:31:53 -05:00
|
|
|
});
|
|
|
|
|
2024-10-18 23:36:03 -04:00
|
|
|
if (open) {
|
|
|
|
|
|
|
|
elem = `<${type} ${elem}>${content}`
|
|
|
|
} else {
|
|
|
|
|
2024-10-18 23:27:11 -04:00
|
|
|
elem = `<${type} ${elem}>${content}</${type}>`
|
2024-10-18 23:36:03 -04:00
|
|
|
}
|
2024-02-25 09:31:53 -05:00
|
|
|
|
2024-10-18 23:27:11 -04:00
|
|
|
cache += elem;
|
2024-02-25 09:31:53 -05:00
|
|
|
|
|
|
|
return elem;
|
|
|
|
}
|
|
|
|
|
|
|
|
function genEntry(posEntry, area, fetchData) {
|
|
|
|
var data = fetchData[posEntry.id] || {};
|
|
|
|
|
|
|
|
var x = posEntry.x * magConst;
|
|
|
|
var y = posEntry.y * treeHeight;
|
|
|
|
|
2024-10-18 23:27:11 -04:00
|
|
|
var x2 = x * zoom + mpos[0];
|
|
|
|
var y2 = y * zoom + mpos[1];
|
|
|
|
|
2024-10-18 23:36:03 -04:00
|
|
|
if (y2 < -1000 || y2 > area2.clientHeight+ 1000) return;
|
2024-10-18 23:27:11 -04:00
|
|
|
|
2024-02-25 09:31:53 -05:00
|
|
|
if (y > 0) {
|
|
|
|
genElement('path', area, '', {
|
|
|
|
'direct': {
|
|
|
|
'class': 'line',
|
|
|
|
'd': `M ${x + (itemWidth / 2)} ${y - treeHeight + itemHeight / 2} v ${itemHeight} z`
|
|
|
|
}
|
2024-10-18 23:27:11 -04:00
|
|
|
});
|
2024-02-25 09:31:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (posEntry.offbranch >= 0) {
|
|
|
|
genElement('path', area, '', {
|
|
|
|
'direct': {
|
|
|
|
'class': 'line',
|
|
|
|
'd': `M ${x + (itemWidth / 2)} ${y + itemHeight / 2} h ${magConst * (posEntry.offbranch)} z`
|
|
|
|
}
|
2024-10-18 23:27:11 -04:00
|
|
|
});
|
2024-02-25 09:31:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
let a = genElement('a', area, '', {
|
|
|
|
'direct': {
|
|
|
|
'href': `https://scratch.mit.edu/projects/${posEntry.id}`,
|
|
|
|
'class': `${posEntry.visible ? '' : 'red'}`,
|
|
|
|
}
|
2024-10-18 23:36:03 -04:00
|
|
|
}, true);
|
2024-02-25 09:31:53 -05:00
|
|
|
|
|
|
|
genElement('image', a, '', {
|
|
|
|
'direct': {
|
|
|
|
'href': `https://uploads.scratch.mit.edu/get_image/project/${posEntry.id}_1920x1080.png`,
|
2024-10-18 23:27:11 -04:00
|
|
|
'x': x - 10,
|
|
|
|
'y': y - 15,
|
2024-02-25 09:31:53 -05:00
|
|
|
'width': '100'
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-10-18 23:36:03 -04:00
|
|
|
cache += '</a>';
|
|
|
|
|
2024-02-25 09:31:53 -05:00
|
|
|
let text = [
|
|
|
|
`${posEntry.name}`,
|
|
|
|
`${posEntry.y} proj. deep`,
|
|
|
|
`${(posEntry.date) ? (new Date(posEntry.date.$date) + '').split('GMT')[0] : 'Date not available'}`,
|
|
|
|
`${posEntry.user}`
|
|
|
|
];
|
|
|
|
|
|
|
|
for (let i in text) {
|
|
|
|
|
|
|
|
genElement('text', a, text[i], {
|
|
|
|
'direct': {
|
2024-10-18 23:27:11 -04:00
|
|
|
'x': x + 75,
|
|
|
|
'y': y + 75 + 8 * i
|
2024-02-25 09:31:53 -05:00
|
|
|
}
|
2024-10-18 23:27:11 -04:00
|
|
|
});
|
2024-02-25 09:31:53 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function genTree(id) {
|
|
|
|
let params = new URLSearchParams(window.location.search);
|
|
|
|
|
|
|
|
let treeId = params.get("id").replace(/[^0-9]/g, '');
|
|
|
|
if (id) treeId = id;
|
|
|
|
|
|
|
|
let fetchData = await fetch(`https://scratch.mit.edu/projects/${treeId}/remixtree/bare`)
|
|
|
|
.then(x => x.json());
|
|
|
|
|
|
|
|
let keys = Object.keys(fetchData);
|
|
|
|
|
2024-10-18 23:27:11 -04:00
|
|
|
let r = fetchData[fetchData.root_id];
|
2024-02-25 09:31:53 -05:00
|
|
|
|
2024-10-18 23:27:11 -04:00
|
|
|
let i = 0;
|
|
|
|
for (let id of keys) {
|
|
|
|
if (id == fetchData.root_id || id == 'root_id') continue;
|
2024-02-25 09:31:53 -05:00
|
|
|
|
2024-10-18 23:27:11 -04:00
|
|
|
if (!fetchData[id].parent_id && keys.findIndex(x => fetchData[x].children && fetchData[x].children.indexOf(id) != -1) == -1) {
|
|
|
|
r.children.push(id);
|
2024-02-25 09:31:53 -05:00
|
|
|
}
|
2024-10-18 23:27:11 -04:00
|
|
|
i++;
|
|
|
|
console.log(i)
|
|
|
|
};
|
2024-02-25 09:31:53 -05:00
|
|
|
|
|
|
|
let pos = await main(fetchData);
|
|
|
|
|
2024-10-18 23:27:11 -04:00
|
|
|
setInterval(function () {
|
|
|
|
cache = '';
|
|
|
|
for (let posEntry of pos) {
|
|
|
|
genEntry(posEntry, area, fetchData);
|
|
|
|
}
|
|
|
|
area.innerHTML = cache;
|
2024-10-18 23:36:03 -04:00
|
|
|
}, 300)
|
2024-02-25 09:31:53 -05:00
|
|
|
|
|
|
|
return pos;
|
|
|
|
}
|