Challenge:
Store the profile photo as the original canvas’s URL ⇒ Get the brightness of image ⇒ get the pixels ⇒draw other words onto it
Gohai’s Code:
https://editor.p5js.org/gohai/sketches/62ntMs7t2\
Done:
MBTI 每个character解释instructions
Count age
//Age Calculation
function getPetAge() {
const value = document.getElementById("birthDisplay").value;
if (!value) return "未知";
const birth = new Date(value);
const today = new Date();
const totalMonths =
(today.getFullYear() - birth.getFullYear()) * 12 +
(today.getMonth() - birth.getMonth());
const years = Math.floor(totalMonths / 12);
const months = totalMonths % 12;
if (years === 0) {
return `${months}个月`;
} else if (months === 0) {
return `${years}岁`;
} else {
return `${years}.${months}岁`;
}
}
add hukou
Store the username ⇒ petname of “who likes you” to the profile
//script.js
// like 时发送到服务器
function like() {
if (currentIndex < profiles.length) {
const likedUsername = profiles[currentIndex].username;
fetch("/like", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
likerUsername: currentUser.username,
likerPetName: currentUser.name,
likedUsername: likedUsername,
}),
});
}
currentIndex++;
showProfile();
}
//server.js
// POST /like — 记录一个 like
app.post("/like", function (req, res) {
const { likerUsername, likerPetName, likedUsername } = req.body;
// 找到被 like 的 profile
let likedProfile = profiles.find((p) => p.username === likedUsername);
if (!likedProfile)
return res.status(404).json({ error: "Profile not found" });
// 初始化 likes 数组
if (!likedProfile.likes) likedProfile.likes = [];
// 避免同一人重复 like
if (!likedProfile.likes.includes(likerPetName)) {
likedProfile.likes.push(likerPetName);
}
// 保存到文件
fs.writeFileSync("profiles.json", JSON.stringify(profiles, null, 2));
res.json({ success: true, likesCount: likedProfile.likes.length });
});
Profile Scrolling Debug: 画图环节的touchMoved 拦截了滑动,所以要用
// 只有在画图页面才拦截触摸
const photoPage = document.getElementById("profile-photo");
if (!photoPage.classList.contains("active")) {
return true; // 👈 其他页面放行,允许正常滚动
}
进入app的时候 会被通知被谁喜欢了:
Count Likes/Dislikes and add to the database
// script.js
// 进入 app 时检查通知
function checkNotifications() {
if (!currentUser) return;
fetch(`/notifications/${currentUser.username}`)
.then((res) => res.json())
.then((data) => {
if (data.likesCount > 0) {
alert(
`💗 你有 ${data.likesCount} 个宠物喜欢你!\n来自: ${data.likedBy.join(", ")}`,
);
}
});
}
// server.js
// GET /notifications/:username — 获取被 like 的通知
app.get("/notifications/:username", function (req, res) {
const username = req.params.username;
const profile = profiles.find((p) => p.username === username);
if (!profile) return res.status(404).json({ error: "Not found" });
res.json({
likesCount: profile.likes ? profile.likes.length : 0,
likedBy: profile.likes || [],
});
});
Login: 密码/username错了通知, 用它们判断是否是login还是register After Login, distinguish who has already registered and enter the swiping page directly. If username is right but password is wrong ⇒ Give a hint
function handleLogin() {
const username = document.getElementById("username").value.trim();
const password = document.getElementById("password").value.trim();
if (!username) return alert("请输入用户名 / Please enter username");
// 从服务器拿所有 profiles,检查是否已存在
fetch("/profiles")
.then((res) => res.json())
.then((data) => {
const existing = data.find(
(p) => p.username === username && p.password === password,
);
if (existing) {
currentUser = existing;
// 老用户 → 直接进入 swipe
checkNotifications();
createSwipeCard();
} else {
const userExists = data.find((p) => p.username === username);
if (userExists) {
// username 存在但密码错
alert("密码错误 / Wrong password");
} else {
// 新用户 → 走注册流程
goTo("profile-name");
}
}
});
}