首页宝宝踢:脚印改成脚掌轮廓 + 五个脚趾(v26110646)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
deploy
2026-11-07 10:15:25 +00:00
parent 95c274a074
commit fab95c6c0b
3 changed files with 24 additions and 18 deletions

View File

@@ -456,23 +456,29 @@
}
cx.restore();
}
// 脚印:脚跟 / 足弓外沿 / 前掌 / 五个脚趾,单位坐标(脚尖朝 -y),整体缩到鼓包的 0.62
const FOOT = [[0, .42, .2], [.1, .12, .15], [-.02, -.18, .24], [-.17, -.5, .1], [-.04, -.57, .08], [.07, -.55, .07], [.16, -.5, .06], [.23, -.41, .055]];
/* 脚印(11-07 重画):一整块脚掌轮廓(脚跟 → 内侧足弓收窄 → 前掌)+ 五个脚趾,单位坐标(脚尖朝 -y,大脚趾在 -x 一侧)。
11-07 用户:「力度大一点,能看出小脚印这种」→ 原来是 8 个极淡的软圆点(0.075),看不出是脚;
改成实心 + shadowBlur 软边的暖灰压痕(峰值约 0.34),左上错开一层白当受光沿,顶到一小半就开始显出来 */
const TOES = [[-.12, -.5, .078, .092], [-.01, -.54, .056, .066], [.075, -.515, .049, .057], [.142, -.465, .043, .05], [.192, -.395, .037, .044]];
function soleShape(dx, dy) {
cx.beginPath();
cx.moveTo(dx, .52 + dy);
cx.bezierCurveTo(-.16 + dx, .52 + dy, -.17 + dx, .3 + dy, -.12 + dx, .16 + dy);
cx.bezierCurveTo(-.08 + dx, .05 + dy, -.21 + dx, -.08 + dy, -.21 + dx, -.22 + dy);
cx.bezierCurveTo(-.21 + dx, -.36 + dy, -.07 + dx, -.41 + dy, .04 + dx, -.385 + dy);
cx.bezierCurveTo(.16 + dx, -.36 + dy, .225 + dx, -.26 + dy, .205 + dx, -.12 + dy);
cx.bezierCurveTo(.185 + dx, .04 + dy, .15 + dx, .2 + dy, .14 + dx, .32 + dy);
cx.bezierCurveTo(.13 + dx, .46 + dy, .1 + dx, .52 + dy, dx, .52 + dy);
for (const [tx, ty, trx, try_] of TOES) { cx.moveTo(tx + dx + trx, ty + dy); cx.ellipse(tx + dx, ty + dy, trx, try_, 0, 0, 7); }
cx.fill();
}
function footprint(x, y, rx, ry, ang, k) {
/* 11-07 用户:「能看出小脚印」→ 原来是全软边的极淡阴影(0.075),实际看不出来。
改成实心中间 + 软边的压痕(暖灰,峰值约 0.38),左上错开一层白边当受光沿,顶到一小半就开始显出来 */
if (k < .15) return;
const a = Math.min(1, (k - .15) / .6), f = .72;
cx.save(); cx.translate(x, y); cx.rotate(ang); cx.scale(rx, ry);
const dot = (ox, oy, r, rgb, al) => {
const g = cx.createRadialGradient(ox, oy, 0, ox, oy, r);
g.addColorStop(0, 'rgba(' + rgb + ',' + al.toFixed(3) + ')');
g.addColorStop(.55, 'rgba(' + rgb + ',' + (al * .8).toFixed(3) + ')');
g.addColorStop(1, 'rgba(' + rgb + ',0)');
cx.fillStyle = g; cx.beginPath(); cx.arc(ox, oy, r, 0, 7); cx.fill();
};
for (const [px, py, r] of FOOT) dot(px * f - .025, py * f - .03, r * f * 1.25, '255,255,255', .32 * a);
for (const [px, py, r] of FOOT) dot(px * f, py * f, r * f * 1.05, '120,72,58', .38 * a);
const a = Math.min(1, (k - .15) / .6), f = .9;
cx.save(); cx.translate(x, y); cx.rotate(ang); cx.scale(rx * f, ry * f);
cx.shadowBlur = 5 * dpr;
cx.fillStyle = cx.shadowColor = 'rgba(255,255,255,' + (.3 * a).toFixed(3) + ')'; soleShape(-.025, -.03);
cx.fillStyle = cx.shadowColor = 'rgba(120,72,58,' + (.34 * a).toFixed(3) + ')'; soleShape(0, 0);
cx.restore();
}
function paint() {