Randomly Generated NFT Collection (10,000+) without Coding Knowledge

How to Randomly Generate 10,000+ NFTs Quickly (Full Collections) and Make Money - No Coding Tutorial

In this video, I cover a new money-making opportunity with NFTs as well as how you can easily create them and generate thousands, even tens of thousands of iterations of artwork!

Download links:
MyPaint: http://mypaint.org 
Visual Studio: https://code.visualstudio.com 
Folder (code) to open in Visual Studio: https://github.com/HashLips/generative-art-node 
Node JS: https://nodejs.org/en/ 

#nft 

What is GEEK

Buddha Community

Randomly Generated NFT Collection (10,000+) without Coding Knowledge
Monty  Boehm

Monty Boehm

1675304280

How to Use Hotwire Rails

Introduction

We are back with another exciting and much-talked-about Rails tutorial on how to use Hotwire with the Rails application. This Hotwire Rails tutorial is an alternate method for building modern web applications that consume a pinch of JavaScript.

Rails 7 Hotwire is the default front-end framework shipped with Rails 7 after it was launched. It is used to represent HTML over the wire in the Rails application. Previously, we used to add a hotwire-rails gem in our gem file and then run rails hotwire: install. However, with the introduction of Rails 7, the gem got deprecated. Now, we use turbo-rails and stimulus rails directly, which work as Hotwire’s SPA-like page accelerator and Hotwire’s modest JavaScript framework.

What is Hotwire?

Hotwire is a package of different frameworks that help to build applications. It simplifies the developer’s work for writing web pages without the need to write JavaScript, and instead sending HTML code over the wire.

Introduction to The Hotwire Framework:

1. Turbo:

It uses simplified techniques to build web applications while decreasing the usage of JavaScript in the application. Turbo offers numerous handling methods for the HTML data sent over the wire and displaying the application’s data without actually loading the entire page. It helps to maintain the simplicity of web applications without destroying the single-page application experience by using the below techniques:

Turbo Frames: Turbo Frames help to load the different sections of our markup without any dependency as it divides the page into different contexts separately called frames and updates these frames individually.
Turbo Drive: Every link doesn’t have to make the entire page reload when clicked. Only the HTML contained within the tag will be displayed.
Turbo Streams: To add real-time features to the application, this technique is used. It helps to bring real-time data to the application using CRUD actions.

2. Stimulus

It represents the JavaScript framework, which is required when JS is a requirement in the application. The interaction with the HTML is possible with the help of a stimulus, as the controllers that help those interactions are written by a stimulus.

3. Strada

Not much information is available about Strada as it has not been officially released yet. However, it works with native applications, and by using HTML bridge attributes, interaction is made possible between web applications and native apps.

Simple diagrammatic representation of Hotwire Stack:

Hotwire Stack

Prerequisites For Hotwire Rails Tutorial

As we are implementing the Ruby on Rails Hotwire tutorial, make sure about the following installations before you can get started.

  • Ruby on Rails
  • Hotwire gem
  • PostgreSQL/SQLite (choose any one database)
  • Turbo Rails
  • Stimulus.js

Looking for an enthusiastic team of ROR developers to shape the vision of your web project?
Contact Bacancy today and hire Ruby developers to start building your dream project!

Create a new Rails Project

Find the following commands to create a rails application.

mkdir ~/projects/railshotwire
cd ~/projects/railshotwire
echo "source 'https://rubygems.org'" > Gemfile
echo "gem 'rails', '~> 7.0.0'" >> Gemfile
bundle install  
bundle exec rails new . --force -d=postgresql

Now create some files for the project, up till now no usage of Rails Hotwire can be seen.
Fire the following command in your terminal.

  • For creating a default controller for the application
echo "class HomeController < ApplicationController" > app/controllers/home_controller.rb
echo "end" >> app/controllers/home_controller.rb
  • For creating another controller for the application
echo "class OtherController < ApplicationController" > app/controllers/other_controller.rb
echo "end" >> app/controllers/home_controller.rb
  • For creating routes for the application
echo "Rails.application.routes.draw do" > config/routes.rb
echo '  get "home/index"' >> config/routes.rb
echo '  get "other/index"' >> config/routes.rb
echo '  root to: "home#index"' >> config/routes.rb
echo 'end' >> config/routes.rb
  • For creating a default view for the application
mkdir app/views/home
echo '<h1>This is Rails Hotwire homepage</h1>' > app/views/home/index.html.erb
echo '<div><%= link_to "Enter to other page", other_index_path %></div>' >> app/views/home/index.html.erb
  • For creating another view for the application
mkdir app/views/other
echo '<h1>This is Another page</h1>' > app/views/other/index.html.erb
echo '<div><%= link_to "Enter to home page", root_path %></div>' >> app/views/other/index.html.erb
  • For creating a database and schema.rb file for the application
bin/rails db:create
bin/rails db:migrate
  • For checking the application run bin/rails s and open your browser, your running application will have the below view.

Rails Hotwire Home Page

Additionally, you can clone the code and browse through the project. Here’s the source code of the repository: Rails 7 Hotwire application

Now, let’s see how Hotwire Rails can work its magic with various Turbo techniques.

Hotwire Rails: Turbo Drive

Go to your localhost:3000 on your web browser and right-click on the Inspect and open a Network tab of the DevTools of the browser.

Now click on go to another page link that appears on the home page to redirect from the home page to another page. In our Network tab, we can see that this action of navigation is achieved via XHR. It appears only the part inside HTML is reloaded, here neither the CSS is reloaded nor the JS is reloaded when the navigation action is performed.

Hotwire Rails Turbo Drive

By performing this action we can see that Turbo Drive helps to represent the HTML response without loading the full page and only follows redirect and reindeer HTML responses which helps to make the application faster to access.

Hotwire Rails: Turbo Frame

This technique helps to divide the current page into different sections called frames that can be updated separately independently when new data is added from the server.
Below we discuss the different use cases of Turbo frame like inline edition, sorting, searching, and filtering of data.

Let’s perform some practical actions to see the example of these use cases.

Make changes in the app/controllers/home_controller.rb file

#CODE

class HomeController < ApplicationController
   def turbo_frame_form
   end
   
   def turbo_frame submit
      extracted_anynumber = params[:any][:anynumber]
      render :turbo_frame_form, status: :ok, locals: {anynumber: extracted_anynumber,      comment: 'turbo_frame_submit ok' }
   end
end

Turbo Frame

Add app/views/home/turbo_frame_form.html.erb file to the application and add this content inside the file.

#CODE

<section>

    <%= turbo_frame_tag 'anyframe' do %>
            
      <div>
          <h2>Frame view</h2>
          <%= form_with scope: :any, url: turbo_frame_submit_path, local: true do |form| %>
              <%= form.label :anynumber, 'Type an integer (odd or even)', 'class' => 'my-0  d-inline'  %>
              <%= form.text_field :anynumber, type: 'number', 'required' => 'true', 'value' => "#{local_assigns[:anynumber] || 0}",  'aria-describedby' => 'anynumber' %>
              <%= form.submit 'Submit this number', 'id' => 'submit-number' %>
          <% end %>
      </div>
      <div>
        <h2>Data of the view</h2>
        <pre style="font-size: .7rem;"><%= JSON.pretty_generate(local_assigns) %></pre> 
      </div>
      
    <% end %>

</section>

Add the content inside file

Make some adjustments in routes.rb

#CODE

Rails.application.routes.draw do
  get 'home/index'
  get 'other/index'

  get '/home/turbo_frame_form' => 'home#turbo_frame_form', as: 'turbo_frame_form'
  post '/home/turbo_frame_submit' => 'home#turbo_frame_submit', as: 'turbo_frame_submit'


  root to: "home#index"
end
  • Next step is to change homepage view in app/views/home/index.html.erb

#CODE

<h1>This is Rails Hotwire home page</h1>
<div><%= link_to "Enter to other page", other_index_path %></div>

<%= turbo_frame_tag 'anyframe' do %>        
  <div>
      <h2>Home view</h2>
      <%= form_with scope: :any, url: turbo_frame_submit_path, local: true do |form| %>
          <%= form.label :anynumber, 'Type an integer (odd or even)', 'class' => 'my-0  d-inline'  %>
          <%= form.text_field :anynumber, type: 'number', 'required' => 'true', 'value' => "#{local_assigns[:anynumber] || 0}",  'aria-describedby' => 'anynumber' %>
          <%= form.submit 'Submit this number', 'id' => 'submit-number' %>
      <% end %>
  <div>
<% end %>

Change HomePage

After making all the changes, restart the rails server and refresh the browser, the default view will appear on the browser.

restart the rails serverNow in the field enter any digit, after entering the digit click on submit button, and as the submit button is clicked we can see the Turbo Frame in action in the below screen, we can observe that the frame part changed, the first title and first link didn’t move.

submit button is clicked

Hotwire Rails: Turbo Streams

Turbo Streams deliver page updates over WebSocket, SSE or in response to form submissions by only using HTML and a series of CRUD-like operations, you are free to say that either

  • Update the piece of HTML while responding to all the other actions like the post, put, patch, and delete except the GET action.
  • Transmit a change to all users, without reloading the browser page.

This transmit can be represented by a simple example.

  • Make changes in app/controllers/other_controller.rb file of rails application

#CODE

class OtherController < ApplicationController

  def post_something
    respond_to do |format|
      format.turbo_stream {  }
    end
  end

   end

file of rails application

Add the below line in routes.rb file of the application

#CODE

post '/other/post_something' => 'other#post_something', as: 'post_something'
Add the below line

Superb! Rails will now attempt to locate the app/views/other/post_something.turbo_stream.erb template at any moment the ‘/other/post_something’ endpoint is reached.

For this, we need to add app/views/other/post_something.turbo_stream.erb template in the rails application.

#CODE

<turbo-stream action="append" target="messages">
  <template>
    <div id="message_1">This changes the existing message!</div>
  </template>
</turbo-stream>
Add template in the rails application

This states that the response will try to append the template of the turbo frame with ID “messages”.

Now change the index.html.erb file in app/views/other paths with the below content.

#CODE

<h1>This is Another page</h1>
<div><%= link_to "Enter to home page", root_path %></div>

<div style="margin-top: 3rem;">
  <%= form_with scope: :any, url: post_something_path do |form| %>
      <%= form.submit 'Post any message %>
  <% end %>
  <turbo-frame id="messages">
    <div>An empty message</div>
  </turbo-frame>
</div>
change the index.html.erb file
  • After making all the changes, restart the rails server and refresh the browser, and go to the other page.

go to the other page

  • Once the above screen appears, click on the Post any message button

Post any message button

This action shows that after submitting the response, the Turbo Streams help the developer to append the message, without reloading the page.

Another use case we can test is that rather than appending the message, the developer replaces the message. For that, we need to change the content of app/views/other/post_something.turbo_stream.erb template file and change the value of the action attribute from append to replace and check the changes in the browser.

#CODE

<turbo-stream action="replace" target="messages">
  <template>
    <div id="message_1">This changes the existing message!</div>
  </template>
</turbo-stream>

change the value of the action attributeWhen we click on Post any message button, the message that appear below that button will get replaced with the message that is mentioned in the app/views/other/post_something.turbo_stream.erb template

click on Post any message button

Stimulus

There are some cases in an application where JS is needed, therefore to cover those scenarios we require Hotwire JS tool. Hotwire has a JS tool because in some scenarios Turbo-* tools are not sufficient. But as we know that Hotwire is used to reduce the usage of JS in an application, Stimulus considers HTML as the single source of truth. Consider the case where we have to give elements on a page some JavaScript attributes, such as data controller, data-action, and data target. For that, a stimulus controller that can access elements and receive events based on those characteristics will be created.

Make a change in app/views/other/index.html.erb template file in rails application

#CODE

<h1>This is Another page</h1>
<div><%= link_to "Enter to home page", root_path %></div>

<div style="margin-top: 2rem;">
  <%= form_with scope: :any, url: post_something_path do |form| %>
      <%= form.submit 'Post something' %>
  <% end %>
  <turbo-frame id="messages">
    <div>An empty message</div>
  </turbo-frame>
</div>

<div style="margin-top: 2rem;">
  <h2>Stimulus</h2>  
  <div data-controller="hello">
    <input data-hello-target="name" type="text">
    <button data-action="click->hello#greet">
      Greet
    </button>
    <span data-hello-target="output">
    </span>
  </div>
</div>

Make A changeMake changes in the hello_controller.js in path app/JavaScript/controllers and add a stimulus controller in the file, which helps to bring the HTML into life.

#CODE

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = [ "name", "output" ]

  greet() {
    this.outputTarget.textContent =
      `Hello, ${this.nameTarget.value}!`
  }
}

add a stimulus controller in the fileGo to your browser after making the changes in the code and click on Enter to other page link which will navigate to the localhost:3000/other/index page there you can see the changes implemented by the stimulus controller that is designed to augment your HTML with just enough behavior to make it more responsive.

With just a little bit of work, Turbo and Stimulus together offer a complete answer for applications that are quick and compelling.

Using Rails 7 Hotwire helps to load the pages at a faster speed and allows you to render templates on the server, where you have access to your whole domain model. It is a productive development experience in ROR, without compromising any of the speed or responsiveness associated with SPA.

Conclusion

We hope you were satisfied with our Rails Hotwire tutorial. Write to us at service@bacancy.com for any query that you want to resolve, or if you want us to share a tutorial on your query.

For more such solutions on RoR, check out our Ruby on Rails Tutorials. We will always strive to amaze you and cater to your needs.

Original article source at: https://www.bacancytechnology.com/

#rails #ruby 

samir G

1627843083

Start Your Gaming Action with peerless NFT Game Development Services

NFTs are becoming more popular in the gaming sector as the demand for unique in-game development increases. Professional NFT Game Development Services deliver a thrilling experience with crypto collectibles. As a professional NFT development company, TokyoTechie is the backbone behind various NFT projects. For more details visit us at TokyoTechie - https://bit.ly/3yglPQG

 

#NFT game development services #NFT gaming development solution #NFT Gaming Platform Solutions #NFT game development company

#NFT gaming software development #NFT gaming platform development services

How to Create a CSS-Only Loader Using One Element

If you have a website, it's helpful to have a loader so users can tell something is happening once they've clicked a link or button.

You can use this loader component in a lot of places, and it should be as simple as possible.

In this post, we will see how to build two types of loaders with only one <div> and a few lines of CSS code. Not only this but we will make them customizable so you can easily create different variations from the same code.

Here's what we'll build:

CSS-only Spinner and Progress Loader

CSS-only Spinner and Progress Loader

How to Create a Spinner Loader

Below is a demo of what we are building:

https://codepen.io/t_afif/pen/PoJyaNy

 <div class="loader"></div>
 <div class="loader" style="--b: 15px;--c: blue;width: 120px;--n: 8"></div>
 <div class="loader" style="--b: 5px;--c: green;width: 80px;--n: 6;--g: 20deg"></div>
 <div class="loader" style="--b: 20px;--c: #000;width: 80px;--n: 15;--g: 7deg"></div> 
 .loader {
   --b: 10px;  /* border thickness */
   --n: 10;    /* number of dashes*/
   --g: 10deg; /* gap between dashes*/
   --c: red;   /* the color */

   width: 100px; /* size */
   aspect-ratio: 1;
   border-radius: 50%;
   padding: 1px;
   background: conic-gradient(#0000,var(--c)) content-box;
   -webkit-mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
           mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
   -webkit-mask-composite: destination-in;
           mask-composite: intersect;
   animation: load 1s infinite steps(var(--n));
 }
 @keyframes load {to{transform: rotate(1turn)}}

We have 4 different loaders using the same code. By only changing a few variables, we can generate a new loader without needing to touch the CSS code.

The variables are defined like below:

  • --b defines the border thickness.
  • --n  defines the number of dashes.
  • --g defines the gap between dashes. Since we're dealing with a circular element, this one is an angle value.
  • --c defines the color.

Here is an illustration to see the different variables.

CSS Variables of the Spinner loader

CSS Variables of the Spinner loader

Let's tackle the CSS code. We will use another figure to illustrate a step-by-step construction of the loader.

Step-by-Step illustration of the Spinner Loader

Step-by-Step illustration of the Spinner Loader

We first start by creating a circle like this:

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
}

Nothing complex so far. Note the use of aspect-ratio which allows us to only modify one value (the width) in order to control the size.

Then we add a conic gradient coloration from transparent to the defined color (the variable --c):

.loader {
  width:100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
}

In this step, we introduce the mask property to hide some parts of the circle in a repetitive manner. This will depend on the --n and --d variables. If you look closely at the figure, we will notice the following pattern:

visible part
invisible part
visible part
invisible part
etc

To do this, we use repeating-conic-gradient(#000 0 X, #0000 0 Y). From 0 to X we have an opaque color (visible part) and from X to Y we have a transparent one (invisible part).

We introduce our variables:

  • We need a gap equal to g between each visible part so the formula between X and Y will be X = Y - g.
  • We need n visible part so the formula of Y should be Y = 360deg/n. A full circle is 360deg so we simply divide it by n

Our code so far is:

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
  mask: repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n))
}

This next step is the trickiest one, because we need to apply another mask to create a kind of hole in order to get the final shape. To do this we will logically use a radial-gradient() with our variable b:

radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0)

A full circle from where we remove a thickness equal to b.

We add this to the previous mask:

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
  mask: 
   radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0),
   repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n))
}

We have two mask layers, but the result is not what we want. We get the following:

It may look strange but it's logical. The "final" visible part is nothing but the sum of each visible part of each mask layer. We can change this behavior using mask-composite. I would need a whole article to explain this property so I will simply give the value.

In our case, we need to consider intersect (and destination-out for the prefixed property). Our code will become:

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
  mask: 
    radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0),
    repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n));
  -webkit-mask-composite: destination-in;
          mask-composite: intersect;
}

We are done with the shape! We are only missing the animation. The latter is an infinite rotation.

The only thing to note is that I am using a steps animation to create the illusion of fixed dashes and moving colors.

Here is an illustration to see the difference

A Linear Animation vs a Steps Animation

The first one is a linear and continuous rotation of the shape (not what we want) and the second one is a discrete animation (the one we want).

Here is the full code including the animation:

 <div class="loader"></div>
 <div class="loader" style="--b: 15px;--c: blue;width: 120px;--n: 8"></div>
 <div class="loader" style="--b: 5px;--c: green;width: 80px;--n: 6;--g: 20deg"></div>
 <div class="loader" style="--b: 20px;--c: #000;width: 80px;--n: 15;--g: 7deg"></div> 
 .loader {
   --b: 10px;  /* border thickness */
   --n: 10;    /* number of dashes*/
   --g: 10deg; /* gap between dashes*/
   --c: red;   /* the color */

   width: 100px; /* size */
   aspect-ratio: 1;
   border-radius: 50%;
   padding: 1px;
   background: conic-gradient(#0000,var(--c)) content-box;
   -webkit-mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
           mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
   -webkit-mask-composite: destination-in;
           mask-composite: intersect;
   animation: load 1s infinite steps(var(--n));
 }
 @keyframes load {to{transform: rotate(1turn)}}

You will notice a few differences with the code I used in the explanation:

  • I am adding padding: 1px and setting the background to content-box
  • There is +/1deg between the colors of the repeating-conic-gradient()
  • There are a few percentages of difference between the color inside the radial-gradient()

Those are some corrections to avoid visual glitches. Gradients are known to produce "strange" results in some cases so we have to adjust some values manually to avoid them.

How to Create a Progress Loader

Like the previous one loader, let's start with an overview:

https://codepen.io/t_afif/pen/bGoNddg

 <div class="loader"></div>
 <div class="loader" style="--s:10px;--n:10;color:red"></div>
 <div class="loader" style="--g:0px;color:darkblue"></div>
 <div class="loader" style="--s:25px;--g:8px;border-radius:50px;color:green"></div>
 .loader {
   --n:5;    /* control the number of stripes */
   --s:30px; /* control the width of stripes */
   --g:5px;  /* control the gap between stripes */

   width:calc(var(--n)*(var(--s) + var(--g)) - var(--g));
   height:30px;
   padding:var(--g);
   margin:5px auto;
   border:1px solid;
   background:
     repeating-linear-gradient(90deg,
       currentColor  0 var(--s),
       #0000 0 calc(var(--s) + var(--g))
     ) left / calc((var(--n) + 1)*(var(--s) + var(--g))) 100% 
     no-repeat content-box;
   animation: load 1.5s steps(calc(var(--n) + 1)) infinite;
 }
 @keyframes load {
   0% {background-size: 0% 100%}
 }

We have the same configuration as the previous loader. CSS variables that control the loader:

  • --n defines the number of dashes/stripes.
  • --s defines the width of each stripe.
  • --g defines the gap between stripes.

Illustration of the CSS Variables

Illustration of the CSS Variables

From the above figure we can see that the width of the element will depend on the 3 variables. The CSS will be as follows:

.loader {
  width: calc(var(--n)*(var(--s) + var(--g)) - var(--g));
  height: 30px; /* use any value you want here */
  padding: var(--g);
  border: 1px solid;
}

We use padding to set the gap on each side. Then the width will be equal to the number of stripes multiplied by their width and the gap. We remove one gap because for N stripes we have N-1 gaps.

To create the stripes we will use the below gradient.

repeating-linear-gradient(90deg,
  currentColor 0 var(--s),
  #0000        0 calc(var(--s) + var(--g))
 )

From 0 to s is the defined color and from s to s + g a transparent color (the gap).

I am using currentColor which is the value of the color property. Note that I didn't define any color inside border so it will also use to the value of color. If we want to change the color of the loader, we only need to set the color property.

Our code so far:

.loader {
  width: calc(var(--n)*(var(--s) + var(--g)) - var(--g));
  height: 30px;
  padding: var(--g);
  border: 1px solid;
  background:
    repeating-linear-gradient(90deg,
      currentColor  0 var(--s),
      #0000 0 calc(var(--s) + var(--g))
    ) left / 100% 100% content-box no-repeat;
}

I am using content-box to make sure the gradient doesn't cover the padding area. Then I define a size equal to 100% 100% and a left position.

It's time for the animation. For this loader, we will animate the background-size from 0% 100% to 100% 100% which means the width of our gradient from 0%  to 100%

Like the previous loader, we will rely on steps() to have a discrete animation instead of a continuous one.

A Linear Animation vs a Steps Animation

The second one is what we want to create, and we can achieve it by adding the following code:

.loader {
  animation: load 1.5s steps(var(--n)) infinite;
}
@keyframes load {
  0% {background-size: 0% 100%}
}

If you look closely at the last figure, you will notice that the animation is not complete. We are missing one stripe at the end, even if we have used N. This is not a bug but how steps() is supposed to work.

To overcome this, we need to add an extra step. We increase the background-size of our gradient to contain N+1 stripes and use steps(N+1). This will get us to the final code:

.loader {
  width: calc(var(--n)*(var(--s) + var(--g)) - var(--g));
  height: 30px;
  padding: var(--g);
  margin: 5px auto;
  border: 1px solid;
  background:
    repeating-linear-gradient(90deg,
      currentColor  0 var(--s),
      #0000 0 calc(var(--s) + var(--g))
    ) left / calc((var(--n) + 1)*(var(--s) + var(--g))) 100% 
    content-box no-repeat;
  animation: load 1.5s steps(calc(var(--n) + 1)) infinite;
}
@keyframes load {
  0% {background-size: 0% 100%}
}

Note that the width of the gradient is equal to N+1 multiplied by the width of one stripe and a gap (instead of being 100% )

Conclusion

I hope you enjoyed this tutorial. If you are interested, I have made more than 500 CSS-only single div loaders. I also wrote another tutorial to explain how to create the Dots loader using only background properties.

Find below useful links to get more detail about some properties I have used that I didn't explain thoroughly due to their complexity:

Thank you for reading!

Link: https://www.freecodecamp.org/news/how-to-create-a-css-only-loader/

#css 

Cómo Crear Un Cargador De Solo CSS Usando Un Elemento

Si tiene un sitio web, es útil tener un cargador para que los usuarios puedan saber que algo está sucediendo una vez que hayan hecho clic en un enlace o botón.

Puede usar este componente del cargador en muchos lugares y debería ser lo más simple posible.

En esta publicación, veremos cómo construir dos tipos de cargadores con solo una <div>y unas pocas líneas de código CSS. No solo esto, sino que los haremos personalizables para que pueda crear fácilmente diferentes variaciones del mismo código.

Esto es lo que construiremos:

Spinner y Progress Loader solo para CSS

Spinner y Progress Loader solo para CSS

Cómo crear un cargador giratorio

A continuación se muestra una demostración de lo que estamos construyendo:

https://codepen.io/t_afif/pen/PoJyaNy

 <div class="loader"></div>
 <div class="loader" style="--b: 15px;--c: blue;width: 120px;--n: 8"></div>
 <div class="loader" style="--b: 5px;--c: green;width: 80px;--n: 6;--g: 20deg"></div>
 <div class="loader" style="--b: 20px;--c: #000;width: 80px;--n: 15;--g: 7deg"></div> 
 .loader {
   --b: 10px;  /* border thickness */
   --n: 10;    /* number of dashes*/
   --g: 10deg; /* gap between dashes*/
   --c: red;   /* the color */

   width: 100px; /* size */
   aspect-ratio: 1;
   border-radius: 50%;
   padding: 1px;
   background: conic-gradient(#0000,var(--c)) content-box;
   -webkit-mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
           mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
   -webkit-mask-composite: destination-in;
           mask-composite: intersect;
   animation: load 1s infinite steps(var(--n));
 }
 @keyframes load {to{transform: rotate(1turn)}}

Tenemos 4 cargadores diferentes usando el mismo código. Con solo cambiar algunas variables, podemos generar un nuevo cargador sin necesidad de tocar el código CSS.

Las variables se definen como sigue:

  • --b define el grosor del borde.
  • --n  define el número de guiones.
  • --gdefine el espacio entre guiones. Como estamos tratando con un elemento circular, este es un valor de ángulo.
  • --c define el color.

Aquí hay una ilustración para ver las diferentes variables.

Variables CSS del cargador Spinner

Variables CSS del cargador Spinner

Abordemos el código CSS. Usaremos otra figura para ilustrar una construcción paso a paso del cargador.

Ilustración paso a paso del cargador giratorio

Ilustración paso a paso del cargador giratorio

Primero comenzamos creando un círculo como este:

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
}

Nada complejo hasta ahora. Tenga en cuenta que su uso aspect-rationos permite modificar solo un valor (el width) para controlar el tamaño.

Luego agregamos una coloración de degradado cónico de transparente al color definido (la variable --c):

.loader {
  width:100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
}

En este paso, introducimos la maskpropiedad para ocultar algunas partes del círculo de forma repetitiva. Esto dependerá de las variables --ny . --dSi observa detenidamente la figura, notaremos el siguiente patrón:

visible part
invisible part
visible part
invisible part
etc

Para hacer esto, usamos repeating-conic-gradient(#000 0 X, #0000 0 Y). De 0a Xtenemos un color opaco (parte visible) y de Xa Ytenemos uno transparente (parte invisible).

Introducimos nuestras variables:

  • Necesitamos un espacio igual a gentre cada parte visible por lo que la fórmula entre Xy Yserá X = Y - g.
  • Necesitamos nla parte visible, por lo que la fórmula de Ydebería ser Y = 360deg/n. Un círculo completo es 360degasí que simplemente lo dividimos porn

Nuestro código hasta ahora es:

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
  mask: repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n))
}

El siguiente paso es el más complicado, porque necesitamos aplicar otra máscara para crear una especie de agujero para obtener la forma final. Para ello usaremos lógicamente a radial-gradient()con nuestra variable b:

radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0)

Un círculo completo del que quitamos un espesor igual a b.

Añadimos esto a la máscara anterior:

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
  mask: 
   radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0),
   repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n))
}

Tenemos dos capas de máscara, pero el resultado no es el que queremos. Obtenemos lo siguiente:

Puede parecer extraño pero es lógico. La parte visible "final" no es más que la suma de cada parte visible de cada capa de máscara. Podemos cambiar este comportamiento usando mask-composite. Necesitaría un artículo completo para explicar esta propiedad, así que simplemente daré el valor.

En nuestro caso, debemos considerar intersect(y destination-outpara la propiedad prefijada). Nuestro código se convertirá en:

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
  mask: 
    radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0),
    repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n));
  -webkit-mask-composite: destination-in;
          mask-composite: intersect;
}

¡Hemos terminado con la forma! Solo nos falta la animación. Esta última es una rotación infinita.

Lo único a tener en cuenta es que estoy usando una stepsanimación para crear la ilusión de guiones fijos y colores en movimiento.

Aquí hay una ilustración para ver la diferencia.

Una animación lineal frente a una animación de pasos

La primera es una rotación lineal y continua de la forma (no la que queremos) y la segunda es una animación discreta (la que queremos).

Aquí está el código completo, incluida la animación:

 <div class="loader"></div>
 <div class="loader" style="--b: 15px;--c: blue;width: 120px;--n: 8"></div>
 <div class="loader" style="--b: 5px;--c: green;width: 80px;--n: 6;--g: 20deg"></div>
 <div class="loader" style="--b: 20px;--c: #000;width: 80px;--n: 15;--g: 7deg"></div> 
 .loader {
   --b: 10px;  /* border thickness */
   --n: 10;    /* number of dashes*/
   --g: 10deg; /* gap between dashes*/
   --c: red;   /* the color */

   width: 100px; /* size */
   aspect-ratio: 1;
   border-radius: 50%;
   padding: 1px;
   background: conic-gradient(#0000,var(--c)) content-box;
   -webkit-mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
           mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
   -webkit-mask-composite: destination-in;
           mask-composite: intersect;
   animation: load 1s infinite steps(var(--n));
 }
 @keyframes load {to{transform: rotate(1turn)}}

Notarás algunas diferencias con el código que usé en la explicación:

  • Estoy agregando padding: 1pxy configurando el fondo paracontent-box
  • Hay +/1degentre los colores de larepeating-conic-gradient()
  • Hay algunos porcentajes de diferencia entre el color dentro del radial-gradient()

Esas son algunas correcciones para evitar fallas visuales. Se sabe que los degradados producen resultados "extraños" en algunos casos, por lo que debemos ajustar algunos valores manualmente para evitarlos.

Cómo crear un cargador de progreso

Al igual que el cargador anterior, comencemos con una descripción general:

https://codepen.io/t_afif/pen/bGoNddg

 <div class="loader"></div>
 <div class="loader" style="--s:10px;--n:10;color:red"></div>
 <div class="loader" style="--g:0px;color:darkblue"></div>
 <div class="loader" style="--s:25px;--g:8px;border-radius:50px;color:green"></div>
 .loader {
   --n:5;    /* control the number of stripes */
   --s:30px; /* control the width of stripes */
   --g:5px;  /* control the gap between stripes */

   width:calc(var(--n)*(var(--s) + var(--g)) - var(--g));
   height:30px;
   padding:var(--g);
   margin:5px auto;
   border:1px solid;
   background:
     repeating-linear-gradient(90deg,
       currentColor  0 var(--s),
       #0000 0 calc(var(--s) + var(--g))
     ) left / calc((var(--n) + 1)*(var(--s) + var(--g))) 100% 
     no-repeat content-box;
   animation: load 1.5s steps(calc(var(--n) + 1)) infinite;
 }
 @keyframes load {
   0% {background-size: 0% 100%}
 }

Tenemos la misma configuración que el cargador anterior. Variables CSS que controlan el cargador:

  • --n define el número de guiones/rayas.
  • --s define el ancho de cada franja.
  • --g define el espacio entre las rayas.

Ilustración de las variables CSS

Ilustración de las variables CSS

De la figura anterior podemos ver que el ancho del elemento dependerá de las 3 variables. El CSS será el siguiente:

.loader {
  width: calc(var(--n)*(var(--s) + var(--g)) - var(--g));
  height: 30px; /* use any value you want here */
  padding: var(--g);
  border: 1px solid;
}

Usamos paddingpara establecer el espacio en cada lado. Entonces el ancho será igual al número de rayas multiplicado por su ancho y el espacio. Eliminamos un espacio porque para Nlas rayas tenemos N-1espacios.

Para crear las rayas usaremos el siguiente degradado.

repeating-linear-gradient(90deg,
  currentColor 0 var(--s),
  #0000        0 calc(var(--s) + var(--g))
 )

De 0a ses el color definido y de sa s + gun color transparente (la brecha).

Estoy usando currentColorcuál es el valor de la colorpropiedad. Tenga en cuenta que no definí ningún color dentro border, por lo que también se usará para el valor de color. Si queremos cambiar el color del cargador, solo necesitamos establecer la colorpropiedad.

Nuestro código hasta ahora:

.loader {
  width: calc(var(--n)*(var(--s) + var(--g)) - var(--g));
  height: 30px;
  padding: var(--g);
  border: 1px solid;
  background:
    repeating-linear-gradient(90deg,
      currentColor  0 var(--s),
      #0000 0 calc(var(--s) + var(--g))
    ) left / 100% 100% content-box no-repeat;
}

Estoy usando content-boxpara asegurarme de que el degradado no cubra el área de relleno. Luego defino un tamaño igual a 100% 100%y una posición izquierda.

Es hora de la animación. Para este cargador, animaremos el background-sizede 0% 100%a 100% 100%lo que significa el ancho de nuestro degradado de 0%  a100%

Al igual que el cargador anterior, confiaremos en steps()tener una animación discreta en lugar de una continua.

Una animación lineal frente a una animación de pasos

El segundo es el que queremos crear, y lo podemos lograr agregando el siguiente código:

.loader {
  animation: load 1.5s steps(var(--n)) infinite;
}
@keyframes load {
  0% {background-size: 0% 100%}
}

Si observa detenidamente la última figura, notará que la animación no está completa. Nos falta una raya al final, incluso si hemos usado N. Esto no es un error, sino cómo steps()se supone que funciona.

Para superar esto, necesitamos agregar un paso adicional. Aumentamos el background-sizede nuestro degradado para contener N+1rayas y usar steps(N+1). Esto nos llevará al código final:

.loader {
  width: calc(var(--n)*(var(--s) + var(--g)) - var(--g));
  height: 30px;
  padding: var(--g);
  margin: 5px auto;
  border: 1px solid;
  background:
    repeating-linear-gradient(90deg,
      currentColor  0 var(--s),
      #0000 0 calc(var(--s) + var(--g))
    ) left / calc((var(--n) + 1)*(var(--s) + var(--g))) 100% 
    content-box no-repeat;
  animation: load 1.5s steps(calc(var(--n) + 1)) infinite;
}
@keyframes load {
  0% {background-size: 0% 100%}
}

Tenga en cuenta que el ancho del degradado es igual a N+1multiplicado por el ancho de una franja y un espacio (en lugar de ser 100%)

Conclusión

Espero que disfrutes este tutorial. Si está interesado, he creado más de 500 cargadores div únicos solo para CSS . También escribí otro tutorial para explicar cómo crear el cargador de puntos usando solo propiedades de fondo .

Encuentre a continuación enlaces útiles para obtener más detalles sobre algunas propiedades que he usado y que no expliqué a fondo debido a su complejidad:

¡Gracias por leer!

Enlace: https://www.freecodecamp.org/news/how-to-create-a-css-only-loader/

#css 

山本  洋介

山本 洋介

1642923600

1つの要素を使用してCSSのみのローダーを作成する

Webサイトがある場合は、ローダーを使用すると、ユーザーがリンクまたはボタンをクリックすると何かが起こっていることを知ることができるので便利です。

このローダーコンポーネントは多くの場所で使用でき、可能な限りシンプルにする必要があります。

<div>この投稿では、1行と数行のCSSコードで2種類のローダーを構築する方法を説明します。これだけでなく、同じコードからさまざまなバリエーションを簡単に作成できるようにカスタマイズできるようにします。

これが私たちが構築するものです:

CSSのみのスピナーとプログレスローダー

CSSのみのスピナーとプログレスローダー

スピナーローダーを作成する方法

以下は、私たちが構築しているもののデモです。

https://codepen.io/t_afif/pen/PoJyaNy

 <div class="loader"></div>
 <div class="loader" style="--b: 15px;--c: blue;width: 120px;--n: 8"></div>
 <div class="loader" style="--b: 5px;--c: green;width: 80px;--n: 6;--g: 20deg"></div>
 <div class="loader" style="--b: 20px;--c: #000;width: 80px;--n: 15;--g: 7deg"></div> 
 .loader {
   --b: 10px;  /* border thickness */
   --n: 10;    /* number of dashes*/
   --g: 10deg; /* gap between dashes*/
   --c: red;   /* the color */

   width: 100px; /* size */
   aspect-ratio: 1;
   border-radius: 50%;
   padding: 1px;
   background: conic-gradient(#0000,var(--c)) content-box;
   -webkit-mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
           mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
   -webkit-mask-composite: destination-in;
           mask-composite: intersect;
   animation: load 1s infinite steps(var(--n));
 }
 @keyframes load {to{transform: rotate(1turn)}}

同じコードを使用する4つの異なるローダーがあります。いくつかの変数を変更するだけで、CSSコードに触れることなく新しいローダーを生成できます。

変数は次のように定義されます。

  • --b 境界線の太さを定義します。
  • --n  ダッシュの数を定義します。
  • --gダッシュ間のギャップを定義します。円形の要素を扱っているので、これは角度の値です。
  • --c 色を定義します。

これは、さまざまな変数を確認するための図です。

スピナーローダーのCSS変数

スピナーローダーのCSS変数

CSSコードに取り組みましょう。別の図を使用して、ローダーの段階的な構成を説明します。

スピナーローダーのステップバイステップの図

スピナーローダーのステップバイステップの図

まず、次のような円を作成します。

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
}

これまでのところ複雑なことはありません。これを使用すると、サイズを制御するためにaspect-ratio1つの値()のみを変更できることに注意してください。width

次に、透明から定義された色(変数--c)に円錐曲線の色を追加します。

.loader {
  width:100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
}

このステップでmaskは、円の一部を繰り返し非表示にするプロパティを紹介します。--nこれはと--d変数に依存します。図をよく見ると、次のパターンに気付くでしょう。

visible part
invisible part
visible part
invisible part
etc

これを行うには、を使用しますrepeating-conic-gradient(#000 0 X, #0000 0 Y)。から0までXは不透明な色(可視部分)があり、からXまでYは透明な色(不可視部分)があります。

変数を紹介します。

  • との間の式がになるgように、各可視部分の間に等しいギャップが必要です。XYX = Y - g
  • n目に見える部分が必要なので、の式YY = 360deg/nです。完全な円は360deg、単純にで割ったものです。n

これまでのコードは次のとおりです。

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
  mask: repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n))
}

この次のステップは最も難しいステップです。最終的な形状を取得するために、別のマスクを適用して一種の穴を作成する必要があるためです。これを行うにはradial-gradient()、変数で論理的にaを使用しますb

radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0)

に等しい厚さを削除するところから完全な円b

これを前のマスクに追加します。

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
  mask: 
   radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0),
   repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n))
}

2つのマスクレイヤーがありますが、結果は私たちが望むものではありません。次のようになります。

奇妙に見えるかもしれませんが、それは論理的です。「最終的な」可視部分は、各マスクレイヤーの各可視部分の合計に他なりません。この動作は、を使用して変更できますmask-composite。このプロパティを説明するために記事全体が必要になるので、単純に値を示します。

intersect私たちの場合、 (そしてdestination-out接頭辞付きのプロパティについて)考慮する必要があります。コードは次のようになります。

.loader {
  width: 100px; /* size */
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#0000,var(--c));
  mask: 
    radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0),
    repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--g)) , #0000 0 calc(360deg/var(--n));
  -webkit-mask-composite: destination-in;
          mask-composite: intersect;
}

形が出来上がりました!アニメーションが欠けているだけです。後者は無限回転です。

注意すべき唯一のことは、stepsアニメーションを使用して、固定されたダッシュと動く色の錯覚を作成しているということです。

これが違いを見るためのイラストです

線形アニメーションとステップアニメーション

最初のものは形状の線形で連続的な回転であり(私たちが望むものではありません)、2番目のものは離散アニメーション(私たちが望むもの)です。

アニメーションを含む完全なコードは次のとおりです。

 <div class="loader"></div>
 <div class="loader" style="--b: 15px;--c: blue;width: 120px;--n: 8"></div>
 <div class="loader" style="--b: 5px;--c: green;width: 80px;--n: 6;--g: 20deg"></div>
 <div class="loader" style="--b: 20px;--c: #000;width: 80px;--n: 15;--g: 7deg"></div> 
 .loader {
   --b: 10px;  /* border thickness */
   --n: 10;    /* number of dashes*/
   --g: 10deg; /* gap between dashes*/
   --c: red;   /* the color */

   width: 100px; /* size */
   aspect-ratio: 1;
   border-radius: 50%;
   padding: 1px;
   background: conic-gradient(#0000,var(--c)) content-box;
   -webkit-mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
           mask:
     repeating-conic-gradient(#0000 0deg,
        #000 1deg calc(360deg/var(--n) - var(--g) - 1deg),
        #0000     calc(360deg/var(--n) - var(--g)) calc(360deg/var(--n))),
     radial-gradient(farthest-side,#0000 calc(98% - var(--b)),#000 calc(100% - var(--b)));
   -webkit-mask-composite: destination-in;
           mask-composite: intersect;
   animation: load 1s infinite steps(var(--n));
 }
 @keyframes load {to{transform: rotate(1turn)}}

説明で使用したコードとの違いに気付くでしょう。

  • padding: 1px背景を追加して設定していますcontent-box
  • +/1degの色の間にありますrepeating-conic-gradient()
  • 内側の色には数パーセントの違いがあります radial-gradient()

これらは、視覚的な不具合を回避するためのいくつかの修正です。グラデーションは「奇妙な」結果を生成することが知られているため、それらを回避するためにいくつかの値を手動で調整する必要があります。

プログレスローダーを作成する方法

前のローダーと同様に、概要から始めましょう。

https://codepen.io/t_afif/pen/bGoNddg

 <div class="loader"></div>
 <div class="loader" style="--s:10px;--n:10;color:red"></div>
 <div class="loader" style="--g:0px;color:darkblue"></div>
 <div class="loader" style="--s:25px;--g:8px;border-radius:50px;color:green"></div>
 .loader {
   --n:5;    /* control the number of stripes */
   --s:30px; /* control the width of stripes */
   --g:5px;  /* control the gap between stripes */

   width:calc(var(--n)*(var(--s) + var(--g)) - var(--g));
   height:30px;
   padding:var(--g);
   margin:5px auto;
   border:1px solid;
   background:
     repeating-linear-gradient(90deg,
       currentColor  0 var(--s),
       #0000 0 calc(var(--s) + var(--g))
     ) left / calc((var(--n) + 1)*(var(--s) + var(--g))) 100% 
     no-repeat content-box;
   animation: load 1.5s steps(calc(var(--n) + 1)) infinite;
 }
 @keyframes load {
   0% {background-size: 0% 100%}
 }

以前のローダーと同じ構成になっています。ローダーを制御するCSS変数:

  • --n ダッシュ/ストライプの数を定義します。
  • --s 各ストライプの幅を定義します。
  • --g ストライプ間のギャップを定義します。

CSS変数の図

CSS変数の図

上の図から、要素の幅が3つの変数に依存することがわかります。CSSは次のようになります。

.loader {
  width: calc(var(--n)*(var(--s) + var(--g)) - var(--g));
  height: 30px; /* use any value you want here */
  padding: var(--g);
  border: 1px solid;
}

padding両側にギャップを設定するために使用します。その場合、幅はストライプの数に幅とギャップを掛けたものに等しくなります。Nストライプにはギャップがあるため、1つのギャップを削除しN-1ます。

ストライプを作成するには、以下のグラデーションを使用します。

repeating-linear-gradient(90deg,
  currentColor 0 var(--s),
  #0000        0 calc(var(--s) + var(--g))
 )

From 0tosは定義された色であり、from stos + gは透明色(ギャップ)です。

currentColorプロパティの値であるwhichを使用していcolorます。内部に色を定義しなかったためborder、の値にも使用されることに注意してくださいcolor。ローダーの色を変更したい場合は、colorプロパティを設定するだけです。

これまでのコード:

.loader {
  width: calc(var(--n)*(var(--s) + var(--g)) - var(--g));
  height: 30px;
  padding: var(--g);
  border: 1px solid;
  background:
    repeating-linear-gradient(90deg,
      currentColor  0 var(--s),
      #0000 0 calc(var(--s) + var(--g))
    ) left / 100% 100% content-box no-repeat;
}

content-boxグラデーションがパディング領域をカバーしないようにするために使用しています。100% 100%次に、左の位置に等しいサイズを定義します。

アニメーションの時間です。このローダーでは、background-sizefrom 0% 100%toをアニメーション化します。これは、fromから  toへ100% 100%のグラデーションの幅を意味します。0%100%

steps()以前のローダーと同様に、連続的なアニメーションではなく、個別のアニメーションを使用することに依存します。

線形アニメーションとステップアニメーション

2つ目は作成したいもので、次のコードを追加することで実現できます。

.loader {
  animation: load 1.5s steps(var(--n)) infinite;
}
@keyframes load {
  0% {background-size: 0% 100%}
}

最後の図をよく見ると、アニメーションが完全ではないことがわかります。を使用したとしても、最後に1つのストライプがありませんN。これはバグではありませんが、どのように機能するsteps()はずです。

これを克服するには、追加のステップを追加する必要があります。background-sizeグラデーションを増やしてN+1ストライプを含め、を使用しますsteps(N+1)。これにより、最終的なコードが表示されます。

.loader {
  width: calc(var(--n)*(var(--s) + var(--g)) - var(--g));
  height: 30px;
  padding: var(--g);
  margin: 5px auto;
  border: 1px solid;
  background:
    repeating-linear-gradient(90deg,
      currentColor  0 var(--s),
      #0000 0 calc(var(--s) + var(--g))
    ) left / calc((var(--n) + 1)*(var(--s) + var(--g))) 100% 
    content-box no-repeat;
  animation: load 1.5s steps(calc(var(--n) + 1)) infinite;
}
@keyframes load {
  0% {background-size: 0% 100%}
}

グラデーションの幅は、N+1(ではなく100%) 1つのストライプとギャップの幅を掛けたものに等しいことに注意してください。

結論

このチュートリアルを楽しんでいただけたでしょうか。興味があれば、私は500以上のCSSのみのシングルdivローダーを作成しました。また、バックグラウンドプロパティのみを使用してドットローダーを作成する方法を説明する別のチュートリアルを作成しました。

以下の便利なリンクを見つけて、複雑さのために完全には説明しなかった、私が使用したいくつかのプロパティの詳細を確認してください。

読んでくれてありがとう!

リンク:https ://www.freecodecamp.org/news/how-to-create-a-css-only-loader/

#css