├── .watchmanconfig ├── .gitignore ├── qr.png ├── demo.gif ├── shoe1@3x.png ├── shoe2@3x.png ├── shoe3@3x.png ├── nike-logo@3x.png ├── assets └── icons │ ├── app-icon.png │ └── loading-icon.png ├── .babelrc ├── package.json ├── app.json ├── README.md └── App.js /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | npm-debug.* 4 | -------------------------------------------------------------------------------- /qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachgibson/nike-parallax-cards/HEAD/qr.png -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachgibson/nike-parallax-cards/HEAD/demo.gif -------------------------------------------------------------------------------- /shoe1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachgibson/nike-parallax-cards/HEAD/shoe1@3x.png -------------------------------------------------------------------------------- /shoe2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachgibson/nike-parallax-cards/HEAD/shoe2@3x.png -------------------------------------------------------------------------------- /shoe3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachgibson/nike-parallax-cards/HEAD/shoe3@3x.png -------------------------------------------------------------------------------- /nike-logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachgibson/nike-parallax-cards/HEAD/nike-logo@3x.png -------------------------------------------------------------------------------- /assets/icons/app-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachgibson/nike-parallax-cards/HEAD/assets/icons/app-icon.png -------------------------------------------------------------------------------- /assets/icons/loading-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachgibson/nike-parallax-cards/HEAD/assets/icons/loading-icon.png -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["babel-preset-expo"], 3 | "env": { 4 | "development": { 5 | "plugins": ["transform-react-jsx-source"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ParallaxCards", 3 | "version": "0.0.0", 4 | "description": "Hello Expo!", 5 | "author": null, 6 | "private": true, 7 | "main": "node_modules/expo/AppEntry.js", 8 | "dependencies": { 9 | "expo": "^20.0.0", 10 | "react": "16.0.0-alpha.12", 11 | "react-native": "https://github.com/expo/react-native/archive/sdk-20.0.0.tar.gz" 12 | } 13 | } -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "ParallaxCards", 4 | "description": "Recreation of a Dribbble post meant to showcase interpolating Animated.event and useNativeDriver.", 5 | "slug": "ParallaxCards", 6 | "privacy": "public", 7 | "sdkVersion": "20.0.0", 8 | "version": "1.0.1", 9 | "orientation": "portrait", 10 | "primaryColor": "#8850FF", 11 | "icon": "./assets/icons/app-icon.png", 12 | "loading": { 13 | "icon": "./assets/icons/loading-icon.png", 14 | "hideExponentText": false 15 | }, 16 | "packagerOpts": { 17 | "assetExts": ["ttf", "mp4", "png"] 18 | }, 19 | "ios": { 20 | "supportsTablet": true 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ParallaxCardsDemo 2 | ![Preview](https://raw.githubusercontent.com/zachgibson/ParallaxCardsDemo/master/demo.gif) 3 | 4 | Recreation of [this Dribbble post](https://dribbble.com/shots/2518516-Nike-Promotion-Ads-Parallax-Effect) meant to highlight [Animated.event](http://facebook.github.io/react-native/releases/0.47/docs/animated.html#event) and [useNativeDriver](http://facebook.github.io/react-native/releases/0.47/docs/animated.html#using-the-native-driver). 5 | 6 | **Expo link**: https://expo.io/@zachgibson/ParallaxCards 7 | 8 | **Expo QR Code**: 9 | 10 | 11 | 12 | ## Running locally with exp CLI 13 | ### Grab the repo 14 | ```shell 15 | $ git clone https://github.com/zachgibson/ParallaxCardsDemo.git && cd ParallaxCardsDemo 16 | ``` 17 | 18 | ### Install packages 19 | ```shell 20 | $ yarn install 21 | ``` 22 | or 23 | ```shell 24 | $ npm install 25 | ``` 26 | 27 | ### Start your packager 28 | ```shell 29 | $ exp start 30 | ``` 31 | 32 | ### Install the app 33 | ```shell 34 | $ exp ios 35 | ``` 36 | Or scan the QR code generated by the CLI to run on device 37 | -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { 3 | AppRegistry, 4 | StyleSheet, 5 | Text, 6 | View, 7 | Animated, 8 | ScrollView, 9 | Dimensions, 10 | Image, 11 | TouchableHighlight, 12 | Alert 13 | } from "react-native"; 14 | import { LinearGradient } from "expo"; 15 | 16 | const { width: deviceWidth, height: deviceHeight } = Dimensions.get("window"); 17 | 18 | const SLIDES = [ 19 | { 20 | shoeImage: require("./shoe1.png"), 21 | shoePrice: 120, 22 | shoeName: "Air Structure 19", 23 | shoeDescription: 24 | "From the Flymesh upper to the triple-density foam midsole, the Nike Air Zoom Structure 19 Men’s Running Shoe offers plenty of support and the response you need for a smooth, stable ride that feels ultra fast.", 25 | shoeCategory: "Men’s Running Shoe", 26 | shoePhrase: "Air", 27 | backgroundColor: "#8850FF", 28 | touchableBackgroundColor: "#CAB1FF", 29 | gradients: { 30 | gradient1: "#F72648", 31 | gradient2: "#FCCC3C" 32 | } 33 | }, 34 | { 35 | shoeImage: require("./shoe2.png"), 36 | shoePrice: 129, 37 | shoeName: "Air Solstice QS", 38 | shoeDescription: 39 | "The Nike Air Solstice draws inspiration from the swoosh's classic running shoes of the 1980's updating the style with premium materials and impressive production quality.", 40 | shoeCategory: "Men’s Shoe", 41 | shoePhrase: "Class", 42 | backgroundColor: "#FFBA00", 43 | touchableBackgroundColor: "#FFDB79", 44 | gradients: { 45 | gradient1: "#3CA3FC", 46 | gradient2: "#FFD300" 47 | } 48 | }, 49 | { 50 | shoeImage: require("./shoe3.png"), 51 | shoePrice: 140, 52 | shoeName: "Air Huarache Utility", 53 | shoeDescription: 54 | "The Nike Air Huarache Utility Men's Shoe toughens up a famous running shoe with a nylon upper, fused mudguard and vibrant detail.", 55 | shoeCategory: "Men’s Shoe", 56 | shoePhrase: "Safar", 57 | backgroundColor: "#4054FF", 58 | touchableBackgroundColor: "#9EA8FF", 59 | gradients: { 60 | gradient1: "#26C9F7", 61 | gradient2: "#DFFC3C" 62 | } 63 | } 64 | ]; 65 | 66 | export default class App extends Component { 67 | scrollX = new Animated.Value(0); 68 | 69 | expandCard() { 70 | Alert.alert("🔥 added to ya wishlist 🔥", "", [{ text: "whatever" }]); 71 | } 72 | 73 | render() { 74 | return ( 75 | 76 | {SLIDES.map((slide, index) => { 77 | return ( 78 | 98 | ); 99 | })} 100 | 110 | {SLIDES.map((slide, index) => { 111 | return ( 112 | 113 | 114 | 115 | 124 | 150 | 154 | 155 | ${slide.shoePrice} 156 | 157 | 158 | 182 | 183 | {slide.shoeName.toUpperCase()} 184 | 185 | 186 | 209 | 210 | {slide.shoeDescription} 211 | 212 | 213 | 214 | {slide.shoePhrase.toUpperCase()} 215 | 216 | 217 | 218 | 219 | 245 | this.expandCard()} 248 | style={[ 249 | styles.button, 250 | { borderColor: slide.backgroundColor } 251 | ]} 252 | > 253 | 259 | WISH LIST 260 | 261 | 262 | 263 | {slide.shoeCategory.toUpperCase()} 264 | 265 | 266 | 267 | 290 | 291 | 292 | 293 | ); 294 | })} 295 | 296 | 297 | 298 | 299 | 300 | 331 | 332 | 333 | ); 334 | } 335 | } 336 | 337 | const styles = StyleSheet.create({ 338 | container: { 339 | flex: 1 340 | }, 341 | cardContainer: { 342 | width: deviceWidth, 343 | height: deviceHeight, 344 | alignItems: "center", 345 | justifyContent: "center" 346 | }, 347 | card: { 348 | width: deviceWidth - 64, 349 | height: deviceHeight * 0.8, 350 | backgroundColor: "white", 351 | borderRadius: 15, 352 | shadowColor: "black", 353 | shadowOpacity: 0.3, 354 | shadowOffset: { 355 | width: 0, 356 | height: 15 357 | }, 358 | shadowRadius: 25 359 | }, 360 | cardTopContainer: { 361 | flex: 3, 362 | overflow: "hidden", 363 | padding: 28, 364 | borderTopLeftRadius: 15, 365 | borderTopRightRadius: 15, 366 | backgroundColor: "transparent" 367 | }, 368 | gradient: { 369 | ...StyleSheet.absoluteFillObject, 370 | padding: 28, 371 | backgroundColor: "transparent", 372 | borderTopLeftRadius: 15, 373 | borderTopRightRadius: 15 374 | }, 375 | nikeImageContainer: { 376 | flexDirection: "row", 377 | alignItems: "center", 378 | justifyContent: "space-between", 379 | marginBottom: 40 380 | }, 381 | nikeImage: { 382 | width: 40, 383 | resizeMode: "contain" 384 | }, 385 | shoePriceText: { 386 | fontSize: 20, 387 | fontWeight: "600", 388 | letterSpacing: 0.38, 389 | color: "white" 390 | }, 391 | shoeNameText: { 392 | fontSize: 15, 393 | fontWeight: "800", 394 | letterSpacing: 1.5, 395 | color: "white" 396 | }, 397 | shoeDescriptionText: { 398 | fontSize: 11, 399 | letterSpacing: 0.07, 400 | lineHeight: 13, 401 | color: "white" 402 | }, 403 | shoePhraseText: { 404 | position: "absolute", 405 | bottom: 0, 406 | left: -32, 407 | width: deviceWidth * 2, 408 | fontSize: deviceWidth / 2, 409 | fontWeight: "900", 410 | letterSpacing: 20, 411 | color: "rgba(0,0,0,0.3)" 412 | }, 413 | buttonContainer: { 414 | flex: 1, 415 | alignItems: "center", 416 | justifyContent: "center" 417 | }, 418 | button: { 419 | marginBottom: 12, 420 | paddingVertical: 15, 421 | paddingHorizontal: 64, 422 | borderWidth: 1.5, 423 | borderRadius: 40 424 | }, 425 | buttonText: { 426 | fontSize: 15, 427 | fontWeight: "700", 428 | letterSpacing: 1.5 429 | }, 430 | shoeCategoryText: { 431 | fontSize: 12, 432 | color: "#AEAEAE" 433 | }, 434 | shoeImageContainer: { 435 | ...StyleSheet.absoluteFillObject, 436 | alignItems: "center", 437 | justifyContent: "center" 438 | }, 439 | shoeImage: { 440 | top: 64, 441 | width: deviceWidth, 442 | resizeMode: "contain" 443 | }, 444 | pageIndicatorContainer: { 445 | position: "absolute", 446 | bottom: 24, 447 | width: 64, 448 | height: 3, 449 | flexDirection: "row", 450 | alignSelf: "center", 451 | alignItems: "center", 452 | justifyContent: "space-between", 453 | overflow: "hidden", 454 | borderRadius: 1.5 455 | }, 456 | inActivePageIndicator: { 457 | width: 16, 458 | height: 3, 459 | backgroundColor: "rgba(255, 255, 255, 0.3)", 460 | borderRadius: 1.5 461 | }, 462 | activePageIndicator: { 463 | position: "absolute", 464 | top: 0, 465 | left: 0, 466 | width: 16, 467 | height: 3, 468 | backgroundColor: "white", 469 | borderRadius: 1.5 470 | } 471 | }); 472 | --------------------------------------------------------------------------------