Я пытаюсь создать эту анимацию с ReactJS и API веб-анимации
Я выбрал WAAPI для изучения механизмов, и мне это нравится.Единственная проблема заключается в том, что при запуске моей веб-страницы Waapi возвращает мне, что
анимация к базовому значению или из него еще не поддерживается.
Я не могу понятьчто не так, может быть, это polyfill, но я импортировал polyfill в мой файл App.js в верхней части моего кода.
Может быть, это другая ошибка?
Вот моя песочница
Здесь моя логика JavaScript, вы можете визуализировать большие шаги логики моего компонента с помощью старой доброй функции конструктора:
constructor( props ){
super( props );
// appreciate arrow or navigate move before trigger animation
// update button view
// stock nextIndex in state
this.animationPrepare = this.animationPrepare.bind(this);
this.buttonBackground = this.buttonBackground.bind(this);
this.updateNextView = this.updateNextView.bind(this);
// set animation
this.routeAnimationPosition = this.routeAnimationPosition.bind(this);
this.setEnterAnimation = this.setEnterAnimation.bind(this);
this.setExitAnimation = this.setExitAnimation.bind(this);
// triger animation
this.firstLineAnimation = this.firstLineAnimation.bind(this);
this.secondLineAnimation = this.secondLineAnimation.bind(this);
this.imageAnimation = this.imageAnimation.bind(this);
// move pageView
this.arrowMove = this.arrowMove.bind(this);
this.circleMove = this.circleMove.bind(this);
// trigger another loop __ update state data
this.updateSlideData = this.updateSlideData.bind(this);
}
componentDidMount(){
this.animationPrepare();
var body= document.body;
body.style.overflow= "hidden";
}
componentWillUnmount(){
var body= document.body;
body.style.overflow= "scroll";
}
// slideState
state={
currentView:0,
nextView:null,
finalLoop:true,
elementType:null,
animation:this.enterDownAnimation,
timing:this.slideAnimationTiming,
imageSource:"/static/assets/illustration/portfolio/chinese_cook.png",
portfolioUrl:"",
firstLineText:"first line",
secondLineText:"secondLine"
}
// animation timing
slideAnimationTiming={
duration: 750,
easing: "ease-in",
delay: this.state.delay,
iterations:1,
direction: "normal",
fill: "forwards"
}
// animations forms
enterDownAnimation=[
{transform:"translate(0, 30vh)", opacity:0},
{transform:"translate(0, 30vh)", opacity:1},
{offset:0.5, transform:"translate(0, 35vh)", opacity:1}
]
enterUpAnimation=[
{transform:"translate(0, 35vh)", opacity:0},
{transform:"translate(0, 35vh)", opacity:1},
{offset:0.5, transform:"translate(0, 30vh)", opacity:1}
]
enterSideAnimation=[
{transform:"translate(10vw)", opacity:0},
{transform:"translate(10vw)", opacity:1},
{offset:0.5, transform:"translate(030vh)", opacity:1}
]
// exit animation
exitDownAnimation=[
{transform:"translate(0, 30vh)", opacity:1},
{transform:"translate(0, 0vh)", opacity:1},
{offset:0.5, transform:"translate(0, 35vh)", opacity:0}
]
exitUpAnimation=[
{transform:"translate(0, 35vh)", opacity:1},
{transform:"translate(0, 35vh)", opacity:1},
{offset:0.5, transform:"translate(0, 30vh)", opacity:0}
]
exitUpAnimation=[
{transform:"translate(10vw)", opacity:1},
{transform:"translate(10vw)", opacity:1},
{offset:0.5, transform:"translate(030vh)", opacity:0}
]
// define animations function
// defineAnimation= () => {
// {here code...}
// }
// trigger logic depending on position's state
animationPrepare=(nextView, isArrow)=>{
console.log("in animation prepare");
isArrow ?
this.setState({arrowMove: true})
:
this.setState({arrowMove: false})
if(this.state.finalLoop === false){
this.buttonBackground(nextView);
this.updateNextView(nextView);
}
this.firstLineAnimation();
}
buttonBackground=(nextView)=>{
var buttonToTransparent=this.refs["button"+this.state.currentView];
buttonToTransparent.style.backgroundColor="transparent";
var buttonCurrentView=this.refs["button"+nextView];
buttonCurrentView.style.backgroundColor="black";
}
updateNextView=(nextView)=>{
this.setState({nextView})
}
routeAnimationPosition=()=>{
if(this.state.finalLoop){
this.setEnterAnimation();
}else{
this.setExitAnimation();
}
}
setEnterAnimation=()=>{
if(this.state.elementType ==="text"){
if(this.state.currentView % 2 === 0){
this.setState({animation:this.enterDownAnimation});
}else{
this.setState({animation:this.enterUpAnimation})
}
}else{
switch(this.state.currentView){
case 0:
this.setState({animation:this.enterSideAnimation});
break;
case 1:
this.setState({animation:this.enterUpAnimation});
break;
case 2:
this.setState({animation:this.enterDownAnimation});
break;
case 3:
this.setState({animation:this.enterSideAnimation});
break;
case 4:
this.setState({animation:this.enterUpAnimation});
break;
default:
console.log("no animation found")
break; // test return
}
}
}
setExitAnimation=()=>{
if(this.state.elementType ==="text"){
if(this.state.currentView % 2 === 0){
this.setState({animation:this.exitDownAnimation});
}else{
this.setState({animation:this.exitUpAnimation})
}
}else{
switch(this.state.currentView){
case 0:
this.setState({animation:this.exitSideAnimation});
break;
case 1:
this.setState({animation:this.exitUpAnimation});
break;
case 2:
this.setState({animation:this.exitDownAnimation});
break;
case 3:
this.setState({animation:this.exitSideAnimation});
break;
case 4:
this.setState({animation:this.exitUpAnimation});
break;
default:
console.log("no animation found")
break; // test return
}
}
}
// animation triggering
// promise to set animation
// with promise resolved to trigger animation
firstLineAnimation=()=>{
// stock next view in componentState
/*****
* SET PROMISE => 2 steps
* set animation position
* set animation form
* *****/
// set animation
this.setState({position:"text"},
() => this.routeAnimationPosition())
/*****
* RESOLVE PROMISE => 3 steps _ inject animation in element
* set element
* define animation
* trigger animation
* *****/
var textFirstLine = this.refs.firstLineTextBox
// promise start here
var textFirstLineAnimation = textFirstLine.animate(
this.state.animation,
this.state.timing
);
// trigger animation
// promise end here
textFirstLineAnimation.play()
// call next animation
var callSecondAnimation= this.secondLineAnimation();
textFirstLineAnimation.onfinish = callSecondAnimation;
}
secondLineAnimation=()=>{
// no delay because component listen
// for first animation finishing
// set animation
var textSecondLine = this.refs.secondLineTextBox
var textSecondLineAnimation = textSecondLine.animate(
this.state.animation,
this.state.timing
)
// trigger animation
textSecondLineAnimation.play();
// call next animation
var callImageAnimation= this.imageAnimation();
textSecondLineAnimation.onfinish = callImageAnimation;
}
imageAnimation=()=>{
// no delay because component listen
// for second animation finishing
// set animation
// promise start here
this.setState({position:"image"},
() => this.routeAnimationPosition())
// inject animation in element
var imageBox = this.refs.imageBox
// promise resolve in imageAnimation
var imageAnimation = imageBox.animate(
this.state.animation,
this.state.timing
)
// trigger animation
imageAnimation.play();
// call updateSlideData function
if(this.state.arrowMove && !(this.state.finalLoop)){
var callArrowMove= () => this.arrowMove();
imageAnimation.onfinish = callArrowMove;
}
else if( !(this.state.arrowMove) && !(this.state.finalLoop)){
var callCircleMove = () => this.circleMove();
imageAnimation.onfinish = callCircleMove;
}
else{
var callUpdateSlideData = this.updateSlideData();
imageAnimation.onfinish = callUpdateSlideData;
}
}
arrowMove=()=>{
// => move background to the relevant sliderView
var imageHolder= this.refs.imageHolder;
var viewTravelValue=-(100*this.state.nextView);
imageHolder.style.setProperty('--viewPosition', viewTravelValue+"vw");
imageHolder.addEventListener("transitionend", function(event) {
console.log("transition achieved")
this.updateSlideData();
}, false);
}
circleMove=()=>{
// => move background to the relevant pageView
var imageHolder= this.refs.imageHolder;
var viewTravelValue=-(100*this.state.nextView);
imageHolder.style.setProperty('--viewPosition', viewTravelValue+"vw");
this.updateSlideData();
imageHolder.addEventListener("transitionend",()=> {
console.log("transition achieved")
this.updateSlideData();
}, false);
}
updateSlideData=()=>{
// console.log("STATE ACTION UPDATE DATA", this.state.action)
// var indexUpdate=this.state.indexUpdate;
if(this.state.finalLoop === false){
var path = "/static/assets/illustration/portfolio/";
var imageSourceTab=[
path + "chinese_cook.png",
path+ "burger_cook.png",
path +"french_cook.png",
path +"chinese_cook.png",
path+"burger_cook.png"
]
var nextViewImage=imageSourceTab[this.state.nextView]
// var firstLineTab=[
/*****
*
* code here
*
*****/
// ]
// var secondLineTab=[
/*****
*
* code here
*
*****/
// ]
// var nextViewFirstLine=firstLineTab[this.state.nextView]
// var nextViewSecondLine=secondLineTab[this.state.nextView]
// var urlTab=[
/*****
*
* code here
*
*****/
// ]
// var nextViewUrl=urlTab[this.state.nextView]
// prepare nextView
// text => todo
this.setState({
currentView:this.state.nextView,
finalLoop:true,
imageSource:nextViewImage,
// portfolioUrl:nextViewUrl,
// firstLineText: nextViewFirstLine,
// secondLineText:nextViewSecondLine
},
// inner_callback to ensure updated state
() => this.animationPrepare()
)
}else{
// prepare the next pageView animation
this.setState({
finalLoop:false,
isArrow:null
})
return
}
}
Моя таблица стилей CSS касается позиционирования сетевого элемента, я думаю, что здесь очень важна логика, особенно с учетом того, что я использую Waapi.
Любая подсказка была бы отличной, спасибо