<! DOCTYPE  html >  
< html  lang = " en" >  
< head> < meta  charset = " UTF-8" > < title>  文本变形动画</ title> < link  rel = " stylesheet"   href = " ./style.css" >  
</ head>  
< body>  
< div  id = " container" > < span  id = " text1" > </ span> < span  id = " text2" > </ span>  
</ div>  
< svg  id = " filter" > < defs> < filter  id = " threshold" > < feColorMatrix  in = " SourceGraphic" type = " matrix" values = " 1 0 0 0 00 1 0 0 00 0 1 0 00 0 0 255 -140"   /> </ filter> </ defs>  
</ svg> < script  src = " ./script.js" > </ script>  
</ body>  
</ html>  
  
@import  url ( 'https://fonts.googleapis.com/css?family=Raleway:900&display=swap' ) ; body  { margin :  0px; 
} #container  { position :  absolute; margin :  auto; width :  100vw; height :  80pt; top :  0; bottom :  0; filter :  url ( #threshold)   blur ( 0.6px) ; 
} #text1, #text2  { position :  absolute; width :  100%; display :  inline-block; font-family :  'Raleway' ,  sans-serif; font-size :  80pt; text-align :  center; user-select :  none; 
} 
  
const  elts =  { text1 :  document. getElementById ( "text1" ) , text2 :  document. getElementById ( "text2" )  } ; 
const  texts =  [ 
"Can" , 
"I" , 
"have" , 
"one" , 
"click" , 
"triple?" 
] ; 
const  morphTime =  1 ; 
const  cooldownTime =  0.25 ; let  textIndex =  texts. length -  1 ; 
let  time =  new  Date ( ) ; 
let  morph =  0 ; 
let  cooldown =  cooldownTime; elts. text1. textContent =  texts[ textIndex %  texts. length] ; 
elts. text2. textContent =  texts[ ( textIndex +  1 )  %  texts. length] ; function  doMorph ( )  { morph -=  cooldown; cooldown =  0 ; let  fraction =  morph /  morphTime; if  ( fraction >  1 )  { cooldown =  cooldownTime; fraction =  1 ; } setMorph ( fraction) ; 
} 
function  setMorph ( fraction )  { elts. text2. style. filter =  ` blur( ${ Math. min ( 8  /  fraction -  8 ,  100 ) } px) ` ; elts. text2. style. opacity =  ` ${ Math. pow ( fraction,  0.4 )  *  100 } % ` ; fraction =  1  -  fraction; elts. text1. style. filter =  ` blur( ${ Math. min ( 8  /  fraction -  8 ,  100 ) } px) ` ; elts. text1. style. opacity =  ` ${ Math. pow ( fraction,  0.4 )  *  100 } % ` ; elts. text1. textContent =  texts[ textIndex %  texts. length] ; elts. text2. textContent =  texts[ ( textIndex +  1 )  %  texts. length] ; 
} function  doCooldown ( )  { morph =  0 ; elts. text2. style. filter =  "" ; elts. text2. style. opacity =  "100%" ; elts. text1. style. filter =  "" ; elts. text1. style. opacity =  "0%" ; 
} 
function  animate ( )  { requestAnimationFrame ( animate) ; let  newTime =  new  Date ( ) ; let  shouldIncrementIndex =  cooldown >  0 ; let  dt =  ( newTime -  time)  /  1000 ; time =  newTime; cooldown -=  dt; if  ( cooldown <=  0 )  { if  ( shouldIncrementIndex)  { textIndex++ ; } doMorph ( ) ; }  else  { doCooldown ( ) ; } 
} 
animate ( ) ;