Last active
July 6, 2019 05:22
-
-
Save natew/55d8e1ae1a739c75f0d7ebecc22c8698 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { animation, Button, Card, Geometry, Row, Title, View } from '@o/ui' | |
import React from 'react' | |
export const TestCarousel = () => { | |
const apps = [{ title: 'ok' }, { title: 'ok2' }, { title: 'ok3' }, { title: 'o4' }] | |
const carousel = animation(() => ({ | |
scrollLeft: 0, | |
zoomed: false, | |
})) | |
/** | |
* animation() is a helper, but desugars into props somewhat like: | |
* scrollLeft={spring(...)} | |
* animated | |
* lets us control it using .set without being fully controlled | |
*/ | |
return ( | |
<View width="100%" height="100%"> | |
<Button onClick={() => carousel.set(cur => ({ zoomed: !cur.zoomed }))}>zoom</Button> | |
<Button onClick={() => carousel.set(cur => ({ scrollLeft: 100 + cur.scrollLeft }))}> | |
scroll 100px right | |
</Button> | |
<Row flex={1} scrollable="x" space={100} {...carousel}> | |
{apps.map((app, index) => ( | |
<Geometry key={index}> | |
{geometry => ( | |
<Card | |
onClick={() => { | |
carousel.set({ | |
scrollLeft: geometry.offset(index), | |
}) | |
}} | |
onDoubleClick={() => { | |
carousel.set(current => ({ | |
scrollLeft: geometry.offset(index), | |
zoomed: !current.zoomed, | |
})) | |
}} | |
transform={{ | |
rotateY: () => (index - geometry.frame(index)) * 10, | |
scale: () => (carousel.zoomed ? 1 : Math.abs(geometry.frame(index))), | |
}} | |
> | |
<Title>{app.title}</Title> | |
</Card> | |
)} | |
</Geometry> | |
))} | |
</Row> | |
</View> | |
) | |
} |
This one is simpler and a bit clearer:
export const TestCarousel = () => {
const apps = ['ok', 'ok2', 'ok3', 'ok4']
const [zoom, setZoom] = useState(false)
const carousel = useRef<HTMLElement>(null)
return (
<View width="100%" height="100%">
<Button onClick={() => setZoom(!zoom)}>zoom</Button>
<Button onClick={() => (carousel.current.scrollLeft += 100)}>scroll 100px right</Button>
<Row ref={carousel} flex={1} scrollable="x" space={100}>
{apps.map((app, index) => (
<Geometry key={index} frame={carousel}>
{geometry => (
<Card
onClick={() => {
carousel.current.scrollLeft = geometry.offset(index)
}}
onDoubleClick={() => {
carousel.current.scrollLeft = geometry.offset(index)
setZoom(false)
}}
animation={{
mass: 10,
friction: 20,
velocity: 100,
}}
transform={{
rotateY: () => (index - geometry.frame(index)) * 10,
scale: () => (zoom ? 1 : Math.abs(geometry.frame(index))),
}}
>
<Title>{app}</Title>
</Card>
)}
</Geometry>
))}
</Row>
</View>
)
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The alternative I see is basically having everything work through the ref of the Row, but that opens up a few problems.
In this example we have this custom
zoomed
property, which I extracted based on an example. I should really post the example to make this clear, which will be my next step. But basically, you can focus out of the cards / focus into any single card using zoom. I'll need to upgrade this demo quite a bit before that's clear.But the custom property feels weird in this alternate attempt:
Since Row/Col and other views all extend the base
View
, which handles the animation stuff, this would work. The changes from current would be:ref.node
default[Property]
as well.Keep in mind this is all pretty sketchy code golfing, likely a number of typos and poorly thought through peices.