Merge branch 'anims-change' into develop
This commit is contained in:
commit
4fc5f46311
@ -25,14 +25,18 @@ function createSocket(store) {
|
|||||||
|
|
||||||
function onDevResolutions(newRes) {
|
function onDevResolutions(newRes) {
|
||||||
const { game: currentGame } = store.getState();
|
const { game: currentGame } = store.getState();
|
||||||
|
let id = 0;
|
||||||
return eachSeries(newRes, (r, cb) => {
|
return eachSeries(newRes, (r, cb) => {
|
||||||
if (['Disable', 'TargetKo'].includes(r.event[0])) return cb();
|
if (['Disable', 'TargetKo'].includes(r.event[0])) return cb();
|
||||||
// Create sub events for combat animations
|
// Create sub events for combat animations
|
||||||
const sequence = getCombatSequence(r);
|
const sequence = getCombatSequence(r);
|
||||||
|
id += 1;
|
||||||
|
|
||||||
return eachSeries(sequence, (stages, sCb) => {
|
return eachSeries(sequence, (stages, sCb) => {
|
||||||
const stagedR = Object.create(r);
|
const stagedR = Object.create(r);
|
||||||
stagedR.sequence = sequence;
|
stagedR.sequence = sequence;
|
||||||
stagedR.stages = stages;
|
stagedR.stages = stages;
|
||||||
|
stagedR.id = id;
|
||||||
|
|
||||||
let timeout = 0;
|
let timeout = 0;
|
||||||
if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) {
|
if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) {
|
||||||
@ -45,11 +49,13 @@ function createSocket(store) {
|
|||||||
return setTimeout(sCb, timeout);
|
return setTimeout(sCb, timeout);
|
||||||
}, err => {
|
}, err => {
|
||||||
if (err) console.error(err);
|
if (err) console.error(err);
|
||||||
|
store.dispatch(actions.setAvatarAnimation({ id, source: false, target: false }));
|
||||||
// Finished this resolution
|
// Finished this resolution
|
||||||
return cb();
|
return cb();
|
||||||
});
|
});
|
||||||
}, err => {
|
}, err => {
|
||||||
if (err) return console.error(err);
|
if (err) return console.error(err);
|
||||||
|
store.dispatch(actions.setAvatarAnimation({ id: -1, source: false, target: false }));
|
||||||
store.dispatch(actions.setResolution(null));
|
store.dispatch(actions.setResolution(null));
|
||||||
// stop skipping resolutions
|
// stop skipping resolutions
|
||||||
store.dispatch(actions.setSkip(false));
|
store.dispatch(actions.setSkip(false));
|
||||||
|
|||||||
@ -73,13 +73,20 @@ function animations(props) {
|
|||||||
const sourceIsPlayer = playerTeamIds.includes(construct.id);
|
const sourceIsPlayer = playerTeamIds.includes(construct.id);
|
||||||
const targetIsPlayer = playerTeamIds.includes(resolution.target.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 sameTeam = (sourceIsPlayer && targetIsPlayer) || (!sourceIsPlayer && !targetIsPlayer);
|
||||||
const y = sameTeam
|
|
||||||
? 0
|
let y = 0;
|
||||||
: targetIsPlayer
|
if (!sameTeam) y = targetIsPlayer ? 1 : -1;
|
||||||
? 1
|
|
||||||
: -1;
|
// const y = sameTeam
|
||||||
|
// ? 0
|
||||||
|
// : targetIsPlayer
|
||||||
|
// ? 1
|
||||||
|
// : -1;
|
||||||
|
|
||||||
const i = sourceIsPlayer
|
const i = sourceIsPlayer
|
||||||
? playerTeamIds.findIndex(c => c === construct.id)
|
? playerTeamIds.findIndex(c => c === construct.id)
|
||||||
@ -90,8 +97,14 @@ function animations(props) {
|
|||||||
: otherTeamIds.findIndex(c => c === resolution.target.id);
|
: otherTeamIds.findIndex(c => c === resolution.target.id);
|
||||||
|
|
||||||
const x = j - i;
|
const x = j - i;
|
||||||
if (avatarAnimation.id !== resolution.id) {
|
if (!avatarAnimation.source) {
|
||||||
setAvatarAnimation({ id: resolution.id, animTargetId: construct.id, x, y });
|
setAvatarAnimation({
|
||||||
|
source: true,
|
||||||
|
target: avatarAnimation.target,
|
||||||
|
animTargetId: construct.id,
|
||||||
|
type: 'sourceCast',
|
||||||
|
params: { x, y },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const targetTeam = targetIsPlayer ? playerTeamIds : otherTeamIds;
|
const targetTeam = targetIsPlayer ? playerTeamIds : otherTeamIds;
|
||||||
@ -100,7 +113,6 @@ function animations(props) {
|
|||||||
|
|
||||||
// target animation
|
// target animation
|
||||||
const anim = text => {
|
const anim = text => {
|
||||||
console.log(text);
|
|
||||||
if (!text || !resolution.sequence[0].includes('END_SKILL')) return false;
|
if (!text || !resolution.sequence[0].includes('END_SKILL')) return false;
|
||||||
const skill = removeTier(text);
|
const skill = removeTier(text);
|
||||||
|
|
||||||
@ -130,14 +142,34 @@ function animations(props) {
|
|||||||
case 'Curse': return <Curse />;
|
case 'Curse': return <Curse />;
|
||||||
case 'Decay': return <Decay />;
|
case 'Decay': return <Decay />;
|
||||||
case 'DecayTick': 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 'Purge': return <Purge />;
|
||||||
case 'Silence': return <Silence />;
|
case 'Silence': return <Silence />;
|
||||||
case 'Restrict': return <Restrict />;
|
case 'Restrict': return <Restrict />;
|
||||||
|
|
||||||
// Stun Base
|
// Stun Base
|
||||||
case 'Stun': return <Stun />;
|
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 'Bash': return <Bash />;
|
||||||
case 'Absorb': return <Absorb />;
|
case 'Absorb': return <Absorb />;
|
||||||
case 'Sleep': return <Sleep />;
|
case 'Sleep': return <Sleep />;
|
||||||
|
|||||||
@ -1,42 +1,17 @@
|
|||||||
const preact = require('preact');
|
|
||||||
const { Component } = require('preact');
|
|
||||||
|
|
||||||
const anime = require('animejs').default;
|
const anime = require('animejs').default;
|
||||||
|
|
||||||
const { TIMES } = require('../../constants');
|
const { TIMES } = require('../../constants');
|
||||||
|
|
||||||
class Banish extends Component {
|
function Banish(id) {
|
||||||
constructor(props) {
|
return anime({
|
||||||
super();
|
targets: [document.getElementById(id)],
|
||||||
this.id = props.id;
|
scaleY: 0,
|
||||||
this.animations = [];
|
fill: '#fff',
|
||||||
}
|
easing: 'easeOutElastic',
|
||||||
|
delay: TIMES.TARGET_DELAY_MS,
|
||||||
render() {
|
duration: TIMES.TARGET_DURATION_MS * 0.45,
|
||||||
// Need this so unmount triggers
|
direction: 'alternate',
|
||||||
return <svg id='invert'></svg>;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.animations.push(anime({
|
|
||||||
targets: [document.getElementById(this.id)],
|
|
||||||
scaleY: 0,
|
|
||||||
fill: '#fff',
|
|
||||||
easing: 'easeOutElastic',
|
|
||||||
delay: TIMES.TARGET_DELAY_MS,
|
|
||||||
duration: TIMES.TARGET_DURATION_MS * 0.5,
|
|
||||||
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;
|
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 anime = require('animejs').default;
|
||||||
|
|
||||||
const { TIMES } = require('../../constants');
|
const { TIMES } = require('../../constants');
|
||||||
|
|
||||||
class Invert extends Component {
|
function Invert(id) {
|
||||||
constructor(props) {
|
return anime({
|
||||||
super();
|
targets: [document.getElementById(id)],
|
||||||
this.id = props.id;
|
rotate: 180,
|
||||||
this.animations = [];
|
delay: TIMES.TARGET_DELAY_MS,
|
||||||
}
|
duration: TIMES.TARGET_DURATION_MS * 0.45,
|
||||||
|
easing: 'easeInOutElastic',
|
||||||
render() {
|
direction: 'alternate',
|
||||||
// Need this so unmount triggers
|
});
|
||||||
return <svg id='invert'></svg>;
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.animations.push(anime({
|
|
||||||
targets: [document.getElementById(this.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;
|
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 { connect } = require('preact-redux');
|
||||||
const anime = require('animejs').default;
|
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 => {
|
const genAvatar = name => {
|
||||||
let hash = 0;
|
let hash = 0;
|
||||||
@ -17,28 +21,6 @@ const genAvatar = name => {
|
|||||||
return `${hash}`;
|
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(
|
const addState = connect(
|
||||||
function receiveState(state) {
|
function receiveState(state) {
|
||||||
@ -48,10 +30,15 @@ const addState = connect(
|
|||||||
);
|
);
|
||||||
|
|
||||||
class ConstructAvatar extends Component {
|
class ConstructAvatar extends Component {
|
||||||
constructor() {
|
constructor(props) {
|
||||||
super();
|
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.animId = 0;
|
||||||
|
this.source = false;
|
||||||
this.animations = [];
|
this.animations = [];
|
||||||
|
this.avatar = genAvatar(props.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -59,61 +46,45 @@ class ConstructAvatar extends Component {
|
|||||||
<div
|
<div
|
||||||
class="avatar"
|
class="avatar"
|
||||||
id={this.props.id}
|
id={this.props.id}
|
||||||
style={{'background-image': `url(/molecules/${genAvatar(this.props.name)}.svg)`}}
|
style={{ 'background-image': `url(/molecules/${this.avatar}.svg)` }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.idle = animateConstruct(this.props.id);
|
this.idle = idleAnimation(this.props.id);
|
||||||
|
this.animations.push(this.idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
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;
|
this.animId = nextProps.avatarAnimation.id;
|
||||||
this.idle.pause();
|
const selectAnim = () => {
|
||||||
const anim = anime({
|
switch (animations.type) {
|
||||||
targets: [document.getElementById(this.props.id)],
|
case 'banish': return banish(this.props.id);
|
||||||
translateY: nextProps.avatarAnimation.y * 200,
|
case 'invert': return invert(this.props.id);
|
||||||
translateX: nextProps.avatarAnimation.x * 200,
|
case 'sourceCast': return sourceCast(this.props.id, animations.params);
|
||||||
easing: 'easeInOutElastic',
|
default: return null;
|
||||||
direction: 'alternate',
|
}
|
||||||
duration: TIMES.SOURCE_DURATION_MS,
|
};
|
||||||
});
|
const anim = selectAnim();
|
||||||
anim.finished.then(this.idle.play);
|
if (anim) {
|
||||||
|
this.idle.pause();
|
||||||
|
this.animations.push(anim);
|
||||||
|
anim.finished.then(this.idle.play);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// console.log(this.props);
|
|
||||||
// console.log(nextProps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
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 = {
|
module.exports = {
|
||||||
ConstructAvatar: addState(ConstructAvatar),
|
ConstructAvatar: addState(ConstructAvatar),
|
||||||
ConstructImg,
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -84,12 +84,13 @@ function registerEvents(store) {
|
|||||||
if (err) console.error(err);
|
if (err) console.error(err);
|
||||||
// Clear the anim classes
|
// Clear the anim classes
|
||||||
store.dispatch(actions.setResolution('clear'));
|
store.dispatch(actions.setResolution('clear'));
|
||||||
|
store.dispatch(actions.setAvatarAnimation({ id, source: false, target: false }));
|
||||||
// Finished this resolution small delay for reset
|
// Finished this resolution small delay for reset
|
||||||
return setTimeout(cb, 5);
|
return setTimeout(cb, 5);
|
||||||
});
|
});
|
||||||
}, err => {
|
}, err => {
|
||||||
if (err) return console.error(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));
|
store.dispatch(actions.setResolution(null));
|
||||||
// stop skipping resolutions
|
// stop skipping resolutions
|
||||||
store.dispatch(actions.setSkip(false));
|
store.dispatch(actions.setSkip(false));
|
||||||
|
|||||||
@ -15,7 +15,7 @@ module.exports = {
|
|||||||
activeConstruct: createReducer(null, 'SET_ACTIVE_CONSTRUCT'),
|
activeConstruct: createReducer(null, 'SET_ACTIVE_CONSTRUCT'),
|
||||||
activeItem: createReducer(null, 'SET_ACTIVE_VAR'),
|
activeItem: createReducer(null, 'SET_ACTIVE_VAR'),
|
||||||
activeSkill: createReducer(null, 'SET_ACTIVE_SKILL'),
|
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'),
|
combiner: createReducer([null, null, null], 'SET_COMBINER'),
|
||||||
constructs: createReducer([], 'SET_CONSTRUCTS'),
|
constructs: createReducer([], 'SET_CONSTRUCTS'),
|
||||||
constructDeleteId: createReducer(null, 'SET_CONSTRUCT_DELETE_ID'),
|
constructDeleteId: createReducer(null, 'SET_CONSTRUCT_DELETE_ID'),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user