Davide Tantillo 3b5d74e0e8 overlay 4
2024-09-26 14:22:58 +02:00

252 lines
8.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OverlayCanvas Example</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.content {
margin: 0 auto;
}
.spine-div {
border: 1px solid black;
/* padding: 20px; */
margin-bottom: 20px;
}
.spacer {
height: 250px;
}
#canvas {
will-change: transform;
}
.resize-handle {
width: 20%;
height: 20%;
background-color: #007bff;
position: absolute;
bottom: 0;
right: 0;
cursor: se-resize;
}
</style>
<!-- <script src="../dist/iife/spine-webgl.js"></script> -->
<!-- <script src="./spine-webgl.min.js"></script> -->
<script src="./spine-webgl.js"></script>
</head>
<body>
<div class="content">
<h1>Spine Canvas Overlay Example</h1>
<div id="spineboy1" class="spine-div" style="width: 200px; height: 300px; margin-left: 200px; touch-action:none; position:relative;" div-spine>
<div id="resizeHandle" class="resize-handle"></div>
<h2>Drag and resize me</h2>
<h3>Mode: inside</h3>
<h4>Spineboy will be resize to remain into the div.</h4>
<h4>Skeleton cannot be reused (side effect on skeleton scale).</h4>
</div>
<div class="spacer"></div>
<div id="spineboy2" class="spine-div" style="width: 50%; margin-left: 50%; touch-action:none" div-spine2>
<h2>Drag me</h2>
<h3>Mode: origin</h3>
<h4>You can easily change the position using offset or percentage of html element axis (origin is top-left)</h4>
<h4>Skeleton can be reused.</h4>
</div>
<div class="spacer"></div>
<div id="spineboy3" class="spine-div" style="width: 50%; margin-left: 50%; touch-action:none" div-spine2>
<h3>Skeleton of previous box is being reused here</h3>
</div>
<div class="spacer"></div>
<div class="spine-div" div-spine3>
<h3>Initializer with NodeList</h3>
</div>
<div class="spine-div" div-spine3>
<h3>Initializer with NodeList</h3>
</div>
<div class="spacer"></div>
<div class="spine-div" style="width: 50%; height: 200px;" div-spine4>
<h3>Initializer with HTMLElement</h3>
</div>
<div class="spacer"></div>
<p>End of content.</p>
</div>
<script>
const divs = document.querySelectorAll(`[div-spine]`);
const overlay = new spine.SpineCanvasOverlay();
const p = overlay.addSkeleton(
{
atlasPath: "assets/spineboy-pma.atlas",
skeletonPath: "assets/spineboy-pro.skel",
scale: .5,
animation: 'walk',
},
[
{
element: divs[0],
mode: 'inside',
showBounds: true,
},
],
);
setTimeout(async () => {
const { skeleton, state } = await p;
state.setAnimation(0, "run", true);
overlay.recalculateBounds(skeleton, state);
}, 1000)
const divs2 = document.querySelectorAll(`[div-spine2]`);
const p2 = overlay.addSkeleton({
atlasPath: "assets/celestial-circus-pma.atlas",
skeletonPath: "assets/celestial-circus-pro.skel",
animation: 'swing',
scale: .5,
},
[
{
element: divs2[0],
mode: 'origin',
showBounds: true,
xAxis: .5,
yAxis: 1,
// offsetX: 100
},
{
element: divs2[1],
mode: 'origin',
showBounds: true,
offsetX: 100,
offsetY: -50
},
],);
p2.then(({ state }) => state.setAnimation(1, "eyeblink", true));
const divs3 = document.querySelectorAll(`[div-spine3]`);
const p3 = overlay.addSkeleton({
atlasPath: "assets/raptor-pma.atlas",
skeletonPath: "assets/raptor-pro.skel",
animation: 'walk',
scale: .5,
}, divs3);
const divs4 = document.querySelectorAll(`[div-spine4]`);
const p4 = overlay.addSkeleton({
atlasPath: "assets/tank-pma.atlas",
skeletonPath: "assets/tank-pro.skel",
animation: 'shoot',
scale: .5,
}, divs4[0]);
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// Drag utility
function makeDraggable(element) {
let isDragging = false;
let startX, startY;
let originalX, originalY;
element.addEventListener('pointerdown', startDragging);
document.addEventListener('pointermove', drag);
document.addEventListener('pointerup', stopDragging);
function startDragging(e) {
e.preventDefault();
if (e.target === document.getElementById('resizeHandle')) return;
isDragging = true;
startX = e.clientX;
startY = e.clientY;
const translate = element.style.transform;
if (translate !== '') {
const translateValues = translate.match(/translate\(([^)]+)\)/)[1].split(', ');
originalX = parseFloat(translateValues[0]);
originalY = parseFloat(translateValues[1]);
} else {
originalX = 0;
originalY = 0;
}
}
function drag(e) {
if (!isDragging) return;
const deltaX = e.clientX - startX;
const deltaY = e.clientY - startY;
element.style.transform = `translate(${originalX + deltaX}px, ${originalY + deltaY}px)`;
e.preventDefault();
}
function stopDragging(e) {
isDragging = false;
e.preventDefault();
}
}
makeDraggable(document.getElementById('spineboy1'));
makeDraggable(document.getElementById('spineboy2'));
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// Resize utility
const resizableDiv = document.getElementById('spineboy1');
const resizeHandle = document.getElementById('resizeHandle');
let isResizing = false;
let startX, startY, startWidth, startHeight;
resizeHandle.addEventListener('pointerdown', initResize);
function initResize(e) {
isResizing = true;
startX = e.clientX;
startY = e.clientY;
startWidth = resizableDiv.offsetWidth;
startHeight = resizableDiv.offsetHeight;
document.addEventListener('pointermove', resize);
document.addEventListener('pointerup', stopResize);
}
function resize(e) {
if (!isResizing) return;
const width = startWidth + (e.clientX - startX);
const height = startHeight + (e.clientY - startY);
resizableDiv.style.width = width + 'px';
resizableDiv.style.height = height + 'px';
}
function stopResize() {
isResizing = false;
document.removeEventListener('pointermove', resize);
document.removeEventListener('pointerup', stopResize);
}
</script>
</body>
</html>