Skip to content

Commit

Permalink
WIP - Add interactivity events. isdraggable is currently broken.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidetan committed Dec 19, 2024
1 parent 0ccd6e3 commit 30a2f80
Show file tree
Hide file tree
Showing 3 changed files with 331 additions and 34 deletions.
4 changes: 2 additions & 2 deletions spine-ts/spine-core/src/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ export class Color {
return Number("0x" + hex(this.r) + hex(this.g) + hex(this.b));
}

static fromString (hex: string): Color {
return new Color().setFromString(hex);
static fromString (hex: string, color = new Color()): Color {
return color.setFromString(hex);
}
}

Expand Down
101 changes: 101 additions & 0 deletions spine-ts/spine-webgl/example/webcomponent-tutorial.html
Original file line number Diff line number Diff line change
Expand Up @@ -2524,6 +2524,107 @@
(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory():typeof define==="function"&&define.amd?define(factory):(global=global||self,global.Ola=factory())})(this,function(){"use strict";const position=(x0,v0,t1,t)=>{const a=(v0*t1+2*x0)/t1**3;const b=-(2*v0*t1+3*x0)/t1**2;const c=v0;const d=x0;return a*t**3+b*t**2+c*t+d};const speed=(x0,v0,t1,t)=>{const a=(v0*t1+2*x0)/t1**3;const b=-(2*v0*t1+3*x0)/t1**2;const c=v0;return 3*a*t**2+2*b*t+c};const each=function(values,cb){const multi=typeof values==="number"?{value:values}:values;Object.entries(multi).map(([key,value])=>cb(value,key))};function Single(init,time){this.start=new Date/1e3;this.time=time;this.from=init;this.current=init;this.to=init;this.speed=0}Single.prototype.get=function(now){const t=now/1e3-this.start;if(t<0){throw new Error("Cannot read in the past")}if(t>=this.time){return this.to}return this.to-position(this.to-this.from,this.speed,this.time,t)};Single.prototype.getSpeed=function(now){const t=now/1e3-this.start;if(t>=this.time){return 0}return speed(this.to-this.from,this.speed,this.time,t)};Single.prototype.set=function(value,time){const now=new Date;const current=this.get(now);this.speed=this.getSpeed(now);this.start=now/1e3;this.from=current;this.to=value;if(time){this.time=time}return current};function Ola(values,time=300){if(typeof values==="number"){values={value:values}}each(values,(init,key)=>{const value=new Single(init,time/1e3);Object.defineProperty(values,"_"+key,{value:value});Object.defineProperty(values,"$"+key,{get:()=>value.to});Object.defineProperty(values,key,{get:()=>value.get(new Date),set:val=>value.set(val),enumerable:true})});Object.defineProperty(values,"get",{get:()=>(function(name="value",now=new Date){return this["_"+name].get(now)})});Object.defineProperty(values,"set",{get:()=>(function(values,time=0){each(values,(value,key)=>{this["_"+key].set(value,time/1e3)})})});return values}return Ola});
</script>

<!--
/////////////////////
// end section //
/////////////////////
-->

<!--
/////////////////////
// start section //
/////////////////////
-->

<div class="section vertical-split" id="above-popup">

<div class="split-top split">
<div class="split-left">
You can attach callback to your widget to react at pointer interactions. Just make it <code>isinteractive</code>.
<br>
<br>
You can attach a callback for interactions with the widget <code>bounds</code> or with <code>slots</code>.
The available events are <code>down</code>, <code>up</code>, <code>enter</code>, <code>leave</code>, <code>move</code>, and <code>drag</code>.
<br>
<br>
In the following example, if the cursor enters the bounds, the jump animation is set, while the wave animation is set when the cursor leaves.
<br>
If you click on the <code>head-base</code> slot (the face), you can change the normal and dark tint with the colors selected in the two following selectors.

<ul>
<li>Tint normal: <input type="color" id="color-picker" value="#ffffff" /></li>
<li>Tint black: <input type="color" id="dark-picker" value="#000000" /></li>
</ul>

</div>
<div class="split-right">
<spine-widget
identifier="interactive"
atlas="assets/chibi-stickers-pma.atlas",
skeleton="assets/chibi-stickers.json",
skin="mario"
animation="emotes/wave"
pad-top="0.05"
pad-bottom="0.05"
isinteractive
></spine-widget>

<script>
(async () => {
const colorPicker = document.getElementById("color-picker");
const darkPicker = document.getElementById("dark-picker");

const widget = await spine.getSpineWidget("interactive").loadingPromise;

widget.cursorBoundsEventCallback = (event) => {
if (event === "enter") widget.state.setAnimation(0, "emotes/hooray", true).mixDuration = .15;
if (event === "leave") widget.state.setAnimation(0, "emotes/wave", true).mixDuration = .25;
}

const tempColor = new spine.Color();
const slot = widget.skeleton.findSlot("head-base");
slot.darkColor = new spine.Color(0, 0, 0, 1);
widget.addCursorSlotEventCallbacks(slot, (slot, event) => {
if (event === "down") {
slot.darkColor.setFromColor(spine.Color.fromString(darkPicker.value, tempColor));
slot.color.setFromColor(spine.Color.fromString(colorPicker.value, tempColor));
}
});
})();
</script>
</div>
</div>

<div class="split-bottom">
<pre><code id="code-display">
<script>escapeHTMLandInject(`
(async () => {
const colorPicker = document.getElementById("color-picker");
const darkPicker = document.getElementById("dark-picker");
const widget = await spine.getSpineWidget("interactive").loadingPromise;
widget.cursorBoundsEventCallback = (event) => {
if (event === "enter") widget.state.setAnimation(0, "emotes/hooray", true).mixDuration = .15;
if (event === "leave") widget.state.setAnimation(0, "emotes/wave", true).mixDuration = .25;
}
const tempColor = new spine.Color();
const slot = widget.skeleton.findSlot("head-base");
slot.darkColor = new spine.Color(0, 0, 0, 1);
widget.addCursorSlotEventCallbacks(slot, (slot, event) => {
if (event === "down") {
slot.darkColor.setFromColor(spine.Color.fromString(darkPicker.value, tempColor));
slot.color.setFromColor(spine.Color.fromString(colorPicker.value, tempColor));
}
});
})();`
);</script>
</code></pre>
</div>

</div>

<!--
/////////////////////
// end section //
Expand Down
Loading

0 comments on commit 30a2f80

Please sign in to comment.