…I’ve modified the version made by @Dwins to easily display images.
Now you can just feed it a table of image names (or asset descriptors) and it will make a nice swipe-able carousel out of them!
With page-indicator dots and everything!
In theory it can accommodate any number of images, though after fifteen ten or so the page-indicator dots might get messed up.
There’s one thing I can’t iron out: when you swipe right on the very first screen, the new image that should be sliding in from the left doesn’t display until the whole page-switching animation is complete.
If any of you fine folks can give me pointers on how to fix that I’d be much obliged.
That’s pretty cool! Just a note that the print(self.images[i]) statement inside the draw() function can make the carousel feel slow as the images array becomes more populated, because it’s printing out every image path multiple times per second
i tried looking through this but there’s too many things going on that i can’t follow, some math in places and i’m left wondering what does this do etc
but my initial thoughts are that when you loop through the images and draw them, you’re not including any “fake” images before the first image, so when you swipe right from the first position there’s no image to the left that is drawn, only once the touch ends does the logic seem to fit the ending image into the draw, so you need a way to move the end image all the way to the left of the first image when you detect a right swipe from the first position and vice vera for the last image when going around to the first image
@skar tbh I don’t know what a lot of the code does either! I just took Dwins’s code and fiddled with it until it did what I want. That’s kind of why I was hoping someone could help me figure this out.
@UberGoober here is an updated one - I bookended the image table with copies of the first and last then modified the code limits to wrap around later/earlier to fake it. There probably is a more elegant solution, but this should give you some pointers
All I had an idea for a scrolling carousel when I started with Codea, together with a series of effects in transposing one image over another. Got the interest back from seeing this and will dig out the old code once I’ve finished my latest project. Thanks for the idea again.
@West I think you helped me understand the code enough to implement the more elegant fix you speculated about.
The code draws all the existing images in one long strip, and then translates the drawing area to match the current page number, so I just drew a copy of the first image at the end of that strip and a copy of the last image before the start of that strip, and since the code already swaps the page count once you wrap around the start or end of the image table, when a transition of that kind is finished animating the page-count-based-translation becomes correct again.
Now, ideally, the code shouldn’t draw all of the images every single time, but instead just draw the current, previous, and next image, but I haven’t figured that out yet.
@UberGoober changing line 186 to the following will literally only draw the image of interest plus its two neighbours
if self.images[i] ~= nil and math.abs(i-self.page)<2 then
You could also put in if statement checks on self.page to control whether the first/last image is also drawn (currently they always are). Not sure if this makes much of a performance impact though
You could also swap the circles for image previews for a different preview. You could also look at a tap to focus on that particular image function too
if i == self.page then
tint(255,200)
sprite(self.images[i],WIDTH/2-s+i*spacingConstant,75,radius*1.5,radius*1.5)
else
tint(255,50)
sprite(self.images[i],WIDTH/2-s+i*spacingConstant,75,radius*0.9,radius*0.9)
end
At any rate I think this does it, with no extraneous drawing:
--image drawing sequence (only draws the current, previous, and next image)
for i,v in ipairs(self.images) do
if self.images[i] ~= nil and math.abs(i-self.page)<2 then
sprite(self.images[i],i*WIDTH-WIDTH/2,HEIGHT/2, WIDTH, HEIGHT)
end
--special cases for beginning and end of image table
if i == 1 then
sprite(self.images[#self.images], -WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)
elseif i == #self.images then
sprite(self.images[1], ((#self.images + 1) * WIDTH)-WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)
end
end
@UberGoober yes, that’s what I meant (though I poorly explained it). You’re right about the tapping to select a picture - here is the fixed code - previous iteration had the sizes hard coded to a set number of dots I think
if touch.state == ENDED and touch.tapCount > 0 then
for i = 1,#self.images do
local radius = WIDTH / #self.images / 1.5
local spacingConstant = radius * 1.25
local s = #self.images*spacingConstant/2
local x,y = WIDTH/2-s+i*50,75
local v = vec2(touch.x,touch.y)-vec2(x,y)
if v:len() < radius then self.page = i end
end
end
this line is strange local radius = WIDTH / #self.images / 1.5
it’s based on the screen width and number of images, which i guess makes sense for larger numbers of images, but try it with only 2, and the dots are huge