Tailwind Infinite Horizontal Scroll Through Items - scroll

I am new to tailwind, so I apologize for this question ahead of time. I am trying to convert existing CSS animations into tailwind. Specifically, how can I create an infinite scroll through a list of items using tailwind? I found this youtube video which accomplishes the exact behavior I would like. If possible how can this be implemented using Tailwind. I tried to search for something along the lines of "infinite scroll" or "carousel" but I couldn't find any other examples except for this video.

I initially struggled with the video instructions. The video instructs to provide a flex box with a width of 200%. Tailwind's config allows me to extend the width in specific pixels; however, I was unable to get it working with percentages.
After some time I found this website which shows a method that only requires extending configure the keyframes and animation like so.
/** #type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {
keyframes: {
marquee: {
'0%': { transform: 'translateX(0%)' },
'100%': { transform: 'translateX(-100%)' },
},
marquee2: {
'0%': { transform: 'translateX(100%)' },
'100%': { transform: 'translateX(0%)' },
},
},
animation : {
'spin-slow-30': 'spin 30s linear infinite',
'spin-slow-25': 'spin 25s linear infinite',
'spin-slow-10': 'spin 10s linear infinite',
'marquee-infinite' : 'marquee 25s linear infinite',
},
},
},
plugins: [],
}
Once set I am then able to define a new component in react. Given the layout of the items, two rows are needed to expand across the width of the screen. I've repeated these items several items per row to achieve 2x the width of the screen otherwise the marquee illusion will break as there isnt enough items to traverse the entire screen.
import React from 'react'
import item1 from '../assets/carousel/1.png'
import item2 from '../assets/carousel/2.png'
import item3 from '../assets/carousel/3.png'
import item4 from '../assets/carousel/4.png'
import item5 from '../assets/carousel/5.png'
const ScrollCarousel = () => {
return (
<>
<div className='mb-96'>
<div className="relative w-full p-16 overflowx-hidden">
<div className="flex absolute left-0 animate-marquee-infinite">
<div className='flex w-96 justify-around'>
<img src={item1} alt="" />
<img src={item2} alt="" />
<img src={item3} alt="" />
<img src={item4} alt="" />
<img src={item5} alt="" />
<img src={item1} alt="" />
<img src={item2} alt="" />
<img src={item3} alt="" />
<img src={item4} alt="" />
<img src={item5} alt="" />
<img src={item1} alt="" />
<img src={item2} alt="" />
<img src={item3} alt="" />
<img src={item4} alt="" />
<img src={item5} alt="" />
</div>
<div className='flex w-96 justify-around'>
<img src={item1} alt="" />
<img src={item2} alt="" />
<img src={item3} alt="" />
<img src={item4} alt="" />
<img src={item5} alt="" />
<img src={item1} alt="" />
<img src={item2} alt="" />
<img src={item3} alt="" />
<img src={item4} alt="" />
<img src={item5} alt="" />
<img src={item1} alt="" />
<img src={item2} alt="" />
<img src={item3} alt="" />
<img src={item4} alt="" />
<img src={item5} alt="" />
</div>
</div>
</div>
</div>
</>
)
}
export default ScrollCarousel

Related

Tailwind & responsive: center horizontally multiple images inside a div

I would like to center images horizontally but I have some responsive issue
<div class="flex items-center justify-center bg-white rounded-tr-lg rounded-bl-lg h-24 p-2 text-center">
<img class="h-full mx-6" src="assets/react.png" alt="react logo" title="React">
<img class="h-full mx-6" src="assets/next.png" alt="next logo" title="Next">
<img class="h-full mx-6" src="assets/redux.png" alt="redux logo" title="Redux">
<img class="h-full mx-6" src="assets/tailwind.png" alt="tailwind logo" title="Tailwind">
<img class="h-full mx-6" src="assets/nestjs.png" alt="redux logo" title="Nest">
<img class="h-full mx-6" src="assets/typeorm.png" alt="tailwind logo" title="Typeorm">
</div>
The result:
Now if I change the dimension of the web browser:
How can I make it responsive ?

Diffrent width and height images layout question in Laravel with fancybox

Here is Photo viewer laravel project. it worked well. but I'm having problem about image layout.
This below image is my current photo gallery page. As you can see images are not line. looks not good.
Becase each uploaded photo size are diffrent width and height so this happens I guess.
I'm using Laravel. And this is fancybox.
and I'm using this gentleman's source code.
https://www.itsolutionstuff.com/post/laravel-5-image-gallery-crud-example-from-scratchexample.html
I had been changing below css parameter but I couldn't fix.
Could you teach me code to fix situation please?
CSS of index.blade.php
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- References: https://github.com/fancyapps/fancyBox -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.min.css" media="screen">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.min.js"></script>
.gallery
{
display: inline-block;
margin-top: 20px;
}
.form-image-upload{
background: #e8e8e8 none repeat scroll 0 0;
padding: 15px;
}
Image output of Index.blade.php
<div class='list-group gallery'>
#if($images->count())
#foreach($images as $image)
<div class='col-sm-4 col-xs-6 col-md-3 col-lg-3'>
<a class="thumbnail fancybox" rel="ligthbox" href="images/{{ $image->image }}">
<img class="img-responsive" alt="" src="images/{{ $image->image }}" />
<div class='text-center'>
<small class='text-muted'>No.{{ $image->id }}</small>
</div> <!-- text-center / end -->
</a>
</div> <!-- col-6 / end -->
#endforeach
#endif
</div>
Why you don't use Image Width and Height just like this
<img class="img-responsive" alt="" src="images/{{ $image->image }}" height="48" width="48"/> // Here 48 in pixel size
You can add a break line every 4 pictures to make it look cleaner - assuming you are using Bootstrap 4:
#foreach($images as $image)
<div class='col-sm-4 col-xs-6 col-md-3 col-lg-3'>
<a class="thumbnail fancybox" rel="ligthbox" href="images/{{ $image->image }}">
<img class="img-responsive" alt="" src="images/{{ $image->image }}" />
<div class='text-center'>
<small class='text-muted'>No.{{ $image->id }}</small>
</div> <!-- text-center / end -->
</a>
</div> <!-- col-6 / end -->
#if ($image->number % 4 == 0)
<div class="w-100"></div>
#endif
#endforeach

how to change the image src in Alpine js like jquery?

there is a div with tag that by click on small image I change the src attribute and show it's the original size, but I don't know how to do in Alpine js?
<div>
<img id="main" />
</div>
/* small images from db */
<div>
foreach($images as $image){
<img id='small' src="images/.$image" />
}
</div>
in jquery :
$("#small").each(function(){
$(this).click(function(){
$("#main").attr('src', $(this).attr('src');)
})
})
})
but I don't know how to do in Alpine js?!
Something like this (using Laravel Blade syntax)?
<div x-data="{imageUrl: ''}">
<section>
<img id="main" :src="imageUrl" />
</section>
<hr />
<div>
#foreach($images as $image)
<img id='small' src="{{ images/.$image }}" #click="imageUrl = '{{ images/.$image }}'" />
#endforeach
</div>
</div>
Demonstrated in a pen here with some dummy data.
Check this codepen: Image Preview Demo. Hope this helps.
<div class="flex items-center justify-center text-gray-500 bg-blue-800 h-screen">
<div class="w-full">
<h3 class="mb-8 text-xl text-center text-white">Image Preview Demo</h3>
<div class="w-full max-w-2xl p-8 mx-auto bg-white rounded-lg">
<div class="" x-data="imageData()">
<div x-show="previewUrl == ''">
<p class="text-center uppercase text-bold">
<label for="thumbnail" class="cursor-pointer">
Upload a file
</label>
<input type="file" name="thumbnail" id="thumbnail" class="hidden" #change="updatePreview()">
</p>
</div>
<div x-show="previewUrl !== ''">
<img :src="previewUrl" alt="" class="rounded">
<div class="">
<button type="button" class="" #click="clearPreview()">change</button>
</div>
</div>
</div>
</div>
<div class="mt-2 text-center text-white">
<a class="w-32 mx-2" href="https://tailwindcss.com/">TailwindCSS</a>
<a class="w-32 mx-2" href="https://github.com/alpinejs/alpine">AlpineJS</a>
</div>
</div>
</div>
You can use x-ref on your main image and then $ref in your Alpine data function to set the src property of your main image. You could define your main image something like:
<img x-ref="mainImage" src="URL TO YOUR FIRST IMAGE" />
For each of your thumbnail images, you can do something like:
<img src="URL TO THUMBNAIL" x-on:click="pickPhoto(ARRAY INDEX)">
Your data function can then include something like this:
...
currentPhoto: 0,
photos: [
"URL TO FIRST IMAGE",
...,
"URL TO LAST IMAGE",
],
pickPhoto(index) {
this.currentPhoto = index;
this.$refs.mainImage.src = this.photos[this.currentPhoto];
},
...
I have uploaded a working example here:
https://tailwindcomponents.com/component/tailwind-css-with-alpine-js-photo-gallery
Note that this is deliberately designed to allow you to have different URLs from your thumbnails and main images, so the thumbnails can be intrinsically smaller, and load very quickly. If you are using the same images for both, you can simplify the code significantly. Each of your thumbnails could be done like this:
<img src="URL TO YOUR FIRST IMAGE" x-on:click="$refs.mainImage.src = 'URL TO YOUR FIRST IMAGE'">
With no need for the pickPhoto function or the photos array.
The downside of the simpler approach is that your page will take longer to load because you won't be using smaller images for your thumbnails.
In AlpineJs you could do something like this.
Not tested, just to make you an idea.
myimages()
{
return {
selected: '',
images: [
'images/1.png',
'images/2.png',
'images/3.png',
'images/4.png'
]
}
}
<div x-data="myimages()">
<div>
<img id="main" :src="selected"/>
</div>
<div>
<template x-for="(selimage, index) in images" :key="index">
<img class='small' :src="selimage" #click="selected = selimage"/>
</template>
</div>
</div>
you can for each both of them like this
<div x-data="{image:'0'}">
<div>
#foreach ($image_src as $key => $image)
<a href="">
<img x-show="image==='{{ $key++ }}'"
src="{{$image}}" alt="">
</a>
#endforeach
</div>
<div class=" overflow-x-scroll ">
#foreach ($image_src as $key=> $image)
<a class="mr-1" on- href="">
<img :class="{' border border-way-pink':image==='{{ $key }}'}"
#click.prevent="image='{{ $key++ }}'"
class="w-32 h-24 mr-5" src="{{$image}}" alt="">
</a>
#endforeach
</div>
</div>

Right way to list image banners

I would like to ask if what is the right way to use 'ul'? will it be okay to use 'ul' to list some image banners? ex. i have 3 image banners with titles and all are floated left. I use to encounter this situation every time and the approach i came up with is the first markup using 'ul'.
Is it okay to use the markup below:
<section class="banners">
<ul>
<li>
<figure>
<a href="#">
<img src="" width="" height="" alt="" />
</a>
</figure>
title here
</li>
<li>
<figure>
<a href="#">
<img src="" width="" height="" alt="" />
</a>
</figure>
title here
</li>
<li>
<figure>
<a href="#">
<img src="" width="" height="" alt="" />
</a>
</figure>
title here
</li>
</ul>
</section>
or should I use:
<section class="banners">
<figure>
<a href="#">
<img src="" width="" height="" alt="" />
</a>
<figcaption>
title here
</figcaption>
</figure>
<figure>
<a href="#">
<img src="" width="" height="" alt="" />
</a>
<figcaption>
title here
</figcaption>
</figure>
<figure>
<a href="#">
<img src="" width="" height="" alt="" />
</a>
<figcaption>
title here
</figcaption>
</figure>
</section>
Do they both represent semantic coding?
This is the sample of the image banner
Since the HTML5 spec is so mercurial and the semantics don't seem to play a major role practically, it's hard to say. However, based on your image, it looks like this is a navigation section. As such, you would want to section it with <nav>.
<ul> spec: http://www.w3.org/TR/html5/grouping-content.html#the-ul-element
<figure> spec: http://www.w3.org/TR/html5/grouping-content.html#the-figure-element
I don't think that these are much help. They are both used for grouping content. The order does not matter for <ul>.
From what I've read, it seems to me that the purpose of <figure> is for annotations of a document -- describing related images, etc. The spec specifically says that these could be moved elsewhere, like an appendix, but that doesn't seem to apply to your situation.
I don't think that <figure> is appropriate here. Instead, use <nav>. You can use the <ul> for styling if you need -- it doesn't provide much semantic meaning (just a somewhat generic grouping content element).

MVC Razor how can i use my HTML helper?

I have created a simple Gallery html helper, its not pretty at the moment, as I cannot get it work with Razor. (I would have liked to use Action as I would have done with the webforms viewengine)
public static HelperResult Gallery<T>(this HtmlHelper html,
IEnumerable<T> items,
int itemsPerRow,
Action rowContainer,
Func<T, HelperResult> itemContainer,
Action endRowContainer)
{
if (items == null)
return new HelperResult(writer => { });
int itemCount = 1;
return new HelperResult(writer =>
{
rowContainer();
foreach (var item in items)
{
if (itemCount % itemsPerRow == 0)
{
endRowContainer();
rowContainer();
}
itemContainer(item).WriteTo(writer);
itemCount++;
}
endRowContainer();
});
}
this is the intened usage, but the rowContainer and endRowContainer are outputed at the top of the generated HTML
#Html.Gallery(
Model.Stores,
3,
()=> { Response.Write("<div class=\"portfolio_box_container\">"); },
#<div class="portfolio_box" style="padding-right: 25px">
<img src="item.png" width="120" height="43" alt="" />
</div>
,
() => { Response.Write("</div>"); })
What im i doing wrong?
if should print off something like:
<div class="portfolio_box_container">
<div class="portfolio_box" style="padding-right: 25px">
<img src="item.png" width="120" height="43" alt="" />
</div>
<div class="portfolio_box" style="padding-right: 25px">
<img src="item.png" width="120" height="43" alt="" />
</div>
<div class="portfolio_box" style="padding-right: 25px">
<img src="item.png" width="120" height="43" alt="" />
</div>
</div>
<div class="portfolio_box_container">
<div class="portfolio_box" style="padding-right: 25px">
<img src="item.png" width="120" height="43" alt="" />
</div>
<div class="portfolio_box" style="padding-right: 25px">
<img src="item.png" width="120" height="43" alt="" />
</div>
<div class="portfolio_box" style="padding-right: 25px">
<img src="item.png" width="120" height="43" alt="" />
</div>
</div>
The problem is that you should use the "writer" parameter of the HelperResult action to write the output in your actions to. Now you use Response.Write that immediately writes to the HTTP response, while the HelperResult has its own writer that will be copied to the response afterward.
The easiest solution is if you use an Action<TextWriter> instead of Action, and then you can pass on the "writer" to your action parts.
E.g. use a parameter Action<TextWriter> rowContainer, and call it as rowContainer(writer) in the Gallery helper.
Then you can pass such an action parameter like (writer)=> { writer.Write("<div class=\"portfolio_box_container\">"); }

Resources