wry host: sites as apps, the rig as a face; join loads the expression skill
This commit is contained in:
parent
d7965a57fd
commit
9ec031c8a8
12 changed files with 730 additions and 11 deletions
80
assets/face/index.html
Normal file
80
assets/face/index.html
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0; padding: 0; height: 100%; width: 100%;
|
||||
background: transparent; overflow: hidden;
|
||||
-webkit-user-select: none; user-select: none;
|
||||
}
|
||||
#live2d-widget { position: fixed; inset: 0; }
|
||||
#live2d { width: 100%; height: 100%; }
|
||||
#bubble {
|
||||
position: fixed; left: 8px; right: 8px; top: 12px;
|
||||
padding: 10px 14px; border-radius: 14px;
|
||||
background: rgba(20,20,24,0.82); color: #f2f2f2;
|
||||
font: 15px/1.35 system-ui, sans-serif;
|
||||
opacity: 0; transition: opacity .2s ease;
|
||||
}
|
||||
#bubble.up { opacity: 1; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="live2d-widget"><canvas id="live2d"></canvas></div>
|
||||
<div id="bubble"></div>
|
||||
<script src="rig://localhost/live2d/js/live2d.js"></script>
|
||||
<script>
|
||||
// The character layer, reduced to what the shell drives. The reference's
|
||||
// message.js owns idle chatter, a talk box and sessionStorage position; none of
|
||||
// that belongs here — the shell owns the conversation and the summoning, and
|
||||
// idle chatter that is hers comes from the subconscious, not a random line
|
||||
// table (TASK-59 Q2).
|
||||
(function () {
|
||||
var canvas = document.getElementById('live2d');
|
||||
var bubble = document.getElementById('bubble');
|
||||
var model = null;
|
||||
|
||||
function fit() {
|
||||
canvas.width = window.innerWidth * window.devicePixelRatio;
|
||||
canvas.height = window.innerHeight * window.devicePixelRatio;
|
||||
}
|
||||
window.addEventListener('resize', fit);
|
||||
fit();
|
||||
|
||||
// loadlive2d is live2d.js's entry point: canvas id, model.json url.
|
||||
try {
|
||||
loadlive2d('live2d', 'rig://localhost/live2d/model/histoire/model.json');
|
||||
} catch (e) {
|
||||
console.error('rig failed to load', e);
|
||||
}
|
||||
|
||||
var hideAt = null;
|
||||
window.face = {
|
||||
// One line of her speech. Called repeatedly as tokens stream, so it
|
||||
// replaces rather than appends — the shell holds the accumulated text.
|
||||
say: function (text) {
|
||||
bubble.textContent = text;
|
||||
bubble.classList.add('up');
|
||||
hideAt = Date.now() + 6000;
|
||||
},
|
||||
clear: function () { bubble.classList.remove('up'); },
|
||||
// Posture from the shell. The rig's own motion groups are named by the
|
||||
// reference (idle, tap); anything richer waits on her own rig.
|
||||
posture: function (name) {
|
||||
if (typeof window.live2dMotion === 'function') window.live2dMotion(name);
|
||||
}
|
||||
};
|
||||
|
||||
setInterval(function () {
|
||||
if (hideAt && Date.now() > hideAt) { hideAt = null; window.face.clear(); }
|
||||
}, 500);
|
||||
|
||||
canvas.addEventListener('click', function () {
|
||||
if (window.souveraine) window.souveraine.tapped('body');
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in a new issue