Removed useless changes on other classes.

This commit is contained in:
Davide Tantillo 2024-09-26 14:41:08 +02:00
parent e9873147c2
commit 9399c42ec7
13 changed files with 23 additions and 5694 deletions

View File

@ -94,7 +94,6 @@ export class AssetManagerBase implements Disposable {
this.assetsLoaded[path] = new Promise<any>((resolve, reject) => {
this.downloader.downloadBinary(path, (data: Uint8Array): void => {
// setTimeout(() => this.success(success, path, data), 10000);
this.success(success, path, data);
resolve(data);
}, (status: number, responseText: string): void => {
@ -136,7 +135,6 @@ export class AssetManagerBase implements Disposable {
});
}
// TODO: refactor assetsLoaded and assets (we should probably merge them)
reuseAssets(path: string,
success: (path: string, data: any) => void = () => { },
error: (path: string, message: string) => void = () => { }) {
@ -375,7 +373,6 @@ export class AssetManagerBase implements Disposable {
export class Downloader {
private callbacks: StringMap<Array<Function>> = {};
rawDataUris: StringMap<string> = {};
cacheTextures: Record<string, Texture> = {};
dataUriToString (dataUri: string) {
if (!dataUri.startsWith("data:")) {

View File

@ -1,187 +0,0 @@
<!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;
}
</style>
<script src="./spine-webgl.min.js"></script>
<!-- <script src="../dist/iife/spine-webgl.min.js"></script> -->
</head>
<body>
<canvas id="canvas" style="position: fixed; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none;"></canvas>
<div class="content">
<h1>OverlayCanvas Example</h1>
<p>Scroll down to div.</p>
<div class="spacer"></div>
<div class="spine-div" div-spine>
<h2>Spine Box 1</h2>
</div>
<div class="spacer"></div>
<div class="spine-div" div-spine>
<h2>Spine Box 2</h2>
</div>
<div class="spacer"></div>
<div class="spine-div" style="width: 50%; margin-left: 50%;" div-spine>
<h2>Spine Box 3</h2>
</div>
<div class="spacer"></div>
<div class="spine-div" style="width: 50%; margin-left: 50%;" div-raptor>
<h2>Raptor Box</h2>
</div>
<div class="spacer"></div>
<div class="spine-div" style="width: 50%; margin-left: 20%;" div-celeste>
<h2>Celeste Box</h2>
</div>
<p>End of content.</p>
</div>
<script>
class App {
constructor() {
const selectors = ['div-spine', 'div-raptor', 'div-celeste'];
this.selectorToDiv = selectors.reduce((acc, next) => {
acc[next] = {
divs: document.querySelectorAll(`[${next}]`),
skeleton: null,
};
return acc;
}, {})
let divs = Array.from(document.querySelectorAll('[div-spine]'));
let divRaptor = Array.from(document.querySelectorAll('[div-raptor]'))[0];
console.log(this.selectorToDiv)
}
loadAssets(canvas) {
canvas.assetManager.loadBinary("assets/spineboy-pro.skel");
canvas.assetManager.loadTextureAtlas("assets/spineboy-pma.atlas");
canvas.assetManager.loadBinary("assets/raptor-pro.skel");
canvas.assetManager.loadTextureAtlas("assets/raptor-pma.atlas");
canvas.assetManager.loadBinary("assets/celestial-circus-pro.skel");
canvas.assetManager.loadTextureAtlas("assets/celestial-circus-pma.atlas");
}
initialize(canvas) {
let assetManager = canvas.assetManager;
this.selectorToDiv['div-spine'].skeleton = initializeSkeleton(assetManager, "assets/spineboy-pma.atlas", "assets/spineboy-pro.skel", .5, "walk");
this.selectorToDiv['div-raptor'].skeleton = initializeSkeleton(assetManager, "assets/raptor-pma.atlas", "assets/raptor-pro.skel", .5, "walk");
this.selectorToDiv['div-celeste'].skeleton = initializeSkeleton(assetManager, "assets/celestial-circus-pma.atlas", "assets/celestial-circus-pro.skel", .2, "swing");
}
update(canvas, delta) {
for (let { skeleton: { skeleton, state } } of Object.values(this.selectorToDiv)) {
state.update(delta);
state.apply(skeleton);
skeleton.update(delta);
skeleton.updateWorldTransform(spine.Physics.update);
}
}
render(canvas) {
let renderer = canvas.renderer;
renderer.resize(spine.ResizeMode.Expand);
canvas.clear(0, 0, 0, 0);
// webgl canvas center
const vec3 = new spine.Vector3(0, 0);
renderer.camera.worldToScreen(vec3, canvas.htmlCanvas.clientWidth, canvas.htmlCanvas.clientHeight);
// loop over the skeleton/div comination
for (let { divs, skeleton } of Object.values(this.selectorToDiv)) {
// loop over each div where to render the current skeleton
for (let div of divs) {
const rect = div.getBoundingClientRect();
rect.x *= window.devicePixelRatio;
rect.y *= window.devicePixelRatio;
// if (rect.bottom > 0 && rect.top < window.innerHeight) {
// renderer.drawSkeleton(skeleton.skeleton, true, -1, -1, (vertices, size, vertexSize) => {
// for (let i = 0; i < size; i+=vertexSize) {
// vertices[i] = vertices[i] + rect.x - vec3.x * window.devicePixelRatio;
// vertices[i+1] = vertices[i+1] - rect.y + vec3.y * window.devicePixelRatio;
// }
// });
renderer.begin();
skeleton.skeleton.x = rect.x - vec3.x * window.devicePixelRatio;
skeleton.skeleton.y = - rect.y + vec3.y * window.devicePixelRatio;
renderer.drawSkeleton(skeleton.skeleton, true);
// show center
const root = skeleton.skeleton.getRootBone();
const vec3Root = new spine.Vector3(root.x, root.y);
renderer.camera.worldToScreen(vec3Root, canvas.htmlCanvas.clientWidth, canvas.htmlCanvas.clientHeight);
renderer.circle(
true,
rect.x - vec3.x * window.devicePixelRatio,
-rect.y + vec3.y * window.devicePixelRatio,
20,
{ r: 1, g: 0, b: 0, a: .5 });
renderer.end();
// }
}
}
// Complete rendering.
}
}
const htmlCanvas = document.getElementById("canvas");
new spine.SpineCanvas(htmlCanvas, {
app: new App()
})
function initializeSkeleton(assetManager, atlas, skeletonFile, scale, animation) {
var atlas = assetManager.require(atlas);
var atlasLoader = new spine.AtlasAttachmentLoader(atlas);
var skeletonBinary = new spine.SkeletonBinary(atlasLoader);
skeletonBinary.scale = scale;
var skeletonData = skeletonBinary.readSkeletonData(assetManager.require(skeletonFile));
const skeleton = new spine.Skeleton(skeletonData);
var animationStateData = new spine.AnimationStateData(skeletonData);
const animationState = new spine.AnimationState(animationStateData);
animationState.setAnimation(0, animation, true);
return { skeleton, state: animationState }
}
</script>
</body>
</html>

View File

@ -1,382 +0,0 @@
<!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;
}
</style>
<script src="../dist/iife/spine-webgl.js"></script>
<!-- <script src="./spine-webgl.min.js"></script> -->
</head>
<body>
<canvas id="canvas" style="display: none;"></canvas>
<div class="content">
<h1>OverlayCanvas Example</h1>
<p>Scroll down to div.</p>
<div class="spacer"></div>
<div class="spine-div" div-spine>
<h2>Spine Box 1</h2>
</div>
<div class="spacer"></div>
<div id="spineboy2" class="spine-div" style="width: 50%; margin-left: 50%; touch-action:none" div-spine>
<h2>Spine Box 2 (drag me)</h2>
</div>
<div class="spacer"></div>
<div id="raptor" class="spine-div" style="width: 50%; margin-left: 50%; transition: transform 1s linear;" div-raptor>
<h2>Raptor Box</h2>
</div>
<div class="spacer"></div>
<div class="spine-div" style="width: 50%; margin-left: 20%;" div-celeste>
<h2>Celeste Box</h2>
</div>
<p>End of content.</p>
</div>
<script>
let selectorToDiv;
class App {
constructor() {
const selectors = ['div-spine', 'div-raptor', 'div-celeste'];
selectorToDiv = selectors.reduce((acc, next) => {
const divs = document.querySelectorAll(`[${next}]`);
acc[next] = {
divs: [...document.querySelectorAll(`[${next}]`)].map(div => {
const position = {};
return { div, position };
}),
skeleton: null,
};
return acc;
}, {})
}
loadAssets(canvas) {
canvas.assetManager.loadBinary("assets/spineboy-pro.skel");
canvas.assetManager.loadTextureAtlas("assets/spineboy-pma.atlas");
canvas.assetManager.loadBinary("assets/raptor-pro.skel");
canvas.assetManager.loadTextureAtlas("assets/raptor-pma.atlas");
canvas.assetManager.loadBinary("assets/celestial-circus-pro.skel");
canvas.assetManager.loadTextureAtlas("assets/celestial-circus-pma.atlas");
}
prevScrollLeft = 0;
prevScrollTop = 0;
initialize(canvas) {
let assetManager = canvas.assetManager;
selectorToDiv['div-spine'].skeleton = initializeSkeleton(assetManager, "assets/spineboy-pma.atlas", "assets/spineboy-pro.skel", .5, "walk");
selectorToDiv['div-raptor'].skeleton = initializeSkeleton(assetManager, "assets/raptor-pma.atlas", "assets/raptor-pro.skel", .5, "walk");
selectorToDiv['div-celeste'].skeleton = initializeSkeleton(assetManager, "assets/celestial-circus-pma.atlas", "assets/celestial-circus-pro.skel", .2, "swing");
window.addEventListener('scroll', () => {
// console.log("canceling: " + canvas.reqAnimationFrameId);
// cancelAnimationFrame(canvas.reqAnimationFrameId);
// canvas.loop();
// console.log(this.prevScrollTop, window.pageYOffset, this.prevScrollTop === window.pageYOffset);
// this.prevScrollTop = window.pageYOffset;
// this.render(canvas, true);
});
window.addEventListener('resize', () => {
canvas.renderer.resize(spine.ResizeMode.Expand);
});
const bodyObserver = new ResizeObserver(() => {
canvas.renderer.resize(spine.ResizeMode.Expand);
});
bodyObserver.observe(document.body);
canvas.renderer.resize(spine.ResizeMode.Expand);
}
update(canvas, delta) {
for (let { skeleton: { skeleton, state } } of Object.values(selectorToDiv)) {
state.update(delta);
state.apply(skeleton);
skeleton.update(delta);
skeleton.updateWorldTransform(spine.Physics.update);
}
}
render(canvas, scroll) {
let renderer = canvas.renderer;
// renderer.resize(spine.ResizeMode.Expand);
canvas.clear(0, 0, 0, 0);
renderer.begin();
// webgl canvas center
const vec3 = new spine.Vector3(0, 0);
renderer.camera.worldToScreen(vec3, canvas.htmlCanvas.clientWidth, canvas.htmlCanvas.clientHeight);
// loop over the skeleton/div comination
for (const { divs, skeleton } of Object.values(selectorToDiv)) {
// loop over each div where to render the current skeleton
for (const { position, div } of divs) {
// const rect = div.getBoundingClientRect();
// rect.x *= window.devicePixelRatio;
// rect.y *= window.devicePixelRatio;
// TODO-WIP: experiment with caching div position to prevent the transform in the for loop
// Need to find a reliable way to get notified when div origin change position
let { x, y } = position;
if (x === undefined || y === undefined) {
const bounds = div.getBoundingClientRect();
x = bounds.x;
y = bounds.y;
} else {
const bounds = div.getBoundingClientRect();
x = bounds.x;
y = bounds.y;
}
const scrollTop = window.pageYOffset;
const scrollLeft = window.pageXOffset;
position.x = (x + scrollLeft) * window.devicePixelRatio;
position.y = (y + scrollTop) * window.devicePixelRatio;
const rect = { x: position.x, y: position.y };
// if (rect.bottom > 0 && rect.top < window.innerHeight) {
// renderer.drawSkeleton(skeleton.skeleton, true, -1, -1, (vertices, size, vertexSize) => {
// for (let i = 0; i < size; i+=vertexSize) {
// vertices[i] = vertices[i] + rect.x - vec3.x * window.devicePixelRatio;
// vertices[i+1] = vertices[i+1] - rect.y + vec3.y * window.devicePixelRatio;
// }
// });
// if (position.x == rect.x && position.y == rect.y) {
// renderer.drawSkeleton(skeleton.skeleton, true);
// } else {
renderer.drawSkeleton(skeleton.skeleton, true, -1, -1, (vertices, size, vertexSize) => {
for (let i = 0; i < size; i+=vertexSize) {
vertices[i] = vertices[i] + rect.x - vec3.x * window.devicePixelRatio;
vertices[i+1] = vertices[i+1] - rect.y + vec3.y * window.devicePixelRatio;
}
});
// position.x = rect.x;
// position.y = rect.y;
// }
// skeleton.skeleton.x = rect.x - vec3.x * window.devicePixelRatio,
// skeleton.skeleton.y = -rect.y + vec3.y * window.devicePixelRatio,
// renderer.drawSkeleton(skeleton.skeleton, true);
// show center
const root = skeleton.skeleton.getRootBone();
const vec3Root = new spine.Vector3(root.x, root.y);
renderer.camera.worldToScreen(vec3Root, canvas.htmlCanvas.clientWidth, canvas.htmlCanvas.clientHeight);
renderer.circle(
true,
rect.x - vec3.x * window.devicePixelRatio,
-rect.y + vec3.y * window.devicePixelRatio,
20,
{ r: 1, g: 0, b: 0, a: 1 }
);
// }
}
}
// Complete rendering.
renderer.end();
}
}
const htmlCanvas = document.getElementById("canvas");
function updateCanvasSize(htmlCanvas) {
htmlCanvas.style.position = 'absolute';
htmlCanvas.style.top = '0';
htmlCanvas.style.left = '0';
const pageSize = getPageSize();
htmlCanvas.style.width = pageSize.width + 'px';
htmlCanvas.style.height = pageSize.height + 'px';
htmlCanvas.style.display = 'inline';
htmlCanvas.style["pointer-events"] = 'none';
}
const app = new spine.SpineCanvas(htmlCanvas, {
app: new App()
})
function initializeSkeleton(assetManager, atlas, skeletonFile, scale, animation) {
var atlas = assetManager.require(atlas);
var atlasLoader = new spine.AtlasAttachmentLoader(atlas);
var skeletonBinary = new spine.SkeletonBinary(atlasLoader);
skeletonBinary.scale = scale;
var skeletonData = skeletonBinary.readSkeletonData(assetManager.require(skeletonFile));
const skeleton = new spine.Skeleton(skeletonData);
var animationStateData = new spine.AnimationStateData(skeletonData);
const animationState = new spine.AnimationState(animationStateData);
animationState.setAnimation(0, animation, true);
return { skeleton, state: animationState }
}
function getPageSize() {
const width = Math.max(
document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth
);
const height = Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight,
document.body.offsetHeight,
document.documentElement.offsetHeight,
document.documentElement.clientHeight
);
return { width, height };
}
const canvasXY = htmlCanvas.getBoundingClientRect()
const resizeObserver = new ResizeObserver(() => {
updateCanvasSize(htmlCanvas);
});
resizeObserver.observe(document.body);
//////////
//////////
//////////
//////////
//////////
function addRandomDiv() {
const div = document.createElement('div');
div.style.width = Math.floor(Math.random() * 200 + 100) + 'px';
div.style.height = Math.floor(Math.random() * 100 + 50) + 'px';
div.style.margin = '10px';
div.style.touchAction = 'none';
div.className = 'spine-div';
const divType = getRandomSpineDiv();
div.setAttribute(divType, '');
div.innerText = "Drag me";
console.log(app)
selectorToDiv[divType].divs.push({ div, position: {} });
makeDraggable(div);
document.body.appendChild(div);
}
function getRandomSpineDiv() {
const divs = ['div-spine', 'div-raptor', 'div-celeste'];
return divs[Math.floor(Math.random() * 3)];
}
// Add a button to trigger new div creation
const addDivButton = document.createElement('button');
addDivButton.textContent = 'Add New Div at the bottome of the page';
addDivButton.style.position = 'fixed';
addDivButton.style.top = '10px';
addDivButton.style.left = '10px';
addDivButton.style.zIndex = '1000';
addDivButton.addEventListener('click', addRandomDiv);
document.body.appendChild(addDivButton);
//////
//////
//////
//////
//////
let isMovingRight = true;
setInterval(() => {
const div = document.getElementById('raptor');
let position = isMovingRight ? 50 : -50;
isMovingRight = !isMovingRight;
div.style.transform = `translateX(${position}px)`;
}, 1000)
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) {
isDragging = true;
startX = e.clientX;
startY = e.clientY;
const translate = element.style.transform;
if (translate !== '') {
// Extract the translate values from the transform string
const translateValues = translate.match(/translate\(([^)]+)\)/)[1].split(', ');
originalX = parseFloat(translateValues[0]);
originalY = parseFloat(translateValues[1]);
} else {
// If there is no transform, return 0,0
originalX = 0;
originalY = 0;
}
// Prevent text selection during drag
e.preventDefault();
}
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();
}
}
const draggableDiv = document.getElementById('spineboy2');
makeDraggable(draggableDiv);
</script>
</body>
</html>

View File

@ -1,324 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGL Overlay Example</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
/* top: 0;
left: 0; */
}
.content {
margin: 0 auto;
}
.spine-div {
border: 1px solid black;
padding: 20px;
margin-top: 20px;
margin-bottom: 20px;
position:relative;
touch-action:none;
}
.spacer {
height: 250px;
}
#canvas {
/* will-change: transform; */
}
</style>
<script src="../dist/iife/spine-webgl.js"></script>
<!-- <script src="./spine-webgl.min.js"></script> -->
<!-- <script src="./spine-webgl.js"></script> -->
</head>
<body>
<span id="fps" style="position: fixed; top: 0; left: 0">a</span>
<div class="content">
<div id="spineboy1" class="spine-div" style="width: 200px; height: 300px; margin-left: 200px;" div-spine>
<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%;" 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%;" div-spine2>
<h3>Skeleton of previous box is being reused here</h3>
</div>
<div class="spacer"></div>
<div id="spineboy4" class="spine-div" div-spine3>
<h3>Initializer with NodeList</h3>
</div>
<div id="spineboy5" class="spine-div" div-spine3>
<h3>Initializer with NodeList</h3>
</div>
<div class="spacer"></div>
<div id="spineboy6" class="spine-div" style="width: 50%; height: 200px;" div-spine4>
<h3>Initializer with HTMLElement</h3>
</div>
<div class="spacer"></div>
<div id="spineboy7" class="spine-div" style="width: 50%; height: 200px;" div-spine5>
<h3>Bounds using a Spine ounding box</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,
draggable: true,
},
],
);
// setTimeout(async () => {
// const { skeleton, state } = await p;
// state.setAnimation(0, "portal", true);
// overlay.recalculateBounds(skeleton);
// }, 1000)
const divs2 = document.querySelectorAll(`[div-spine2]`);
const p2 = overlay.addSkeleton({
atlasPath: "assets/celestial-circus-pma.atlas",
skeletonPath: "assets/celestial-circus-pro.skel",
animation: 'wings-and-feet',
scale: .25,
},
[
{
element: divs2[0],
mode: 'origin',
// showBounds: true,
xAxis: .5,
yAxis: 1,
draggable: true,
},
{
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,
}, [{
element: divs4[0],
showBounds: true,
}]);
const divs5 = document.querySelectorAll(`[div-spine5]`);
const p5 = overlay.addSkeleton({
atlasPath: "assets/spineboy-pma.atlas",
skeletonPath: "assets/spineboy-pro.skel",
animation: 'walk',
update: (_, delta, skeleton, state) => {
state.update(delta / 3);
state.apply(skeleton);
skeleton.update(delta / 3);
skeleton.updateWorldTransform(spine.Physics.update);
}
}, [{
element: divs5[0],
showBounds: true,
mode: 'inside',
draggable: true,
}]);
p5.then(({ skeleton }) => {
const bbAttachmentSlot = skeleton.findSlot("head-bb");
const currentAttachment = bbAttachmentSlot.attachment;
skeleton.setAttachment("head-bb", "head");
const bbAttachment = bbAttachmentSlot.attachment;
const computedVertices = [];
bbAttachment.computeWorldVertices(bbAttachmentSlot, 0, bbAttachment.worldVerticesLength, computedVertices, 0, 2);
const vertices = computedVertices;
let x = Infinity, maxX = -Infinity, y = Infinity, maxY = -Infinity;
for (let i = 0; i < vertices.length; i+=2) {
x = Math.min(vertices[i], x);
y = Math.min(vertices[i+1], y);
maxX = Math.max(vertices[i], maxX);
maxY = Math.max(vertices[i+1], maxY);
}
const width = maxX - x;
const height = maxY - y;
console.log({ x, y, width, height })
overlay.setBounds(skeleton, { x, y, width, height })
bbAttachmentSlot.setAttachment(currentAttachment)
})
// setTimeout(async () => {
// overlay.dispose();
// }, 2000)
makeResizable(document.getElementById('spineboy1'))
// makeDraggable(document.getElementById('spineboy1'));
makeResizable(document.getElementById('spineboy2'))
makeDraggable(document.getElementById('spineboy2'));
makeResizable(document.getElementById('spineboy7'))
makeDraggable(document.getElementById('spineboy7'));
makeResizable(document.getElementById('spineboy3'))
makeDraggable(document.getElementById('spineboy3'));
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// 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) {
if (e.target === element.querySelector('#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)`;
}
function stopDragging(e) {
isDragging = false;
}
}
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// Resize utility
function makeResizable(element) {
const resizeHandle = document.createElement('div');
element.appendChild(resizeHandle);
resizeHandle.id = "resizeHandle";
resizeHandle.style.width = "20%";
resizeHandle.style.height = "20%";
resizeHandle.style.bottom = "0";
resizeHandle.style.right = "0";
resizeHandle.style.position = "absolute";
resizeHandle.style["background-color"] = "#007bff";
resizeHandle.style["cursor"] = "se-resize";
let isResizing = false;
let startX, startY, startWidth, startHeight, startPaddingLeft, startPaddingRight, startPaddingTop, startPaddingBottom;
resizeHandle.addEventListener('pointerdown', initResize);
function initResize(e) {
isResizing = true;
startX = e.clientX;
startY = e.clientY;
startWidth = element.offsetWidth;
startHeight = element.offsetHeight;
startPaddingLeft = parseFloat(window.getComputedStyle(element).paddingLeft);
startPaddingRight = parseFloat(window.getComputedStyle(element).paddingRight);
startPaddingTop = parseFloat(window.getComputedStyle(element).paddingTop);
startPaddingBottom = parseFloat(window.getComputedStyle(element).paddingBottom);
document.addEventListener('pointermove', resize);
document.addEventListener('pointerup', stopResize);
}
function resize(e) {
if (!isResizing) return;
const width = startWidth + (e.clientX - startX) - startPaddingLeft - startPaddingRight;
const height = startHeight + (e.clientY - startY) - startPaddingTop - startPaddingBottom;
element.style.width = width + 'px';
element.style.height = height + 'px';
}
function stopResize() {
isResizing = false;
document.removeEventListener('pointermove', resize);
document.removeEventListener('pointerup', stopResize);
}
}
</script>
</body>
</html>

View File

@ -1,831 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="../dist/iife/spine-webgl.js"></script>
<!-- <script src="./spine-webgl.js"></script> -->
<title>JS Library Showcase</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: Arial, sans-serif;
}
.section {
/* height: 100lvh; */
/* height: 800px; */
display: flex;
justify-content: center;
align-items: center;
color: white;
background-color: #3498db;
}
.split {
display: flex;
}
.split-left, .split-right {
width: 50%;
min-height: 50%;
padding: 1rem;
margin: 1rem;
border: 1px solid salmon;
}
.split-nosize {
/* padding: 1rem; */
/* margin: 1rem; */
border: 1px solid salmon;
}
.navigation {
display: flex;
position: fixed;
left: 20px;
bottom: 20px;
transform: translateY(-50%);
}
.nav-btn {
display: block;
margin: 0px 5px;
padding: 10px;
background-color: rgba(255, 255, 255, 0.7);
border: none;
cursor: pointer;
}
.vertical-split {
display: flex;
flex-direction: column;
}
.split-top {
width: 100%;
height: 600px;
}
.split-bottom {
width: 100%;
/* height: 600px; */
}
.split-top {
display: flex;
justify-content: center;
align-items: center;
}
.split-bottom {
background-color: #1e1e1e;
color: #d4d4d4;
overflow: auto;
}
.split-bottom pre {
height: 100%;
margin: 0;
}
.split-bottom code {
font-family: 'Consolas', 'Courier New', monospace;
font-size: 12px;
line-height: 1.5;
display: block;
padding: 1rem;
}
</style>
</head>
<body>
<span id="fps" style="position: fixed; top: 0; left: 0">FPS</span>
<!--
/////////////////////
// start section 0 //
/////////////////////
-->
<div id="section0" class="section vertical-split">
<div class="split-top split">
<div class="split-left">
aaa
</div>
<div class="split-right" id="section0-element">
<spine identifier="section0" createDiv="true" width="220" height="50"/>
</div>
</div>
<div class="split-bottom">
<pre><code id="code-display">
</code></pre>
</div>
</div>
<!--
/////////////////////
// end section 0 //
/////////////////////
-->
<!--
/////////////////////
// start section 1 //
/////////////////////
-->
<div id="section1" class="section vertical-split">
<div class="split-top split">
<div class="split-left" id="section1-element">
</div>
<div class="split-right">
</div>
</div>
<div class="split-bottom">
<pre><code id="code-display">
const overlay = new spine.SpineCanvasOverlay();
overlay.addSkeleton(
{
atlasPath: "assets/spineboy-pma.atlas",
skeletonPath: "assets/spineboy-pro.skel",
animation: 'walk',
},
document.getElementById(`section1-element`),
);
</code></pre>
</div>
</div>
<!--
/////////////////////
// end section 1 //
/////////////////////
-->
<!--
/////////////////////
// start section 2 //
/////////////////////
-->
<div id="section2" class="section vertical-split">
<div class="split-top split">
<div class="split-left">
Mode <code>origin</code> uses the HTML element top-left corner as origin for the skeleton. <br>
You are responsible to scale the skeleton using this mode. <br>
Move the origin by a percentage of the div width and height by using <code>xAxis</code> and <code>yAxis</code> respectively.
</div>
<div class="split-right" id="section2-element">
</div>
</div>
<div class="split-bottom">
<pre><code id="code-display">
overlay.addSkeleton(
{
atlasPath: "assets/spineboy-pma.atlas",
skeletonPath: "assets/spineboy-pro.skel",
animation: 'run',
scale: .25,
},
{
element: document.getElementById(`section2-element`),
mode: 'origin',
xAxis: .5,
yAxis: 1,
},
);
</code></pre>
</div>
</div>
<!--
/////////////////////
// end section 2 //
/////////////////////
-->
<!--
/////////////////////
// start section 3 //
/////////////////////
-->
<div id="section3" class="section vertical-split">
<div class="split-top split">
<div class="split-left" id="section3-element">
</div>
<div class="split-right">
Use <code>offsetX</code> and <code>offsetY</code> to move you skeleton left or right by the pixel amount you specify.
This works for both mode <code>origin</code> and <code>inside</code>.
</div>
</div>
<div class="split-bottom">
<pre><code id="code-display">
overlay.addSkeleton(
{
atlasPath: "assets/spineboy-pma.atlas",
skeletonPath: "assets/spineboy-pro.skel",
animation: 'run',
},
{
element: document.getElementById(`section3-element`),
mode: 'inside', // default
offsetX: 100,
offsetY: 50,
},
);
</code></pre>
</div>
</div>
<!--
/////////////////////
// end section 3 //
/////////////////////
-->
<!--
/////////////////////
// start section 4 //
/////////////////////
-->
<div id="section4" class="section vertical-split">
<div class="split-top split">
<div class="split-left">
You can easily access the <code>Skeleton</code> and the <code>AnimationState</code> of your character, and use them as if you were using <code>spine-webgl</code>. <br>
If you change animation, you can ask to scale the skeleton based on the new animation.
</div>
<div class="split-right" id="section4-element">
</div>
</div>
<div class="split-bottom">
<pre><code id="code-display">
// access the skeleton and the state asynchronously
const { skeleton, state } = await overlay.addSkeleton(
{
atlasPath: "assets/raptor-pma.atlas",
skeletonPath: "assets/raptor-pro.skel",
animation: 'walk',
},
document.getElementById(`section4-element`)
);
let isRoaring = false;
setInterval(() => {
const newAnimation = isRoaring ? "walk" : "roar";
state.setAnimation(0, newAnimation, true);
overlay.recalculateBounds(skeleton); // scale the skeleton based on the new animation
isRoaring = !isRoaring;
}, 4000);
</code></pre>
</div>
</div>
<!--
/////////////////////
// end section 4 //
/////////////////////
-->
<!--
/////////////////////
// start section 5 //
/////////////////////
-->
<div id="section5" class="section vertical-split">
<div class="split-top split">
<div class="split-left">
You can also set a custom bounds to center a specific element or area of you animation in the div.
</div>
<div class="split-right" id="section5-element">
TODO
</div>
</div>
<div class="split-bottom">
<pre><code id="code-display">
</code></pre>
</div>
</div>
<!--
/////////////////////
// end section 5 //
/////////////////////
-->
<!--
/////////////////////
// start section 6 //
/////////////////////
-->
<div id="section6" class="section vertical-split">
<div class="split-top split">
<div class="split-left">
Moving the div will move the skeleton origin. <br>
Resizing the div will resize the skeleton in <code>inside</code> mode, but not in <code>origin</code> mode.
</div>
<div class="split-right" id="section6-element">
</div>
</div>
<div class="split-bottom">
<pre><code id="code-display">
overlay.addSkeleton(
{
atlasPath: "assets/cloud-pot-pma.atlas",
skeletonPath: "assets/cloud-pot.skel",
animation: 'playing-in-the-rain',
},
document.getElementById(`section6-element`)
);
</code></pre>
</div>
</div>
<!--
/////////////////////
// end section 6 //
/////////////////////
-->
<!--
/////////////////////
// start section 7 //
/////////////////////
-->
<div id="section7" class="section vertical-split">
<div class="split-top split">
<div class="split-left">
You can view the skeleton world origin (green), the root bone position (red), and the bounds rectangle and center (blue) by setting <code>debug</code> to <code>true</code>.
</div>
<div class="split-right" id="section7-element">
</div>
</div>
<div class="split-bottom">
<pre><code id="code-display">
overlay.addSkeleton(
{
atlasPath: "assets/owl-pma.atlas",
skeletonPath: "assets/owl-pro.skel",
animation: 'idle',
},
{
element: document.getElementById(`section7-element`),
debug: true,
}
);
</code></pre>
</div>
</div>
<!--
/////////////////////
// end section 7 //
/////////////////////
-->
<!--
/////////////////////
// start section 8 //
/////////////////////
-->
<div id="section8" class="section vertical-split">
<div class="split-top split">
<div class="split-left">
As a bonus item, you can move you skeleton around just by setting the <code>draggable</code> property to <code>true</code>.
</div>
<div class="split-right" id="section8-element">
</div>
</div>
<div class="split-bottom">
<pre><code id="code-display">
overlay.addSkeleton(
{
atlasPath: "assets/celestial-circus-pma.atlas",
skeletonPath: "assets/celestial-circus-pro.skel",
animation: 'wings-and-feet',
},
{
element: document.getElementById(`section8-element`),
draggable: true,
}
);
</code></pre>
</div>
</div>
<!--
/////////////////////
// end section 8 //
/////////////////////
-->
<!-- <div class="navigation">
<button class="nav-btn" onclick="scrollToSection('section1')">1</button>
<button class="nav-btn" onclick="scrollToSection('section2')">2</button>
<button class="nav-btn" onclick="scrollToSection('section3')">3</button>
<button class="nav-btn" onclick="scrollToSection('section4')">4</button>
<button class="nav-btn" onclick="scrollToSection('section5')">5</button>
<button class="nav-btn" onclick="scrollToSection('section6')">6</button>
<button class="nav-btn" onclick="scrollToSection('section7')">7</button>
<button class="nav-btn" onclick="scrollToSection('section8')">8</button>
</div> -->
<script>
function scrollToSection(id) {
document.getElementById(id).scrollIntoView({ behavior: 'smooth' });
}
let sections = document.querySelectorAll('.section');
let currentSection = 0;
// window.addEventListener('wheel', (e) => {
// if (e.deltaY > 0 && currentSection < sections.length - 1) {
// currentSection++;
// } else if (e.deltaY < 0 && currentSection > 0) {
// currentSection--;
// }
// sections[currentSection].scrollIntoView({ behavior: 'smooth' });
// });
</script>
<script>
(async () => {
const overlay = new spine.SpineCanvasOverlay();
// overlay.addSkeleton(
// {
// atlasPath: "assets/spineboy-pma.atlas",
// skeletonPath: "assets/spineboy-pro.skel",
// // scale: 1,
// // animation: 'walk',
// },
// {
// mode: "origin",
// xAxis: 1,
// yAxis: 1,
// element: document.querySelectorAll(`#section1-element`)[0],
// debug: true
// }
// );
/////////////////////
// start section 1 //
/////////////////////
overlay.addSkeleton(
{
atlasPath: "assets/spineboy-pma.atlas",
skeletonPath: "assets/spineboy-pro.skel",
animation: 'walk',
},
[
{
identifier: `section0`,
debug: true,
}
]
);
/////////////////////
// end section 1 //
/////////////////////
// /////////////////////
// // start section 1 //
// /////////////////////
// overlay.addSkeleton(
// {
// atlasPath: "assets/spineboy-pma.atlas",
// skeletonPath: "assets/spineboy-pro.skel",
// animation: 'walk',
// },
// document.querySelectorAll(`#section1-element`),
// );
// /////////////////////
// // end section 1 //
// /////////////////////
// /////////////////////
// // start section 2 //
// /////////////////////
// overlay.addSkeleton(
// {
// atlasPath: "assets/spineboy-pma.atlas",
// skeletonPath: "assets/spineboy-pro.skel",
// animation: 'run',
// scale: .25,
// },
// {
// element: document.getElementById(`section2-element`),
// mode: 'origin',
// xAxis: .5,
// yAxis: 1,
// },
// );
// /////////////////////
// // end section 2 //
// /////////////////////
// /////////////////////
// // start section 3 //
// /////////////////////
// overlay.addSkeleton(
// {
// atlasPath: "assets/spineboy-pma.atlas",
// skeletonPath: "assets/spineboy-pro.skel",
// animation: 'jump',
// },
// {
// element: document.getElementById(`section3-element`),
// mode: 'inside', // default
// offsetX: 100,
// offsetY: 50,
// },
// );
// /////////////////////
// // end section 3 //
// /////////////////////
// /////////////////////
// // start section 4 //
// /////////////////////
// const { skeleton, state } = await overlay.addSkeleton(
// {
// atlasPath: "assets/raptor-pma.atlas",
// skeletonPath: "assets/raptor-pro.skel",
// animation: 'walk',
// },
// document.getElementById(`section4-element`)
// );
// let isRoaring = false;
// setInterval(() => {
// const newAnimation = isRoaring ? "walk" : "roar";
// state.setAnimation(0, newAnimation, true);
// overlay.recalculateBounds(skeleton);
// isRoaring = !isRoaring;
// }, 4000);
// /////////////////////
// // end section 4 //
// /////////////////////
// /////////////////////
// // start section 5 //
// /////////////////////
// // const { skeleton: skeleton5 } = await overlay.addSkeleton(
// // {
// // atlasPath: "assets/spineboy-pma.atlas",
// // skeletonPath: "assets/spineboy-pro.skel",
// // animation: 'walk',
// // },
// // document.getElementById(`section5-element`)
// // );
// // const bbAttachmentSlot = skeleton5.findSlot("head-bb");
// // const currentAttachment = bbAttachmentSlot.attachment;
// // skeleton5.setAttachment("head-bb", "head");
// // const bbAttachment = bbAttachmentSlot.attachment;
// // const computedVertices = [];
// // bbAttachment.computeWorldVertices(bbAttachmentSlot, 0, bbAttachment.worldVerticesLength, computedVertices, 0, 2);
// // const vertices = computedVertices;
// // let x = Infinity, maxX = -Infinity, y = Infinity, maxY = -Infinity;
// // for (let i = 0; i < vertices.length; i+=2) {
// // x = Math.min(vertices[i], x);
// // y = Math.min(vertices[i+1], y);
// // maxX = Math.max(vertices[i], maxX);
// // maxY = Math.max(vertices[i+1], maxY);
// // }
// // const width = maxX - x;
// // const height = maxY - y;
// // console.log({ x, y, width, height })
// // overlay.setBounds(skeleton5, { x, y, width, height })
// // bbAttachmentSlot.setAttachment(currentAttachment)
// /////////////////////
// // end section 5 //
// /////////////////////
// /////////////////////
// // start section 6 //
// /////////////////////
// overlay.addSkeleton(
// {
// atlasPath: "assets/cloud-pot-pma.atlas",
// skeletonPath: "assets/cloud-pot.skel",
// animation: 'playing-in-the-rain',
// },
// document.getElementById(`section6-element`)
// );
// /////////////////////
// // end section 6 //
// /////////////////////
// /////////////////////
// // start section 7 //
// /////////////////////
// overlay.addSkeleton(
// {
// atlasPath: "assets/owl-pma.atlas",
// skeletonPath: "assets/owl-pro.skel",
// animation: 'idle',
// },
// {
// element: document.getElementById(`section7-element`),
// debug: true,
// }
// );
// //////////////////////
// // end section 7 //
// //////////////////////
// /////////////////////
// // start section 8 //
// /////////////////////
// overlay.addSkeleton(
// {
// atlasPath: "assets/celestial-circus-pma.atlas",
// skeletonPath: "assets/celestial-circus-pro.skel",
// animation: 'wings-and-feet',
// },
// {
// element: document.getElementById(`section8-element`),
// draggable: true,
// debug: true,
// }
// );
// //////////////////////
// // end section 8 //
// //////////////////////
})();
</script>
<script>
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// Drag utility
function makeDraggable(element) {
element.style["touch-action"] = "none";
let isDragging = false;
let startX, startY;
let originalX, originalY;
element.addEventListener('pointerdown', startDragging);
document.addEventListener('pointermove', drag);
document.addEventListener('pointerup', stopDragging);
function startDragging(e) {
if (e.target === element.querySelector('#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)`;
}
function stopDragging(e) {
isDragging = false;
}
}
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// Resize utility
function makeResizable(element) {
const resizeHandle = document.createElement('div');
element.appendChild(resizeHandle);
resizeHandle.id = "resizeHandle";
resizeHandle.style.width = "20%";
resizeHandle.style.height = "20%";
resizeHandle.style.bottom = "0";
resizeHandle.style.right = "0";
resizeHandle.style.position = "absolute";
resizeHandle.style["background-color"] = "#007bff";
resizeHandle.style["cursor"] = "se-resize";
element.style["position"] = "relative";
element.style["touch-action"] = "none";
let isResizing = false;
let startX, startY, startWidth, startHeight, startPaddingLeft, startPaddingRight, startPaddingTop, startPaddingBottom;
resizeHandle.addEventListener('pointerdown', initResize);
function initResize(e) {
isResizing = true;
startX = e.clientX;
startY = e.clientY;
startWidth = element.offsetWidth;
startHeight = element.offsetHeight;
startPaddingLeft = parseFloat(window.getComputedStyle(element).paddingLeft);
startPaddingRight = parseFloat(window.getComputedStyle(element).paddingRight);
startPaddingTop = parseFloat(window.getComputedStyle(element).paddingTop);
startPaddingBottom = parseFloat(window.getComputedStyle(element).paddingBottom);
document.addEventListener('pointermove', resize);
document.addEventListener('pointerup', stopResize);
}
function resize(e) {
if (!isResizing) return;
const width = startWidth + (e.clientX - startX) - startPaddingLeft - startPaddingRight;
const height = startHeight + (e.clientY - startY) - startPaddingTop - startPaddingBottom;
element.style.width = width + 'px';
element.style.height = height + 'px';
}
function stopResize() {
isResizing = false;
document.removeEventListener('pointermove', resize);
document.removeEventListener('pointerup', stopResize);
}
}
makeDraggable(document.getElementById(`section6-element`));
makeResizable(document.getElementById(`section6-element`));
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -1,210 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="../dist/iife/spine-webgl.js"></script>
<!-- <script src="./spine-webgl.min.js"></script> -->
<title>JS Library Showcase</title>
<style>
body {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
/* scroll-behavior: smooth; */
}
body {
font-family: Arial, sans-serif;
}
.section {
/* height: 100lvh; */
/* height: 800px; */
display: flex;
justify-content: center;
align-items: center;
color: white;
background-color: #3498db;
}
.split {
display: flex;
justify-content: center;
align-items: center;
}
.full-width {
width: 100%;
}
.split-left, .split-right {
width: 50%;
min-height: 50%;
padding: 1rem;
margin: 1rem;
border: 1px solid salmon;
}
.split-nosize {
border: 1px solid salmon;
}
.split-size {
padding: 1rem;
margin: 1rem;
}
.navigation {
display: flex;
position: fixed;
left: 20px;
bottom: 20px;
transform: translateY(-50%);
}
.nav-btn {
display: block;
margin: 0px 5px;
padding: 10px;
background-color: rgba(255, 255, 255, 0.7);
border: none;
cursor: pointer;
}
.vertical-split {
display: flex;
flex-direction: column;
}
.high-page {
height: 600px;
}
.split-top {
width: 100%;
height: 600px;
}
.split-bottom {
width: 100%;
/* height: 600px; */
}
.split-bottom {
background-color: #1e1e1e;
color: #d4d4d4;
overflow: auto;
}
.split-bottom pre {
height: 100%;
margin: 0;
}
.split-bottom code {
font-family: 'Consolas', 'Courier New', monospace;
font-size: 12px;
line-height: 1.5;
display: block;
padding: 1rem;
}
.skin-grid {
width: 100%;
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: space-evenly;
padding: 20px;
box-sizing: border-box;
}
.skin-grid-element {
border: 1px solid #ccc;
width: 150px;
aspect-ratio: 3 / 3;
}
</style>
<script>
function escapeHTMLandInject(text) {
const escaped = text
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
document.currentScript.parentElement.innerHTML = escaped;
}
</script>
</head>
<body>
<!-- <div style="height: 1200px; flex-direction: column;">
</div> -->
<!--
/////////////////////
// start section 1 //
/////////////////////
-->
<div id="section1" class="section vertical-split">
<div class="split-top split">
<div class="split-left">
<spine-widget
atlas="assets/raptor-pma.atlas"
skeleton="assets/raptor-pro.skel"
animation="walk"
scale="3"
clip="true"
fit="height"
></spine-widget>
</div>
<div class="split-right">
<spine-widget
atlas="assets/spineboy-pma.atlas"
skeleton="assets/spineboy-pro.skel"
animation="walk"
scale="1.5"
fit="none"
clip="true"
></spine-widget>
</div>
<div class="split-right">
<spine-widget
atlas="assets/spineboy-pma.atlas"
skeleton="assets/spineboy-pro.skel"
animation="walk"
scale="1"
fit="none"
clip="true"
></spine-widget>
</div>
<!-- <div class="split-right">
<spine-widget
atlas="assets/cloud-pot-pma.atlas"
skeleton="assets/cloud-pot.skel"
animation="playing-in-the-rain"
draggable="true"
></spine-widget>
</div>
<div class="split-right">
<spine-widget
atlas="assets/celestial-circus-pma.atlas"
skeleton="assets/celestial-circus-pro.skel"
animation="wings-and-feet"
draggable="true"
></spine-widget>
</div> -->
</div>
</div>
<div style="height: 1200px; flex-direction: column;">
</div>
<!--
/////////////////////
// end section 1 //
/////////////////////
-->
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -68,7 +68,7 @@ export class Input {
if (this.buttonDown) {
if (listener.dragged) listener.dragged(this.mouseX, this.mouseY, ev);
} else {
if (listener.moved) listener.moved(this.mouseX, this.mouseY);
if (listener.moved) listener.moved(this.mouseX, this.mouseY, ev);
}
});
}
@ -80,7 +80,7 @@ export class Input {
this.mouseX = ev.clientX - rect.left;;
this.mouseY = ev.clientY - rect.top;
this.buttonDown = false;
this.listeners.map((listener) => { if (listener.up) listener.up(this.mouseX, this.mouseY); });
this.listeners.map((listener) => { if (listener.up) listener.up(this.mouseX, this.mouseY, ev); });
document.removeEventListener("mousemove", mouseMove);
document.removeEventListener("mouseup", mouseUp);
@ -92,7 +92,7 @@ export class Input {
let deltaY = ev.deltaY;
if (ev.deltaMode == WheelEvent.DOM_DELTA_LINE) deltaY *= 8;
if (ev.deltaMode == WheelEvent.DOM_DELTA_PAGE) deltaY *= 24;
this.listeners.map((listener) => { if (listener.wheel) listener.wheel(ev.deltaY); });
this.listeners.map((listener) => { if (listener.wheel) listener.wheel(ev.deltaY, ev); });
};
element.addEventListener("mousedown", mouseDown, true);
@ -122,7 +122,7 @@ export class Input {
let dx = this.touch1.x - this.touch0.x;
let dy = this.touch1.x - this.touch0.x;
this.initialPinchDistance = Math.sqrt(dx * dx + dy * dy);
this.listeners.map((listener) => { if (listener.zoom) listener.zoom(this.initialPinchDistance, this.initialPinchDistance) });
this.listeners.map((listener) => { if (listener.zoom) listener.zoom(this.initialPinchDistance, this.initialPinchDistance, ev) });
}
}
if (this.preventDefault) ev.preventDefault();
@ -151,7 +151,7 @@ export class Input {
let dx = this.touch1.x - this.touch0.x;
let dy = this.touch1.x - this.touch0.x;
let distance = Math.sqrt(dx * dx + dy * dy);
this.listeners.map((listener) => { if (listener.zoom) listener.zoom(this.initialPinchDistance, distance) });
this.listeners.map((listener) => { if (listener.zoom) listener.zoom(this.initialPinchDistance, distance, ev) });
}
}
if (this.preventDefault) ev.preventDefault();
@ -171,7 +171,7 @@ export class Input {
this.touch0 = null;
this.mouseX = x;
this.mouseY = y;
this.listeners.map((listener) => { if (listener.up) listener.up(x, y) });
this.listeners.map((listener) => { if (listener.up) listener.up(x, y, ev) });
if (!this.touch1) {
this.buttonDown = false;
@ -216,9 +216,9 @@ export class Touch {
export interface InputListener {
down?(x: number, y: number, ev?: MouseEvent | TouchEvent): void;
up?(x: number, y: number): void;
moved?(x: number, y: number): void;
up?(x: number, y: number, ev?: MouseEvent | TouchEvent): void;
moved?(x: number, y: number, ev?: MouseEvent | TouchEvent): void;
dragged?(x: number, y: number, ev?: MouseEvent | TouchEvent): void;
wheel?(delta: number): void;
zoom?(initialDistance: number, distance: number): void;
wheel?(delta: number, ev?: MouseEvent | TouchEvent): void;
zoom?(initialDistance: number, distance: number, ev?: MouseEvent | TouchEvent): void;
}

View File

@ -463,24 +463,6 @@ export class SceneRenderer implements Disposable {
this.activeRenderer = null;
}
resize2 () {
let canvas = this.canvas;
this.context.gl.viewport(0, 0, canvas.width, canvas.height);
this.camera.setViewport(canvas.width, canvas.height);
this.camera.update();
}
resize3 (width: number, height: number) {
console.log("resize gl")
let canvas = this.canvas;
const dpr = window.devicePixelRatio;
this.canvas.width = Math.round(width * dpr);
this.canvas.height = Math.round(height * dpr);
this.context.gl.viewport(0, 0, canvas.width, canvas.height);
this.camera.setViewport(canvas.width, canvas.height);
this.camera.update();
}
resize (resizeMode: ResizeMode) {
let canvas = this.canvas;
var dpr = window.devicePixelRatio || 1;

View File

@ -203,8 +203,6 @@ export class SkeletonRenderer {
clipper.clipEndWithSlot(slot);
}
// console.log(renderable.vertices[1])
clipper.clipEnd();
}

View File

@ -110,7 +110,7 @@ export class SpineCanvas {
let waitForAssets = () => {
if (this.disposed) return;
if (!config.app.loadAssets || this.assetManager.isLoadingComplete()) {
if (this.assetManager.isLoadingComplete()) {
if (this.assetManager.hasErrors()) {
if (config.app.error) config.app.error(this, this.assetManager.getErrors());
} else {

View File

@ -1303,7 +1303,7 @@ class SpineWebComponentOverlay extends HTMLElement {
this.canvas.style.width = totalWidth + "px";
this.canvas.style.height = totalHeight + "px";
this.renderer.resize3(totalWidth, totalHeight);
this.resize(totalWidth, totalHeight);
}
}
@ -1333,9 +1333,19 @@ class SpineWebComponentOverlay extends HTMLElement {
widget.currentScaleDpi = scale;
});
this.renderer.resize3(parseFloat(this.canvas.style.width), parseFloat(this.canvas.style.height));
this.resize(parseFloat(this.canvas.style.width), parseFloat(this.canvas.style.height));
}
private resize(width: number, height: number) {
let canvas = this.canvas;
const dpr = window.devicePixelRatio;
this.canvas.width = Math.round(width * dpr);
this.canvas.height = Math.round(height * dpr);
this.renderer.context.gl.viewport(0, 0, canvas.width, canvas.height);
this.renderer.camera.setViewport(canvas.width, canvas.height);
this.renderer.camera.update();
}
// we need the bounding client rect otherwise decimals won't be returned
// this means that during zoom it might occurs that the div would be resized
// rounded 1px more making a scrollbar appear