Merge branch 'anims-change' into develop
This commit is contained in:
commit
4fc5f46311
@ -25,14 +25,18 @@ function createSocket(store) {
|
||||
|
||||
function onDevResolutions(newRes) {
|
||||
const { game: currentGame } = store.getState();
|
||||
let id = 0;
|
||||
return eachSeries(newRes, (r, cb) => {
|
||||
if (['Disable', 'TargetKo'].includes(r.event[0])) return cb();
|
||||
// Create sub events for combat animations
|
||||
const sequence = getCombatSequence(r);
|
||||
id += 1;
|
||||
|
||||
return eachSeries(sequence, (stages, sCb) => {
|
||||
const stagedR = Object.create(r);
|
||||
stagedR.sequence = sequence;
|
||||
stagedR.stages = stages;
|
||||
stagedR.id = id;
|
||||
|
||||
let timeout = 0;
|
||||
if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) {
|
||||
@ -45,11 +49,13 @@ function createSocket(store) {
|
||||
return setTimeout(sCb, timeout);
|
||||
}, err => {
|
||||
if (err) console.error(err);
|
||||
store.dispatch(actions.setAvatarAnimation({ id, source: false, target: false }));
|
||||
// Finished this resolution
|
||||
return cb();
|
||||
});
|
||||
}, err => {
|
||||
if (err) return console.error(err);
|
||||
store.dispatch(actions.setAvatarAnimation({ id: -1, source: false, target: false }));
|
||||
store.dispatch(actions.setResolution(null));
|
||||
// stop skipping resolutions
|
||||
store.dispatch(actions.setSkip(false));
|
||||
|
||||
@ -73,13 +73,20 @@ function animations(props) {
|
||||
const sourceIsPlayer = playerTeamIds.includes(construct.id);
|
||||
const targetIsPlayer = playerTeamIds.includes(resolution.target.id);
|
||||
|
||||
if (resolution.source.id === construct.id && resolution.stages.includes('START_SKILL')) {
|
||||
const skipSource = (resolution.source.id === resolution.target.id
|
||||
&& ['Invert', 'Banish'].includes(removeTier(event.skill)));
|
||||
|
||||
if (!skipSource && resolution.source.id === construct.id && resolution.stages.includes('START_SKILL')) {
|
||||
const sameTeam = (sourceIsPlayer && targetIsPlayer) || (!sourceIsPlayer && !targetIsPlayer);
|
||||
const y = sameTeam
|
||||
? 0
|
||||
: targetIsPlayer
|
||||
? 1
|
||||
: -1;
|
||||
|
||||
let y = 0;
|
||||
if (!sameTeam) y = targetIsPlayer ? 1 : -1;
|
||||
|
||||
// const y = sameTeam
|
||||
// ? 0
|
||||
// : targetIsPlayer
|
||||
// ? 1
|
||||
// : -1;
|
||||
|
||||
const i = sourceIsPlayer
|
||||
? playerTeamIds.findIndex(c => c === construct.id)
|
||||
@ -90,8 +97,14 @@ function animations(props) {
|
||||
: otherTeamIds.findIndex(c => c === resolution.target.id);
|
||||
|
||||
const x = j - i;
|
||||
if (avatarAnimation.id !== resolution.id) {
|
||||
setAvatarAnimation({ id: resolution.id, animTargetId: construct.id, x, y });
|
||||
if (!avatarAnimation.source) {
|
||||
setAvatarAnimation({
|
||||
source: true,
|
||||
target: avatarAnimation.target,
|
||||
animTargetId: construct.id,
|
||||
type: 'sourceCast',
|
||||
params: { x, y },
|
||||
});
|
||||
}
|
||||
}
|
||||
const targetTeam = targetIsPlayer ? playerTeamIds : otherTeamIds;
|
||||
@ -100,7 +113,6 @@ function animations(props) {
|
||||
|
||||
// target animation
|
||||
const anim = text => {
|
||||
console.log(text);
|
||||
if (!text || !resolution.sequence[0].includes('END_SKILL')) return false;
|
||||
const skill = removeTier(text);
|
||||
|
||||
@ -130,14 +142,34 @@ function animations(props) {
|
||||
case 'Curse': return <Curse />;
|
||||
case 'Decay': return <Decay />;
|
||||
case 'DecayTick': return <Decay />;
|
||||
case 'Invert': return <Invert id={construct.id} />;
|
||||
case 'Invert': {
|
||||
if (!avatarAnimation.target) {
|
||||
setAvatarAnimation({
|
||||
source: avatarAnimation.source,
|
||||
target: true,
|
||||
id: resolution.id,
|
||||
animTargetId: construct.id,
|
||||
type: 'invert',
|
||||
});
|
||||
} break;
|
||||
}
|
||||
case 'Purge': return <Purge />;
|
||||
case 'Silence': return <Silence />;
|
||||
case 'Restrict': return <Restrict />;
|
||||
|
||||
// Stun Base
|
||||
case 'Stun': return <Stun />;
|
||||
case 'Banish': return <Banish id={construct.id} />;
|
||||
case 'Banish': {
|
||||
if (!avatarAnimation.target) {
|
||||
setAvatarAnimation({
|
||||
source: avatarAnimation.source,
|
||||
target: true,
|
||||
id: resolution.id,
|
||||
animTargetId: construct.id,
|
||||
type: 'banish',
|
||||
});
|
||||
} break;
|
||||
}
|
||||
case 'Bash': return <Bash />;
|
||||
case 'Absorb': return <Absorb />;
|
||||
case 'Sleep': return <Sleep />;
|
||||
|
||||
@ -1,42 +1,17 @@
|
||||
const preact = require('preact');
|
||||
const { Component } = require('preact');
|
||||
|
||||
const anime = require('animejs').default;
|
||||
|
||||
const { TIMES } = require('../../constants');
|
||||
|
||||
class Banish extends Component {
|
||||
constructor(props) {
|
||||
super();
|
||||
this.id = props.id;
|
||||
this.animations = [];
|
||||
}
|
||||
|
||||
render() {
|
||||
// Need this so unmount triggers
|
||||
return <svg id='invert'></svg>;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.animations.push(anime({
|
||||
targets: [document.getElementById(this.id)],
|
||||
function Banish(id) {
|
||||
return anime({
|
||||
targets: [document.getElementById(id)],
|
||||
scaleY: 0,
|
||||
fill: '#fff',
|
||||
easing: 'easeOutElastic',
|
||||
delay: TIMES.TARGET_DELAY_MS,
|
||||
duration: TIMES.TARGET_DURATION_MS * 0.5,
|
||||
duration: TIMES.TARGET_DURATION_MS * 0.45,
|
||||
direction: 'alternate',
|
||||
}));
|
||||
}
|
||||
|
||||
// this is necessary because
|
||||
// skipping / timing / unmounting race conditions
|
||||
// can cause the animations to cut short, this will ensure the values are reset
|
||||
// because preact will recycle all these components
|
||||
componentWillUnmount() {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = Banish;
|
||||
|
||||
18
client/src/components/anims/idle.jsx
Normal file
18
client/src/components/anims/idle.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
const anime = require('animejs').default;
|
||||
|
||||
function idle(id) {
|
||||
const duration = anime.random(2000, 18000);
|
||||
const target = document.getElementById(id);
|
||||
return anime({
|
||||
targets: target,
|
||||
translateX: () => anime.random(-20, 20),
|
||||
translateY: () => anime.random(0, -40),
|
||||
rotate: () => anime.random(-15, 15),
|
||||
duration,
|
||||
direction: 'alternate',
|
||||
easing: 'linear',
|
||||
loop: true,
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = idle;
|
||||
@ -1,41 +1,16 @@
|
||||
const preact = require('preact');
|
||||
const { Component } = require('preact');
|
||||
|
||||
const anime = require('animejs').default;
|
||||
|
||||
const { TIMES } = require('../../constants');
|
||||
|
||||
class Invert extends Component {
|
||||
constructor(props) {
|
||||
super();
|
||||
this.id = props.id;
|
||||
this.animations = [];
|
||||
}
|
||||
|
||||
render() {
|
||||
// Need this so unmount triggers
|
||||
return <svg id='invert'></svg>;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.animations.push(anime({
|
||||
targets: [document.getElementById(this.id)],
|
||||
function Invert(id) {
|
||||
return anime({
|
||||
targets: [document.getElementById(id)],
|
||||
rotate: 180,
|
||||
delay: TIMES.TARGET_DELAY_MS,
|
||||
duration: TIMES.TARGET_DURATION_MS * 0.45,
|
||||
easing: 'easeInOutElastic',
|
||||
direction: 'alternate',
|
||||
}));
|
||||
}
|
||||
|
||||
// this is necessary because
|
||||
// skipping / timing / unmounting race conditions
|
||||
// can cause the animations to cut short, this will ensure the values are reset
|
||||
// because preact will recycle all these components
|
||||
componentWillUnmount() {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = Invert;
|
||||
|
||||
17
client/src/components/anims/source.cast.jsx
Normal file
17
client/src/components/anims/source.cast.jsx
Normal file
@ -0,0 +1,17 @@
|
||||
const anime = require('animejs').default;
|
||||
|
||||
const { TIMES } = require('../../constants');
|
||||
|
||||
function sourceCast(id, params) {
|
||||
const { x, y } = params;
|
||||
return anime({
|
||||
targets: [document.getElementById(id)],
|
||||
translateX: x * 200,
|
||||
translateY: y * 200,
|
||||
easing: 'easeInOutElastic',
|
||||
direction: 'alternate',
|
||||
duration: TIMES.SOURCE_DURATION_MS,
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = sourceCast;
|
||||
@ -3,7 +3,11 @@ const { Component } = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
const anime = require('animejs').default;
|
||||
|
||||
const { TIMES } = require('../constants');
|
||||
const banish = require('./anims/banish');
|
||||
const idleAnimation = require('./anims/idle');
|
||||
const invert = require('./anims/invert');
|
||||
const sourceCast = require('./anims/source.cast');
|
||||
|
||||
|
||||
const genAvatar = name => {
|
||||
let hash = 0;
|
||||
@ -17,28 +21,6 @@ const genAvatar = name => {
|
||||
return `${hash}`;
|
||||
};
|
||||
|
||||
const animations = {};
|
||||
function animateConstruct(id) {
|
||||
if (animations[id]) return false;
|
||||
animations[id] = true;
|
||||
const duration = anime.random(2000, 18000);
|
||||
const target = document.getElementById(id);
|
||||
return anime({
|
||||
targets: target,
|
||||
translateX: () => anime.random(-20, 20),
|
||||
translateY: () => anime.random(0, -40),
|
||||
rotate: () => anime.random(-15, 15),
|
||||
duration,
|
||||
direction: 'alternate',
|
||||
easing: 'linear',
|
||||
loop: true,
|
||||
complete: () => animations[id] = false,
|
||||
});
|
||||
}
|
||||
|
||||
function clearAnimation(id) {
|
||||
animations[id] = false;
|
||||
}
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
@ -48,10 +30,15 @@ const addState = connect(
|
||||
);
|
||||
|
||||
class ConstructAvatar extends Component {
|
||||
constructor() {
|
||||
constructor(props) {
|
||||
super();
|
||||
// The animation ids are a check to ensure that animations are not repeated
|
||||
// When a new construct animation is communicated with state it will have a corresponding Id
|
||||
// which is a count of how many resoluttions have passed
|
||||
this.animId = 0;
|
||||
this.source = false;
|
||||
this.animations = [];
|
||||
this.avatar = genAvatar(props.name);
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -59,61 +46,45 @@ class ConstructAvatar extends Component {
|
||||
<div
|
||||
class="avatar"
|
||||
id={this.props.id}
|
||||
style={{'background-image': `url(/molecules/${genAvatar(this.props.name)}.svg)`}}
|
||||
style={{ 'background-image': `url(/molecules/${this.avatar}.svg)` }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.idle = animateConstruct(this.props.id);
|
||||
this.idle = idleAnimation(this.props.id);
|
||||
this.animations.push(this.idle);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.avatarAnimation.id !== this.animId && nextProps.avatarAnimation.animTargetId === this.props.id) {
|
||||
const animations = nextProps.avatarAnimation;
|
||||
if (animations.id === -1) this.animId = 0; // The current set of resolutions ended reset to 0
|
||||
if (animations.id !== this.animId && animations.animTargetId === this.props.id) {
|
||||
this.animId = nextProps.avatarAnimation.id;
|
||||
const selectAnim = () => {
|
||||
switch (animations.type) {
|
||||
case 'banish': return banish(this.props.id);
|
||||
case 'invert': return invert(this.props.id);
|
||||
case 'sourceCast': return sourceCast(this.props.id, animations.params);
|
||||
default: return null;
|
||||
}
|
||||
};
|
||||
const anim = selectAnim();
|
||||
if (anim) {
|
||||
this.idle.pause();
|
||||
const anim = anime({
|
||||
targets: [document.getElementById(this.props.id)],
|
||||
translateY: nextProps.avatarAnimation.y * 200,
|
||||
translateX: nextProps.avatarAnimation.x * 200,
|
||||
easing: 'easeInOutElastic',
|
||||
direction: 'alternate',
|
||||
duration: TIMES.SOURCE_DURATION_MS,
|
||||
});
|
||||
this.animations.push(anim);
|
||||
anim.finished.then(this.idle.play);
|
||||
}
|
||||
// console.log(this.props);
|
||||
// console.log(nextProps);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearAnimation(this.props.id);
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
class ConstructImg extends Component {
|
||||
render() {
|
||||
return (
|
||||
<img
|
||||
class="avatar"
|
||||
id={this.props.id}
|
||||
src={`/molecules/${genAvatar(this.props.name)}.svg`}
|
||||
height="500"
|
||||
onError={event => event.target.setAttribute('src', '/molecules/726.svg')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
animateConstruct(this.props.id);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearAnimation(this.props.id);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
ConstructAvatar: addState(ConstructAvatar),
|
||||
ConstructImg,
|
||||
};
|
||||
|
||||
@ -84,12 +84,13 @@ function registerEvents(store) {
|
||||
if (err) console.error(err);
|
||||
// Clear the anim classes
|
||||
store.dispatch(actions.setResolution('clear'));
|
||||
store.dispatch(actions.setAvatarAnimation({ id, source: false, target: false }));
|
||||
// Finished this resolution small delay for reset
|
||||
return setTimeout(cb, 5);
|
||||
});
|
||||
}, err => {
|
||||
if (err) return console.error(err);
|
||||
store.dispatch(actions.setAvatarAnimation({ id: -1 }));
|
||||
store.dispatch(actions.setAvatarAnimation({ id: -1, source: false, target: false }));
|
||||
store.dispatch(actions.setResolution(null));
|
||||
// stop skipping resolutions
|
||||
store.dispatch(actions.setSkip(false));
|
||||
|
||||
@ -15,7 +15,7 @@ module.exports = {
|
||||
activeConstruct: createReducer(null, 'SET_ACTIVE_CONSTRUCT'),
|
||||
activeItem: createReducer(null, 'SET_ACTIVE_VAR'),
|
||||
activeSkill: createReducer(null, 'SET_ACTIVE_SKILL'),
|
||||
avatarAnimation: createReducer({ id: -1 }, 'SET_AVATAR_ANIMATION'),
|
||||
avatarAnimation: createReducer({ id: -1, source: false, target: false }, 'SET_AVATAR_ANIMATION'),
|
||||
combiner: createReducer([null, null, null], 'SET_COMBINER'),
|
||||
constructs: createReducer([], 'SET_CONSTRUCTS'),
|
||||
constructDeleteId: createReducer(null, 'SET_CONSTRUCT_DELETE_ID'),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user