2017-01-24 27 views
8

My Animated.View posiada następujące style:React Native animacje - translateX i translateY podczas skalowania

{ 
     transform: [ 
      { 
       scale: this.animatedValue.interpolate({ 
        inputRange: [0, 1], 
        outputRange: [initialScale, 1] 
      })}, 
      { 
       translateX: this.animatedValue.interpolate({ 
        inputRange: [0, 1], 
        outputRange: [startX, endX] 
      })}, 
      { 
       translateY: this.animatedValue.interpolate({ 
        inputRange: [0, 1], 
        outputRange: [startY, endY] 
      })}, 
     ] 
    } 

Kiedy initialScale jest 1 i rozpoczyna się animacja, widzę oczekiwane zachowanie: Animated.View rozpoczyna się (startx, startY) i liniowo przesuwa się do (endX, endY).
Jednak, gdy początkowa wartość skali to 0,5, punktem początkowym widoku nie jest (startX, startY), ruch nie jest liniowy (nieco sferyczny), a punkt końcowy jest nadal zgodny z oczekiwaniami - (endX, endY).

Jak skalować widok, zachowując ruch liniowy i oczekiwaną pozycję początkową?

+1

Kiedy skalować go zobaczyć zachowuje oryginalne centrum X (przesuwając się w prawo). Kiedy przetłumaczysz ten sam widok, będzie on tłumaczył z pozornie przesuniętej pozycji. Jeśli użyjesz dwóch zapakowanych widoków, skalując wewnętrzny i tłumacząc ten zewnętrzny, możesz uzyskać oczekiwany wynik. – ArneHugo

+0

Pomaga to w ruchu sferycznym, ale pozycja początkowa jest nadal wyłączona –

+1

Jeśli można ustawić pochodzenie transformacji, prawdopodobnie można przeskalować ją w kierunku prawego górnego rogu. Jednak pochodzenie transformacji nie jest obsługiwane w trybie natywnym. Możesz jednak * możesz * jednak [użyć transformMatrix] (https://github.com/facebook/react-native/issues/1964#issuecomment-222480415), aby zdefiniować transformację zamiast tego, chociaż jest to zupełnie inny sposób robienia tego. – ArneHugo

Odpowiedz

8

Podobnie jak użytkownik @ArneHugo wskazany w komentarzach, ruch nieliniowy można rozwiązać, umieszczając pełnowymiarowy element kontenera i skalując inny element w nim.

Pozycja elementu nie jest zgodna z oczekiwaniami, ponieważ punkt początkowy przekształcenia skali jest punktem środkowym elementu. React Native nie (jeszcze) wsparcie określający pochodzenie przekształcenia, ale jeśli szerokość i wysokość skalowany elementem są znane z góry, to łatwo obliczyć przesunięcie następująco:

const width = 100; 
const height = 20; 
const scale = { 
    transform: [ 
    { 
     scale: this.animatedValue.interpolate({ 
     inputRange: [0, 1], 
     outputRange: [initialScale, 1] 
     }) 
    } 
    ] 
}; 

const position= { 
    transform: [ 
    { 
     translateX: this.animatedValue.interpolate({ 
     inputRange: [0, 1], 
     outputRange: [startX - (width/2) - (width * initialScale/2), endX] 
     }) 
    }, 
    { 
     translateY: this.animatedValue.interpolate({ 
     inputRange: [0, 1], 
     outputRange: [startY - (height/2) - (height * initialScale/2), endY] 
     }) 
    } 
    ] 
}; 

return (
    <Animated.View style={position}> 
    <Animated.View style={[styles.thing, scale]} /> 
    </Animated.View> 
); 
+0

Dzięki! Wprowadził niewielką zmianę do formuły i zrobił magię (edytował również zmianę w twoim poście) –