const target = document.getElementById("comments");
target.style.backgroundColor = "rgba(192,192,255,0.75)";
target.style.padding = "0.5em";
target.style.borderRadius = "0.5em";
const header = document.createElement("p");
header.innerHTML = "Comments - click to display area of interest
";
const body = document.createElement("div");
commentList = document.createElement("ul");
commentList.id = "commentlist";
body.appendChild(commentList);
const nick = document.createElement("input");
nick.id = "comment-nick";
nick.title = "Username for comment";
const nickLabel = document.createElement("label");
nickLabel.htmlFor = "comment-nick";
const input = document.createElement("input");
input.title = "Comment text";
input.size = "100";
const submit = document.createElement("button");
submit.textContent = "submit";
submit.title = "Submit comment";
const info = document.createElement("p");
info.innerHTML = "Tap coordinates on the final image or timelapse to set area and time of interest. Submitting a comment will make your username/chosen nickname public. Do not abuse.";
const footer = document.createElement("p");
footer.style.fontFamily = "monospace";
footer.textContent = "";
target.appendChild(header);
const hideComments = document.getElementById("hidecomments");
hideComments.onclick = function () {
body.style.display = body.style.display === "none" ? "block" : "none";
hideComments.textContent = body.style.display === "none" ? "show comments" : "hide comments";
}
target.appendChild(body);
body.appendChild(nick);
body.appendChild(nickLabel);
body.appendChild(input);
body.appendChild(submit);
body.appendChild(info);
body.appendChild(footer);
let x = NaN, y = NaN, w = NaN, h = NaN, tStart = NaN, tEnd = NaN;
let tLast, backupCanvas;
submit.onclick = function () {
const text = input.value;
input.value = "";
const data = {
text:text,
canvas: commentsCanvas,
x: x,
y: y,
w: w,
h: h,
tStart: tStart,
tEnd: tEnd
}
if (auth.authed) {
data.user = auth.user;
data.hash = auth.hash;
} else {
data.user = nick.value === "" ? "anonymous" : nick.value;
data.hash = -1;
}
fetch(`/pxlsarchive/comment.php`,
{
method: "post",
body: JSON.stringify(data),
headers: {
"content-type": "application/json"
}
}
).then(
function(result) {
while (commentList.firstChild) {
commentList.removeChild(commentList.firstChild);
}
populateComments();
}
);
}
document.addEventListener("_pxlsFiddle-auth",function () {
if (auth.authed) {
nick.value = auth.user;
nick.disabled = true;
}
});
const finalImage = document.getElementById("final");
const finalOverlay = document.getElementById("finaloverlay");
document.addEventListener("_panZoomEvent",timelapseClick);
function showArea(xPos,yPos,width,height,tStart,tEnd) {
if (typeof x === "undefined") {
// entire canvas
} else {
finalOverlay.width = finalImage.naturalWidth;
finalOverlay.height = finalImage.naturalHeight;
const ctx = finalOverlay.getContext("2d");
ctx.strokeStyle = "rgba(255,128,0,1)";
ctx.lineWidth = 8;
ctx.fillStyle = "rgba(255,128,0,0.1)";
if (isNaN(width)) {
// just a spot
ctx.beginPath();
ctx.arc(xPos+0.5,yPos+0.5,31,0,2*Math.PI)
ctx.stroke();
ctx.fill();
} else {
// region
ctx.fillRect(xPos+0.5,yPos+0.5,width,height);
ctx.rect(xPos+0.5,yPos+0.5,width,height);
ctx.stroke();
ctx.fill();
}
if (!isNaN(tStart)) {
const sources = btnTimelapse.dataset.sources.split(",");
const crop = {
x: xPos - 16,
y: yPos - 16,
w: width + 16 + 16,
h: height + 16 + 16
};
startTime = tStart;
endTime = isNaN(tEnd) ? NaN : tEnd;
panZoom.video(sources,{
crop: crop,
highlightCrop: true,
startTime: startTime - 1,
endTime: endTime + 1,
chapters:[tStart,tEnd],
timeMultiplier:30*300 // 30fps * 300s/frame
});
};
}
}
function clearArea() {
const ctx = finalOverlay.getContext("2d");
ctx.clearRect(0, 0, finalOverlay.width, finalOverlay.height);
}
function commentClick(canvas,xPos,yPos,t) {
const ctx = canvas.getContext("2d");
ctx.strokeStyle = "rgba(255,128,0,1)";
ctx.lineWidth = 4;
ctx.fillStyle = "rgba(255,128,0,0.1)";
if (isNaN(x)) {
tLast = t;
backupCanvas = document.createElement("canvas");
backupCanvas.width = canvas.width;
backupCanvas.height = canvas.height;
backupCanvasCtx = backupCanvas.getContext("2d");
backupCanvasCtx.drawImage(canvas,0,0);
x = parseInt(xPos,10);
y = parseInt(yPos,10);
ctx.beginPath();
ctx.arc(x+0.5,y+0.5,31,0,2*Math.PI)
ctx.stroke();
ctx.fill();
tStart = t;
} else {
if (t === tLast) {
ctx.drawImage(backupCanvas,0,0);
}
if (isNaN(w)) {
if (xPos < x) {
w = parseInt(x - xPos);
x = xPos
} else {
w = parseInt(xPos - x);
}
if (yPos < y) {
h = parseInt(y - yPos);
y = yPos
} else {
h = parseInt(yPos - y);
}
ctx.beginPath();
ctx.fillRect(x+0.5,y+0.5,w,h);
ctx.rect(x+0.5,y+0.5,w,h);
ctx.stroke();
ctx.fill();
if (t !== tStart) {
if (t < tStart) {
tEnd = tStart;
tStart = t;
} else {
tEnd = t;
}
}
} else {
if (t === tLast) {
ctx.drawImage(backupCanvas,0,0);
}
ctx.drawImage(backupCanvas,0,0);
x = NaN;
y = NaN;
w = NaN;
h = NaN;
tStart = NaN;
tEnd = NaN;
}
}
if (isNaN(x)) {
footer.textContent = "No coordinates set - presuming comment is for entire canvas";
} else {
if (isNaN(w)) {
footer.textContent = `Coordinate of interest set... x=${x} y=${y}`;
} else {
footer.textContent = `Rect of interest set... x=${x} y=${y} w=${w} h=${h}`;
}
}
if (!isNaN(tStart)) {
if (!isNaN(tEnd)) {
footer.textContent += ` from time index ${tStart} to time index ${tEnd}`;
} else {
footer.textContent += ` at time index ${tStart}`;
}
}
}
function timelapseClick() {
commentClick(panZoomEvent.canvas,panZoomEvent.x,panZoomEvent.y,panZoomEvent.t);
}
finalOverlay.style.pointerEvents = "none";
finalImage.onclick = function (e) {
finalOverlay.width = finalImage.naturalWidth;
finalOverlay.height = finalImage.naturalHeight;
const pos = imgZoom.getImgMousePos(finalImage,e);
commentClick(finalOverlay,pos.x,pos.y,NaN);
};
function populateComments() {
fetch(`/pxlsarchive/comment?canvas=${commentsCanvas}`).then(
function (response) {
if (response.status !== 200) {
// infobar.show(`Could not fetch ${board.config.domain} board info - status: ${response.status}`,"#fff","#800");
return;
}
response.json().then(function(comments) {
const list = commentList;
list.onclick = function (e) {
const data = e.target.dataset;
showArea(parseInt(data.x,10),parseInt(data.y,10),parseInt(data.w,10),parseInt(data.h,10),parseFloat(data.tStart),parseFloat(data.tEnd));
}
list.onmouseover = function (e) {
const data = e.target.dataset;
showArea(parseInt(data.x,10),parseInt(data.y,10),parseInt(data.w,10),parseInt(data.h,10));
}
list.onmouseout = function (e) {
clearArea(finalOverlay);
}
for (let i = 0; i < comments.length; i += 1) {
const comment = comments[i];
const commentElement = document.createElement("li");
if (comment.x) {
commentElement.dataset.x = comment.x;
commentElement.dataset.y = comment.y;
if (comment.w) {
commentElement.dataset.w = comment.w;
commentElement.dataset.h = comment.h;
}
if (comment.tStart) {
commentElement.dataset.tStart = comment.tStart;
// btnTimelapse.dataset.chapters = "1,2,3,4,5";
if (comment.tEnd) {
commentElement.dataset.tEnd = comment.tEnd;
}
}
}
commentElement.innerHTML = `${comment.authed ? "" : ""}${comment.user}${comment.authed ? "" : ""}: ${comment.tStart ? "🎞️" : (comment.w ? "◼️" : (comment.x ? "⚫" : ""))} ${comment.comment}`;
if (!comment.hidden) {
list.appendChild(commentElement);
}
}
return;
});
}
).catch(function(err) {
// infobar.show(`Could not fetch ${board.config.domain} board info - error: ${err}`,"#fff","#800");
return;
});
}
populateComments();