<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marius Reimer</title>
    <description>The latest articles on DEV Community by Marius Reimer (@reime005).</description>
    <link>https://dev.to/reime005</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F144061%2Faad483ef-e378-437e-9add-2284932c62fe.jpeg</url>
      <title>DEV Community: Marius Reimer</title>
      <link>https://dev.to/reime005</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/reime005"/>
    <language>en</language>
    <item>
      <title>Svelte with Rust and a GraphQL REST API Wrapper</title>
      <dc:creator>Marius Reimer</dc:creator>
      <pubDate>Mon, 08 Feb 2021 03:10:59 +0000</pubDate>
      <link>https://dev.to/reime005/svelte-with-rust-and-a-graphql-rest-api-wrapper-4293</link>
      <guid>https://dev.to/reime005/svelte-with-rust-and-a-graphql-rest-api-wrapper-4293</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Frust-graphql-pokeapi-hq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Frust-graphql-pokeapi-hq.jpg" alt="Svelte with Rust and GraphQL REST API Wrapper"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GraphQL has become a new alternative for developing APIs other than the common REST approach. Being more lightweight by selectively requesting fields (querying) instead of transmitting unnecessary data just makes sense. With these and other benefits there also are disadvantages like the knowledge it requires to maintain, develop or offer such an API (not every customer wants GraphQL).&lt;/p&gt;

&lt;p&gt;What you could do is to add GraphQL to your existing REST API, basically as a thin layer on top of it. This gives you the benefit of being able to use both. Of course, there is also the cost of maintaining both.&lt;/p&gt;

&lt;p&gt;I decided to create a GraphQL server for the open source PokeAPI. For that, I've used Rust, with the &lt;strong&gt;Juniper&lt;/strong&gt; GraphQL library, with &lt;strong&gt;Actix Web&lt;/strong&gt; as a web server implementation. Serialization of objects has been done with &lt;strong&gt;Serde&lt;/strong&gt;. The whole thing is a wrapper on top of the pokerust REST client. Lastly, I've built a small web interface with Svelte in form of a PokeDex which displays some basic Pokemon information.&lt;/p&gt;

&lt;p&gt;You can find the source code &lt;a href="https://github.com/reime005/graphql_pokeapi_rust" rel="noopener noreferrer"&gt;on Github&lt;/a&gt; and the Svelte PokeDex UI &lt;a href="https://graphql-pokeapi-rust.reime005.vercel.app" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/RV-8q-AkPd8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL
&lt;/h3&gt;

&lt;p&gt;In GraphQL you have a single endpoint or URL that the client is communicating with. You can enable clients to authenticate, query (&lt;strong&gt;R&lt;/strong&gt;ead), mutate (&lt;strong&gt;C&lt;/strong&gt;reate, &lt;strong&gt;U&lt;/strong&gt;pdate, &lt;strong&gt;D&lt;/strong&gt;elete) data and also listen or subscribe to data changes. When the GraphQL server receives a query, it needs to resolve all data that is required. This can happen through different data sources, like a data base or REST api.&lt;/p&gt;

&lt;p&gt;From an HTTP layer perspective, GraphQL is usually based on POST and not GET. Reason for that is mostly the limited amount of data that you can send (query) with GET. This also comes with the challenge of no client side caching. You may read more about it in &lt;a href="https://www.apollographql.com/blog/graphql-caching-the-elephant-in-the-room-11a3df0c23ad/" rel="noopener noreferrer"&gt;this article&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Playground
&lt;/h4&gt;

&lt;p&gt;GraphQL libraries often provide a playground, which is a tool to explore the API with. That is a pretty much self documented way to develop an API, similar to what you might know from the OpenAPI specification. You can explore the whole schema with it and test or execute queries. You can find an example &lt;a href="https://graphql-pokeapi.herokuapp.com/graphiql" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rust
&lt;/h3&gt;

&lt;p&gt;I chose Rust as a programming language because it aims to deliver high performance and an effective or safe way of memory management. The rough idea is that memory that you use or allocate is managed or freed after specific conditions. These conditions are defined statically on the language level, so that as long as it compiles, memory will usually be safely handled.&lt;/p&gt;

&lt;p&gt;One of the best choices for Rust web server libraries currently is &lt;strong&gt;Actix Web&lt;/strong&gt;. It provides ways to setup things like CORS and all necessary routes to the GraphQL endpoint. The main endpoint is defined via POST on &lt;code&gt;/graphql&lt;/code&gt; and the playground via GET on &lt;code&gt;/graphiql&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can also take use of environment variables to change port and ip of the server without recompiling. This is where &lt;strong&gt;Dotenv&lt;/strong&gt; can be helpful.&lt;/p&gt;

&lt;h4&gt;
  
  
  Query Example
&lt;/h4&gt;

&lt;p&gt;There are different ways of creating the GraphQL schema. Either schema first, where you directly define the schema or code first, where your schema is generated based on the code that you have written. Juniper uses the &lt;strong&gt;code first schema&lt;/strong&gt; approach, but there is an alternative &lt;a href="https://github.com/davidpdrsn/juniper-from-schema" rel="noopener noreferrer"&gt;schema-to-juniper&lt;/a&gt; generator.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This function translates to the query named &lt;code&gt;pokemonByName&lt;/code&gt;. However, Juniper provides a way to adjust the final name. This can be useful for example if an object has the field &lt;code&gt;move&lt;/code&gt;, which is a keyword in the Rust language. As you see in the query, we only want the &lt;code&gt;height&lt;/code&gt; of the queried pokemon.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Object Conversion Trait
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://doc.rust-lang.org/book/ch10-02-traits.html" rel="noopener noreferrer"&gt;Traits&lt;/a&gt; in Rust are pretty much its way of an interface, so you can specify a set of shared behavior for types with it. Since we are using the pokerust library, we receive objects (structs) that are not fully compatible with Juniper. For example, some data types were &lt;code&gt;i16&lt;/code&gt; or similar, which are not natural to GraphQL. Basic data types in GraphQL are called &lt;a href="https://graphql-rust.github.io/juniper/current/types/scalars.html" rel="noopener noreferrer"&gt;Scalars&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You may create custom scalars for GraphQL with Juniper, but I have decided to just convert them to &lt;code&gt;String&lt;/code&gt;. This is where the object conversion trait &lt;code&gt;From&amp;lt;T&amp;gt;&lt;/code&gt; is useful. It allows to implement a type conversion so that you can do the following: &lt;code&gt;let pokemon = GraphedPokemon::from(pokemon_to_convert)&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Svelte
&lt;/h3&gt;

&lt;p&gt;In the end, we want to display some data to make use of the GraphQL API. For that, I have decided to use &lt;a href="https://svelte.dev" rel="noopener noreferrer"&gt;Svelte&lt;/a&gt; as an alternative approach to React. To me, it felt much more native to "VanillaJS". This is already one of the features of Svelte. Besides that, there is no virtual DOM, so in the end you should have less JavaScript code that needs to do manipulation in the browser.&lt;/p&gt;

&lt;p&gt;Code optimization is done at compile time. Also, state management is much simpler, by being reactive itself. Some downsides could be, as with every framework, that is less adopted, less popular and you may find less developers to maintain your code.&lt;/p&gt;

&lt;p&gt;Showing Svelte code here would be a bit too much, but the syntax is quite easy to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying to Heroku
&lt;/h2&gt;

&lt;p&gt;I have used Github Actions as a simple CI/CD. The Rust app is deployed to Heroku via Docker. I have added the &lt;code&gt;pokeapi&lt;/code&gt; repository as a git submodule and deployed the Python app in the Docker container, too. On start of the container, both server are started and GraphQL server uses the local REST API. For Heroku, you have to make sure that your server's port can be changed via the &lt;code&gt;PORT&lt;/code&gt; environment variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The technology stack of Juniper and Actix to build a GraphQL server is probably the best way to do it in Rust right now, even though Juniper is still pretty much in development where API changes are common. In practice, you would usually have a database, where &lt;a href="http://diesel.rs" rel="noopener noreferrer"&gt;Diesel&lt;/a&gt; is used. The way of creating a GraphQL schema via code is also not always the preferred way. Svelte is interesting to work with, had pretty much no dependencies to install and compiled fast.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://mariusreimer.com" rel="noopener noreferrer"&gt;https://mariusreimer.com&lt;/a&gt; on February 8, 2021.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>graphql</category>
      <category>svelte</category>
    </item>
    <item>
      <title>Typed Config via Context in React Native</title>
      <dc:creator>Marius Reimer</dc:creator>
      <pubDate>Sat, 23 Jan 2021 14:22:51 +0000</pubDate>
      <link>https://dev.to/reime005/typed-config-via-context-in-react-native-5478</link>
      <guid>https://dev.to/reime005/typed-config-via-context-in-react-native-5478</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CpkgIeio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/rn-config-context-hq.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CpkgIeio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/rn-config-context-hq.jpeg" alt="Typed Config via Context in React Native"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contexts are common in most programming languages or frameworks. They are mostly used to contain and share specific information or functionality across different parts of an application. Sometimes they are used to inject behavior depending on the use case, like testing or production. I explain how I have used React Context to share configuration data across a React Native app with TypeScript support.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Android&lt;/strong&gt; app development, the context is used to access &lt;a href="https://developer.android.com/reference/android/content/Context"&gt;application environment specific information&lt;/a&gt;. Things like starting new activities (app instances), services/broadcasts (like alarm clocks) or theme data is handled by that.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Flutter&lt;/strong&gt;, the purpose of the context property is to &lt;a href="https://api.flutter.dev/flutter/widgets/State/context.html"&gt;localize the widget&lt;/a&gt; inside the app's hierarchy tree. With that, you could also perform media queries to get the device size, or to retrieve theme data.&lt;/p&gt;

&lt;h2&gt;
  
  
  React Context
&lt;/h2&gt;

&lt;p&gt;In React, same applies to &lt;strong&gt;React Native&lt;/strong&gt;, context helps you with &lt;a href="https://reactjs.org/docs/context.html"&gt;sharing data between&lt;/a&gt; different parts (components) of your application. It is to say that this has to happen top-down, so you have to &lt;strong&gt;provide&lt;/strong&gt; data "early" in your application in order for child components to &lt;strong&gt;consume&lt;/strong&gt; that data. This explain the two important concepts: Context.Provider and Context.Consumer.&lt;/p&gt;

&lt;p&gt;As docs also state that you should only use React Context for global app information, such as user information or language settings. It generally helps you to share data between different nesting levels. Otherwise, you could pass data via &lt;code&gt;props&lt;/code&gt; and/or compose different components, so that these components share specific state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frequent changes
&lt;/h3&gt;

&lt;p&gt;Important to highlight is the fact of component re-rendering. You have to be careful about unnecessary rendering of components that consume a context that changes often. This could be solved by context splitting, means that you keep rarely changing data in the global context and create further contexts that only contain specific, frequently changing data.&lt;/p&gt;

&lt;p&gt;In this example I used &lt;code&gt;react-native-config&lt;/code&gt; to add environment specific that I then added to a app config via context. You can then easily put information to the &lt;code&gt;.env&lt;/code&gt; file and consume that in the app. This could also be combined with a dynamic replacement of secrets for your application, so that you can keep sensitive data in your CI/CD for example. You can see an example in &lt;a href="https://github.com/reime005/SpaceSeek/blob/master/.github/workflows/ci.yml#L35"&gt;one of my apps&lt;/a&gt;. Please note that secrets will still appear in your application, since they are inside your JavaScript bundle. The benefit is that you can hide it in your version control.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Since we want to use the benefits of TypeScript, we will create an interface for the shared &lt;code&gt;Config&lt;/code&gt; data. This will include some arbitrary data and a set of the secrets that we put in the &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When setting up the context data, you want to have specified the &lt;code&gt;initialStore&lt;/code&gt; for passing it to the context creator. From there on, we can export and later use the &lt;code&gt;Context.Provider&lt;/code&gt; as a component wrapper. You could then export the created context and consume it using &lt;code&gt;React.useContext&lt;/code&gt; or make it simpler by creating a wrapper hook called &lt;code&gt;useConfig&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Finally, on top of wrapping your app in the context provider, you actually create its state and pass it to the provider. That way the context can be used to share the data. There you could also perform asynchronous loading of config data (often called hydration), for example to load changed theme or language preferences from the device.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And finally, you will see the usage of &lt;code&gt;useConfig&lt;/code&gt; in the &lt;code&gt;Example&lt;/code&gt; component. This way you can easily access config variables from any component of your React Native app.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Originally published at &lt;a href="https://mariusreimer.com/blog/id/rn-config-context"&gt;https://mariusreimer.com&lt;/a&gt; on January 23, 2021.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>App Onboarding Experience in Flutter</title>
      <dc:creator>Marius Reimer</dc:creator>
      <pubDate>Wed, 20 Jan 2021 23:41:43 +0000</pubDate>
      <link>https://dev.to/reime005/app-onboarding-experience-in-flutter-4o4p</link>
      <guid>https://dev.to/reime005/app-onboarding-experience-in-flutter-4o4p</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Fflutter-onboarding-experience-hq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Fflutter-onboarding-experience-hq.png" alt="App Onboarding Experience in Flutter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Many mobile apps have a unique flow of experience that the user has to go through. A tutorial or onboarding screen can help with explaining the steps that the user has to do in the app. I show roughly how I created such a screen in Flutter. The source code can be found &lt;a href="https://github.com/reime005/FlutterOnboarding" rel="noopener noreferrer"&gt;on Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/XgtzUORaYKU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The Important Widgets
&lt;/h2&gt;

&lt;p&gt;Widgets that I have used in this example are the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SafeArea&lt;/li&gt;
&lt;li&gt;Column, Row, Container, AnimatedContainer&lt;/li&gt;
&lt;li&gt;Text, FlatButton&lt;/li&gt;
&lt;li&gt;SvgPicture from 'flutter_svg'&lt;/li&gt;
&lt;li&gt;Expanded, Padding&lt;/li&gt;
&lt;li&gt;PageView&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Important to highlight here are the first and last one. The &lt;code&gt;SafeArea&lt;/code&gt; helps you using only the area of the phone that is safe to be used for designing. That is, rounded borders from certain devices. With help of the &lt;code&gt;PageView&lt;/code&gt; you can create the horizontal page scroll effect.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Fflutter-onboarding-experience-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Fflutter-onboarding-experience-1.png" alt="Flutter Animated Page Position Indicator"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, we want to define the data that we use for the explanation screens. For that, a specific class &lt;code&gt;ExplanationData&lt;/code&gt; will be defined, to hold these information. Each page has a specific background color, title, short description and an image on top. The image will handled as vector graphics via &lt;code&gt;flutter_svg&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  The Animated Page Position Indicator
&lt;/h2&gt;

&lt;p&gt;The next code snippet shows the state handling of the &lt;code&gt;PageView&lt;/code&gt; widget, so that we can track the current page index and programmatically (when pressing on a button) jump the next page. It also shows the create function for the page indicator circles. For each page we render a specific circle, with when the current page is selected, the circle is about three times wider. This gives a better impression of where the user is currently. Using the &lt;code&gt;AnimatedContainer&lt;/code&gt; we can achieve a simple animation effect.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Lastly, you see a snippet of the horizontal &lt;code&gt;PageView&lt;/code&gt; widget. Using the &lt;code&gt;onPageChanged&lt;/code&gt; callback, we can track the current index, leading to a re-render of the page indicators. These indicators are generated with the help of &lt;code&gt;List.generate&lt;/code&gt; and by using the length of the previously defined &lt;code&gt;data&lt;/code&gt;, put into a &lt;code&gt;Row&lt;/code&gt; widget.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Originally published at &lt;a href="https://mariusreimer.com" rel="noopener noreferrer"&gt;https://mariusreimer.com&lt;/a&gt; on January 20, 2021.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>ux</category>
    </item>
    <item>
      <title>Animated Book Star Rating in React Native</title>
      <dc:creator>Marius Reimer</dc:creator>
      <pubDate>Wed, 13 Jan 2021 16:48:37 +0000</pubDate>
      <link>https://dev.to/reime005/animated-book-star-rating-in-react-native-1oi8</link>
      <guid>https://dev.to/reime005/animated-book-star-rating-in-react-native-1oi8</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Frn-animated-star-rating.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Frn-animated-star-rating.png" alt="Animated Book Start Rating in React Native"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Animations can make already good apps look and feel even better. It can improve the user experience by making actions feel more natural or living. One use case of animations are modals or pop ups, that dynamically display content on the screen. I will describe how you can create a modal in React Native, that opens and closes from/to the bottom.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/gTjrigBf1f8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In addition, the modal will have a vector-based star rating box, in order to make the user rate an item (in this case books). Also, the backdrop of the modal blurs the content behind it. This should make the modal fell more natural. Works on Android and iOS. You can find the full source code &lt;a href="https://github.com/reime005/ReactNativeStarRating" rel="noopener noreferrer"&gt;on Github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Modal
&lt;/h2&gt;

&lt;p&gt;The Modal consists of several views, but the root should be positioned absolute, otherwise you may run into problems with your layout. Also, the modal needs an &lt;code&gt;Animated.View&lt;/code&gt; component, that contains the &lt;code&gt;PanResponder&lt;/code&gt; functionality, in order to handle the swipe events. For the blur effect, which is rather simple to achieve, &lt;code&gt;@react-native-community/blur&lt;/code&gt; is being used. Note that the entire screen will be covered by the pan handler, since we also want to catch if the user clicked on the backdrop/blur view.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When it comes to the actual modal window, I set the height it to be 25% of the screen's height, as defined in &lt;code&gt;MODAL_HEIGHT&lt;/code&gt;. As you will see later, we track the amount of pixels that the modal has been swiped down in a React reference as &lt;code&gt;Animated.ValueXY&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using the reference value, we can change the opacity of the modal window, depending on how far the modal has transitioned. For this, we will use interpolation, mapping the position (translation) of the modal window to an opacity value between 1 (fully open) and 0.5 (modal is out of screen).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Jumping forward to the actual content of the modal window, which will be a row of stars that the user can select for rating books. In order to know which star is being selected and at which part, we will use another &lt;code&gt;PanResponder&lt;/code&gt;. We will do this because it makes position tracking much easier and reliable, than with just one responder. You also the see a &lt;code&gt;onLayout&lt;/code&gt; callback, which is used to keep track of the star row's width, as later described. It had to be a React reference and not a state, because it is used in a &lt;code&gt;PanResponder&lt;/code&gt; and thus would not work otherwise.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The &lt;strong&gt;Modal Responder&lt;/strong&gt; allows you to keep track of touches inside the whole modal (except the star row). Before we actually allow a gesture to be tracked, we check if the touch is inside the window area (25% height). Otherwise, the touch would hit the backdrop area. Also, when the swiping down of the modal ends, we either close it completely or keep it open, defined by being less than 50% closed already. Move events will change the modal position, as described later.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;For the &lt;strong&gt;Star Responder&lt;/strong&gt; we will add the same behavior for when the gesture ends, as with the modal responder. But for the touch and move events, the star rating (here offset) is being calculated and set. If the user swipes down over a star, the change in &lt;code&gt;y&lt;/code&gt; is being checked, and if its greater than a threshold, the modal position will change instead.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Spring Animation
&lt;/h3&gt;

&lt;p&gt;In order to achieve a natural, slight bounce animation of the modal window, we will use a spring animation. When the modal window opens, it moves from the bottom of the screen up by its height. This is why we, to calculate that position, subtract the screen height (which is the full modal height) minus the targeted modal window height (25% of that size). Closing the window means moving it to the bottom, out of the screen, meaning the screen's height.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Tracking the Modal Position
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;PanResponder&lt;/code&gt; fires events for touches that the user does on the modal. To track that position, we take the accumulated distance of the gesture since the touch started, as saved in &lt;code&gt;dy&lt;/code&gt;. This is then saved as an animated value in a React reference and used for &lt;code&gt;translateY&lt;/code&gt; and &lt;code&gt;opacity&lt;/code&gt;, as mentioned before.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  The Star
&lt;/h2&gt;

&lt;p&gt;As the user touches the stars, we also want them to be able to select half stars. This requires a gesture tracking and evaluation, otherwise we could just a &lt;code&gt;TouchableOpacity&lt;/code&gt; or similar to track clicks on a star. The row of stars will specifically track touches in this area. Somehow, we need to check the x position of where the user touches the star row.&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;pageX&lt;/code&gt; value, we can track the x position of where the user touches, in relation to the screen. There is an alternative, called &lt;code&gt;locationX&lt;/code&gt;, but that caused problems on Android. To know which star is being touched, we need to know its position on the phone's screen.&lt;/p&gt;

&lt;p&gt;This example is rather simple, so the calculation required knowing the star row width, as well as a single star size (plus its margin distance). If the user touches the first half of a star, its value is being evaluated to 0.5. Otherwise, the star would be selected as full.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In order to easily scale and fill a star, we will use a vector-graphics based solution via the &lt;code&gt;react-native-svg&lt;/code&gt; library. This allows filling the star with a linear gradient, so that we can even fill a star by 27%, if needed. The &lt;code&gt;LinearGradient&lt;/code&gt; will have two &lt;code&gt;Stop&lt;/code&gt; definitions, which then adjust the filling via the &lt;code&gt;offset&lt;/code&gt; prop.&lt;/p&gt;

&lt;p&gt;Each star can then be filled via passing an &lt;code&gt;offset&lt;/code&gt; with a range between &lt;code&gt;[0, 1]&lt;/code&gt;. This then means you know how much to color each star, since its index is known via the root component. Simple subtraction then gives you the &lt;code&gt;offset&lt;/code&gt; value.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Originally published at &lt;a href="https://mariusreimer.com" rel="noopener noreferrer"&gt;https://mariusreimer.com&lt;/a&gt; on January 13, 2021.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Image Scroll Zoom in React Native</title>
      <dc:creator>Marius Reimer</dc:creator>
      <pubDate>Fri, 08 Jan 2021 23:49:35 +0000</pubDate>
      <link>https://dev.to/reime005/image-scroll-zoom-in-react-native-29f7</link>
      <guid>https://dev.to/reime005/image-scroll-zoom-in-react-native-29f7</guid>
      <description>&lt;p&gt;When creating a scroll view for a mobile app, a common principle could be to have an image on the very top of the list. This could be to showcase the content of the page. Examples for this could be found in the Spotify app, where an album cover is shown first, followed by a list of its songs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Frn-image-scroll-zoom.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Frn-image-scroll-zoom.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scrolling up a list of items with an image on top, it can be a nice feature to zoom in the picture naturally. I describe how this can be easily done in React Native. In one of my current React Native apps, which is [open source] with full End-To-End and CI/CD setup, I have implemented this feature. The source code / component can be found &lt;a href="https://github.com/reime005/SpaceSeek/blob/master/src/components/LaunchContent/LaunchContent.tsx" rel="noopener noreferrer"&gt;on Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/5q5ORAdSlBk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The basis of all here is the React Native &lt;code&gt;ScrollView&lt;/code&gt;. This allows us to have content in a scrollable container. When hitting the end of the scroll container in one direction, you may see a bounce of the content. This can be manipulated by changing the boolean &lt;code&gt;bounces&lt;/code&gt; prop. Since this is enabled by default, we should be good here.&lt;/p&gt;

&lt;p&gt;Next, we need to track the &lt;code&gt;y&lt;/code&gt; position of the content offset, so that we can change the image style later. For this, we use the &lt;code&gt;ScrollView&lt;/code&gt; callback &lt;code&gt;onScroll&lt;/code&gt; and map the offset to the &lt;code&gt;Animated.ValueXY()&lt;/code&gt; reference and using the &lt;code&gt;Animated.event&lt;/code&gt; for simplification, as you can see in the code.&lt;/p&gt;

&lt;p&gt;In order to improve scroll event accuracy (allowing it to fire more frequently), we can set &lt;code&gt;scrollEventThrottle&lt;/code&gt; to 1. However, this could cause performance problems, since more data is sent (over the bridge - serialized and sent to the JavaScript environment).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The image is the first item in the scroll view. In order to change its size dynamically, the view must be animated. You could either do this by using &lt;code&gt;Animated.createAnimatedComponent&lt;/code&gt; for your own component, wrap a view inside an &lt;code&gt;Animated.View&lt;/code&gt; or just use &lt;code&gt;Animated.Image&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;My approach to perform the image zooming is by changing &lt;code&gt;scale&lt;/code&gt; and &lt;code&gt;translateY&lt;/code&gt; from the style's &lt;code&gt;transform&lt;/code&gt; prop. The idea is, that the scale increases to a certain value (20 in this example) in relation to a negative change of the &lt;code&gt;contentOffset.y&lt;/code&gt; value. This means that the more negative (scrolling up, or over the top edge) the value gets, the more we increase the image's scale.&lt;/p&gt;

&lt;p&gt;Now, you may notice an empty space on top of the image, the further you scrolled up. You might not want this, so what you could do is change the &lt;code&gt;translateY&lt;/code&gt; value, also in relation to the changing &lt;code&gt;contentOffset.y&lt;/code&gt; value. This should keep the image on top of the scroll view's container. You may need to play with the values a bit, since they can be different in your app.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Lastly, the content below the image may be a bit off when scrolling or zooming. If you don't want this, you could wrap these views in an &lt;code&gt;Animated.View&lt;/code&gt; and also apply a change in &lt;code&gt;translateY&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Originally published at &lt;a href="https://mariusreimer.com" rel="noopener noreferrer"&gt;https://mariusreimer.com&lt;/a&gt; on January 8, 2021.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Horizontal Card Carousel in React Native</title>
      <dc:creator>Marius Reimer</dc:creator>
      <pubDate>Thu, 07 Jan 2021 12:51:29 +0000</pubDate>
      <link>https://dev.to/reime005/horizontal-card-carousel-in-react-native-303n</link>
      <guid>https://dev.to/reime005/horizontal-card-carousel-in-react-native-303n</guid>
      <description>&lt;p&gt;A card carousel allows you to display data in a horizontal swipe view, in the form of cards. Each card has a specific snap position that the user may scroll to, instead of having a free scrolling. This should give a better experience in case the user has to choose between different categories for example. I will show how you can achieve create such a carousel view, with core React Native components.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/csUb9nnhelU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;To keep the example simple, we will fill the carousel view with cards (simple Views), that each represent a different color and a random word (lorem ipsum). Each card that is currently selected or active (in the middle of the carousel view), will have a slightly higher size than its neighbors. Also, the neighbor left and right from the active one will already be party visible. The size of the cards will change, depending on how far it is scrolled.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Frn-card-carousel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmariusreimer.com%2Fimages%2Frn-card-carousel.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generating the words to fill the cards can simply be done by taking a "lorem ipsum" sentence and then &lt;code&gt;split&lt;/code&gt; it into words. The whole carousel view is based on the React Native &lt;code&gt;FlatList&lt;/code&gt;, but could also just be replaced by a &lt;code&gt;ScrollView&lt;/code&gt;. Important are the &lt;code&gt;props&lt;/code&gt;, that have to be set specifically, to enable things like horizontal scrolling and snapping.&lt;/p&gt;

&lt;p&gt;Most props like &lt;code&gt;horizontal&lt;/code&gt; or &lt;code&gt;data&lt;/code&gt; or the ones to disable the scroll indicators should be pretty easy to get. The interesting part is are the snapping props. Snapping in the scroll view should be centered, using &lt;code&gt;snapToAlignment&lt;/code&gt;, which means that the cards are aligned to the center of the scroll view.&lt;/p&gt;

&lt;p&gt;Setting the &lt;code&gt;scrollEventThrottle&lt;/code&gt; to 1 increases the scroll position accuracy, but might cause performance problems, since more data is sent (over the bridge - serialized and sent to the JavaScript environment). We may also need to adjust the default settings for the content insets, which is the amount of the scroll view inner distance to its elements. Reason for that is the missing cards left and right of the very first and last ones.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When it comes to defining the width of the cards, we could either make them hard coded (like 500px), or specify it depending on the scroll view size. This can be achieved by using the &lt;code&gt;onLayout&lt;/code&gt; callback of the &lt;code&gt;FlatList&lt;/code&gt; and tracking the width in a state. The card size will then by 80% of the scroll view width.&lt;/p&gt;

&lt;p&gt;The width of one card will also be the size of the important prop &lt;code&gt;snapToInterval&lt;/code&gt;, because with that we define the stopping points the carousel effect (could also be called pagination). Another way would be to use &lt;code&gt;snapToOffsets&lt;/code&gt;, but this requires an array of "break points", which would be interesting for content with different sizes. Also, the &lt;code&gt;contentInset&lt;/code&gt; and &lt;code&gt;contentOffset&lt;/code&gt; are set, which are needed for initial scroll and content adjustment.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;At next, the scroll events will be tracked, to make the card animation possible. This can simple be done by using a reference via &lt;code&gt;React.useRef&lt;/code&gt; and the &lt;code&gt;Animated.event&lt;/code&gt; function for &lt;code&gt;onScroll&lt;/code&gt;. That is just a code simplification, means you could also use &lt;code&gt;setValue&lt;/code&gt; on the reference and use the function callback.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The most interesting part is the &lt;code&gt;renderItem&lt;/code&gt; function, that renders a card for the &lt;code&gt;FlatList&lt;/code&gt;. The container view needs to be animated (from React Native). What happens then is change the scale of the elements, depending on how far the user scrolled the scroll view content. This is where interpolation can be helpful. It maps an input range (content offset) to an output range (scale). Each card only cares about itself, as well as if the right or left neighbor is changing. This is why the &lt;code&gt;boxWidth&lt;/code&gt; is multiplied by the according indices, for calculating their positions in the scroll view (content) container. Lastly, you see the change of the &lt;code&gt;backgroundColor&lt;/code&gt; by calculating the rgb values arbitrarily according to the item's &lt;code&gt;index&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Originally published at &lt;a href="https://mariusreimer.com" rel="noopener noreferrer"&gt;https://mariusreimer.com&lt;/a&gt; on January 7, 2021.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Books that I read in 2020</title>
      <dc:creator>Marius Reimer</dc:creator>
      <pubDate>Sat, 02 Jan 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/reime005/books-that-i-read-in-2020-58j1</link>
      <guid>https://dev.to/reime005/books-that-i-read-in-2020-58j1</guid>
      <description>&lt;p&gt;I'm listing and reviewing the books I've read in 2020 with the most important learnings for me personally.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Snowball (Warren Buffet)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--202FEOl3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-buffet.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--202FEOl3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-buffet.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interesting biography of the legendary investor Warren Buffet. What I found pretty interesting is that he (as many other business-successful people) has started really early (in his childhood), selling things. What you could conclude from that is that you should start early with making/keeping/growing money.&lt;/p&gt;

&lt;p&gt;He also mentioned that he patience on finding the right time to invest, while keeping the focus on the value behind the company. That means, a company could have a higher, intrinsic value than what is perceived by the public (value investment).&lt;/p&gt;

&lt;h2&gt;
  
  
  Thinking, Fast and Slow (Daniel Kahnemann)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K74ju54g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-thinking-fast-slow.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K74ju54g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-thinking-fast-slow.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea is that humans basically have two different systems, that reflect their mind. System 1 operates automatically, quickly, with no effort and no sense of voluntary control and conclude tasks everyday life requires (like navigating and walking). System 2 requires more effort and attention and conclude tasks that require concentration (like solving complex math problems).&lt;/p&gt;

&lt;p&gt;One thing that was really important to keep for me was the confirmation bias and fact of jumping to conclusions. Often, system 1 draws conclusions based on readily available, often misleading and wrong information, to take the decision off of system 2. If we have a believe about something to be true, we should not look for data that supports that, but rather data that contradicts it.&lt;/p&gt;

&lt;p&gt;Also interesting was the fact that people tend to overweight recent experiences, means that if you have both positive and negative experiences, you would rather conclude the whole experience to be negative if the most recent event was negative. For example, if the last days of your vacation were bad, you would more likely conclude that the vacation was rather negative, even though you had plenty of positive experiences before.&lt;/p&gt;

&lt;h2&gt;
  
  
  Psycho-Cybernetics (Maxwell Maltz)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hj3OZLgd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-psycho-cyber.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hj3OZLgd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-psycho-cyber.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is considered to be one of the best books in the psychology and self-help category. The author, Maxwell Maltz, professionally a cosmetic surgeon, observed the fact that people had believes about their portrait (like their nose) and after correcting them (via cosmetic surgery) they looked different physically, but they still saw themselves with the "disability". Maxwell brought the fact that people let past experiences define them in a negative way, making them not see who they really are, but who they think they are (self image).&lt;/p&gt;

&lt;p&gt;Very important to remember was also that our brain does not distinguish between imagination and reality, so our thoughts influence "trick" us to believe that something is real, even though it is just imagined. You could see this in a positive or negative way, for example by having a clear vision/picture of who we want to be and regularly think/vision that picture.&lt;/p&gt;

&lt;p&gt;The author also described the "success mechanism", that works in a way that our conscious mind is less helpful in solving problems, but our creative, unconscious mind much more. You may find a solution to a problem by not thinking about it actively, but by doing rather unrelated tasks. The success mechanism works by intensively thinking about the problem in as much detail as you can, then forget about the problem for some time (even days). The solution then often presents itself, by letting the mind work on it unconsciously.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Power of Positive Thinking (Norman Vincent Peale)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P1er9iNZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-power-positive-thinking.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P1er9iNZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-power-positive-thinking.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This book is pretty focus on religion and god. It is said that god will help you, heal you, solve problems for you if you believe in it, remove negative feeling, thoughts and have faith. The interesting part for me here was the banish of self-doubt, that often originate from values and experiences of our childhood. Positive thinking will help you achieve your goals. You should practice inner happiness, not worry about eventual negative outcomes and keep a regular routine "praying" of picturing/visioning and imagining of a thing or goal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Crowd: A Study of the Popular Mind (Gustave LeBon)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gs0rBdTB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-psy-crowd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gs0rBdTB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-psy-crowd.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It gives interesting insights on the psychology of the crowd. The majority of men, especially those in large groups/masses, do not have clear or reasoned ideas on a subject outside their own specialty. People join mass movements to get rid of their responsibility of life and different burdens that they have, leading to a feeling of connectedness and strength.&lt;/p&gt;

&lt;h2&gt;
  
  
  Influence - The Psychology of Persuasion (Robert B. Cialdini)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VaTHJQfd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-influence.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VaTHJQfd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-influence.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In 6 principles, it is explained why people say "yes". This is interesting to know, since everyone is either influencing someones else and/or is influenced by someone. The first, reciprocation, is giving back what another person gave us (someone gives you a present - you want to give them one too). The second, commitment and consistency, is that we usually stay fixed on an opinion that we have taken stand on (like to say that we have a specific political standpoint). The third, social proof, is that we do what the people around us is doing, because we assume it to be true (like laughing to a joke in a group, even though you did not understand it). The fourth, liking, relates to agreeing to people that we feel physically attracted, similar to or received compliments from (for example finding out that your neighbor does the same sport as you). The fifth, authority, is simply the fact that we are taught to follow orders from people with higher authority, like police men. The sixth, scarcity, tells that the fear of loss is greater than the desire to gain, so that the more available something is, the less we desire it (for example limited time offers in stores).&lt;/p&gt;

&lt;h2&gt;
  
  
  How You Decide: The Science of Human Decision Making (Ryan Hamilton)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wiFjAfjX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-how-decide.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wiFjAfjX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-how-decide.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is commonly estimated that humans make around 35000 decisions a day. Most of them (approximately 95%) may happen unconsciously. Different parts of the human's brain make different decisions and react and are triggered differently. The emotional part of the brain (limbic system) handles lots of information in an unconscious way, learns by try-and-error and is heavily steered by the hormone dopamine (something has a high reward will likely be repeated in the future, even though it is short time). The logical part of the brain (neo-cortex system) can see things from a different/rational perspective, by controlling emotions and do rational decisions (like in emergencies). However, the logical part cannot deal with as much information as the emotional part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blackout (Marc Elsberg)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--haNTLs6p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-blackout.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--haNTLs6p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-blackout.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a book that does not fit into my usual selection, but it tells a great story that I can highly recommended. In summary, the energy (power) connections in Europe start to fail. This follows a chain of reactions all over the cities, that cause panic. That was really interesting to see, because it shines light on things that you might only think about when you heard about it. For example: no energy means no water flush, means no water or toilet usage. Sooner or later, this may increase the infection risk, because dirt accumulates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Range - Why Generalists Triumph in a Specialized World (David Epstein)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4ZPj4ytc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-range.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4ZPj4ytc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-range.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This book is almost an anti these to the famous "10000 hours" rule to achieve mastery in a field (as outlined in the book "Mastery" by Robert Greene). The author outlines that generalists, rather than specialists, will be needed more and more in the future. The reason for that is the rapidly changing environments that most field bring with them, requiring a broad set of skills and creativity to solve problems.&lt;/p&gt;

&lt;p&gt;Specialization could make you blind to all possibilities of solving a problem. The idea is that you try different things, fail fast, learn and apply. Applying conceptual knowledge from one domain to another or a new one is key here.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hard Thing About Hard Things - Building a Business When There Are No Easy Answers (Ben Horowitz)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DrvA_HFH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-hard-things.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DrvA_HFH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-hard-things.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main saying of this book is that there is no recipe for situations when things get hard. Throughout the book, there were a number of advices and stories that were told that may help with hard things. There was also the fact of having artificial deadlines to increase productivity, or having less people that are the single point of decision, just to prevent being a task being stuck at one person.&lt;/p&gt;

&lt;h2&gt;
  
  
  12 Rules for Life - An Antidote to Chaos (Jordan B. Peterson)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zOie2zmc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-12-rules.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zOie2zmc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-12-rules.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The author described 12 rules that can help you with you and your life. I'm not going to write them down here, since that is too much. The most important things for me were that you should hang out with people who are where you want to be, support you and are positive. Also, you should reward yourself for doing unpleasant things that you don't want to do. Also, the "stand up straight with your shoulders back" rule can be helpful to remember, to act more dominant which will make you less anxious, more confident and more likely to attract positivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Wisdom of Insecurity - A Message for an Age of Anxiety (Alan Watts)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k1_hrmKP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-wisdom-insecurity.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k1_hrmKP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-wisdom-insecurity.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This book is pretty strong about spirituality and self-help. The author describes that in the modern age, people tend to crave for a feeling of insecurity (even though this does not exist) and so fear things that are not real, causing anxiety. This can be solved by living in the present moment, rather then holding on present experiences or future projects. He brought the example of a person that must undergo a surgery in some weeks and has no pain, but instead of living in the present, he is occupied with thoughts of possibly dying or cancelling the surgery. Other things that the author mentioned were perception of time, self and reality for being the root of all insecurity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inner Engineering (Sadhguru)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TJ7mfe_h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-inner.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TJ7mfe_h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-inner.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inner Engineering goes into the topic of spirituality. Sadhguru, the author, talks deeply about his experience with meditation and yoga. Happiness comes from the inside, not from another person or the outer world. It is told that, when we change something or reached a certain goal, we become happy. But the author describes that this is what prevents us from being happy, since everything happens right now, in this moment and within us. So the search for happiness should happen in ourselves. Also, responding to life events (responseability) is meant in a way to increase freedom by being able to respond to events consciously.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Anatomy of Loneliness - How to Find Your Way Back to Connection (Teal Swan)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zGhBkoZ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-lone.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zGhBkoZ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-lone.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The author describes that every human experiences loneliness to a degree, while separating between one that can be solved by being around other people, and one that cannot. The latter is the genuine loneliness, which can lead to a sense of isolation and separateness to others. It is stated that survival as a human race depends on the capacity to be connected. Loneliness is an epidemic with devastating implications. Three main concepts are key here: Separation, Shame and Fear.&lt;/p&gt;

&lt;p&gt;Shame is an instinct (or unconscious) reaction, like the fight-or-flight response that causes us to react, or nowadays overreact to stimuli (like notifications on phones) fully automatically as an evolutionary result. We may withdraw from other people by avoiding them or acting in a not authentic way, making it impossible for them to understand yourself.&lt;/p&gt;

&lt;p&gt;Fear is pushing something away from us and separating from it. It may be the result of rejection, disapproval or abandonment. Interesting to know is that we do not fear the unknown, but rather a similar, traumatic situation from the past. Fear is a part of you and can be resolved by resolving past experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Culture Map - Breaking Through the Invisible Boundaries of Global Business (Erin Meyer)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c2G2zCxc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-culture.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c2G2zCxc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mariusreimer.com/images/book-culture.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is interesting especially for everyone who works in a company with people from different international origins. It shines a light on how different cultures react to situations, like meetings, conversations or reviews. For example, some cultures are more open to direct feedback, or maybe want to say "no" when they rather say "this can be difficult to fit in my schedule".&lt;/p&gt;

</description>
      <category>books</category>
      <category>learning</category>
    </item>
    <item>
      <title>Simple Settings List in React Native</title>
      <dc:creator>Marius Reimer</dc:creator>
      <pubDate>Tue, 15 Dec 2020 17:03:10 +0000</pubDate>
      <link>https://dev.to/reime005/simple-settings-list-in-react-native-5co9</link>
      <guid>https://dev.to/reime005/simple-settings-list-in-react-native-5co9</guid>
      <description>&lt;p&gt;There are many libraries that provide a way to create a settings screen or list for your React Native app. I show a simple way to achieve this with basic or no dependencies.&lt;/p&gt;

&lt;p&gt;You can find the source code &lt;a href="https://github.com/reime005/SpaceSeek/blob/master/src/components/Settings/SettingsList.tsx" rel="noopener noreferrer"&gt;here&lt;/a&gt;. In essence, we use the React Native &lt;code&gt;SectionList&lt;/code&gt; for a structured or sectioned partition of the list. Alternatively, you could use a &lt;code&gt;FlatList&lt;/code&gt; or even &lt;code&gt;ScrollView&lt;/code&gt; if you have a small amount of items to put in your list. For imaging, you would use &lt;code&gt;react-native-svg&lt;/code&gt; or alternatively the React Native &lt;code&gt;Image&lt;/code&gt;. Persistence, if needed for things like a dark mode switch, could be achieved by &lt;code&gt;react-native-async-storage&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SectionList
&lt;/h2&gt;

&lt;p&gt;The most interesting feature about the &lt;a href="https://reactnative.dev/docs/sectionlist" rel="noopener noreferrer"&gt;SectionList&lt;/a&gt; is its sectioned data handling. You can pass the data via &lt;code&gt;sections&lt;/code&gt;, its function to render items via &lt;code&gt;renderItem&lt;/code&gt; and its function to render the section header via &lt;code&gt;renderSectionHeader&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fapk7uhkuakaocfop5tjq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fapk7uhkuakaocfop5tjq.png" alt="0*lyUnxHSsm0htic-k"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Structured data is required for the Section List. Each section has a header and a bunch of items. You can define this structure for yourself. This means, you could also add elements like a header icon, as you can see in the orange box.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When you put this data in the &lt;code&gt;SectionList&lt;/code&gt;, when using TypeScript, types for the rendering function should be automatically inferred. This makes writing these functions much easier. It also prevents possible errors by enforcing types on &lt;code&gt;sections&lt;/code&gt;, for example to require an array type.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  The Section Item and Header
&lt;/h2&gt;

&lt;p&gt;When looking closely, you may have also noticed that the Section Item has rounded borders, if they are first or last in the list. This can be achieved by comparing the current render index against the &lt;code&gt;sections&lt;/code&gt; data that you put into the &lt;code&gt;SectionList&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The Section Header is also a rather simple component. It needs to render the title and icon that you specified.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Originally published at &lt;a href="https://mariusreimer.com/blog/id/simple-settings-list-in-react-native" rel="noopener noreferrer"&gt;https://mariusreimer.com&lt;/a&gt; on December 15, 2020.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>TikTok Animation in React Native</title>
      <dc:creator>Marius Reimer</dc:creator>
      <pubDate>Fri, 11 Dec 2020 17:22:02 +0000</pubDate>
      <link>https://dev.to/reime005/tiktok-animation-in-react-native-33bl</link>
      <guid>https://dev.to/reime005/tiktok-animation-in-react-native-33bl</guid>
      <description>&lt;p&gt;The TikTok app has a pretty interesting loading animation. It has two horizontally aligned circles that seem to rotate its positions, seemingly in a circle. I wanted to create a similar behavior in React Native. The source code can be found &lt;a href="https://github.com/reime005/ReactNativeTikTokComments/blob/master/src/components/Spinner/Spinner.tsx" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/HiFhYtRElD0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Initially, the spinner consists of two colored circles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg56nlsrvntiys7qb86lp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg56nlsrvntiys7qb86lp.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As soon as the red circle moves “below” the blue one, its overlapping shape turns into the background color. A similar “black” effect could be achieved by using the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode" rel="noopener noreferrer"&gt;mix-blend-mode&lt;/a&gt; CSS property, if you are on the web. However, this does not exist in React Native.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy5b5sa36q529zcg02vv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy5b5sa36q529zcg02vv2.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The red circle moves all the way through the blue circle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8dyz5w3lrru6bj17el66.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8dyz5w3lrru6bj17el66.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At half time, the red circle is left to the red circle. This triggers the back animation, so that the red circle moves back to its initial position.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe1mkj69ekm7gio3cup69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe1mkj69ekm7gio3cup69.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;First, we need to declare the shared variables. For managing the animated values, we use the &lt;code&gt;useSharedValue&lt;/code&gt; hook. This has a behavior similar to &lt;code&gt;React.useRef&lt;/code&gt;, means that is does not trigger re-render of the component. The react-native-reanimated library uses the JavaScript Interface (JSI), which means good performance due to synchronous JavaScript &amp;lt;-&amp;gt; Native calls.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The following code shows how to change a shared animated value. After the component has been mounted, we start the animation timer. Using a combination of &lt;code&gt;withRepeat&lt;/code&gt;, &lt;code&gt;withSequence&lt;/code&gt; and &lt;code&gt;withTiming&lt;/code&gt;, the timer counts from 1 to -1 and back, in a loop.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Depending on the current time value, we need to change the &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;radius&lt;/code&gt; values. The library changes values automatically, means that you do not need to trigger most things, following the declarative concept. However, you need to put those changes (to change animated style or props) in specific hooks. In this example, we only need to change the component's props, so we will use &lt;code&gt;useAnimatedProps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To actually change &lt;code&gt;radius&lt;/code&gt; and &lt;code&gt;x&lt;/code&gt;, we will use interpolation. We will simply "map" the input range from -1 to 1 to a specific output range. For x, we switch both circle's positions. For the &lt;code&gt;radius&lt;/code&gt;, we change according to the initial value. Similar things apply to the second circle.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Animate React Native SVG
&lt;/h2&gt;

&lt;p&gt;In order to change component props via animated shared values, you need to pass the &lt;code&gt;useAnimatedProps&lt;/code&gt; output to the component. This will only work, when the component is actually animated via &lt;code&gt;Animated.createAnimatedComponent&lt;/code&gt; and you change native props of native views.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The circles are now animated, but still need to have the clipping effect. In order to achieve this, we need to define a &lt;code&gt;ClipPath&lt;/code&gt; mask, that includes both animated circles.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Finally, we will render three circles. First is for the render red circle. The last two are for the green one and its background, which have the same position and size. The green circle applies the clip path. As you might notice, one output of &lt;code&gt;useAnimatedProps&lt;/code&gt; could only be applied to one component, so the props had to be duplicated. This feels like a hack, but makes sense if you view it from a native perspective.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://mariusreimer.com" rel="noopener noreferrer"&gt;https://mariusreimer.com&lt;/a&gt; on December 10, 2020.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Faster React Page Loads With Lazy and Suspense</title>
      <dc:creator>Marius Reimer</dc:creator>
      <pubDate>Tue, 28 Jul 2020 20:00:27 +0000</pubDate>
      <link>https://dev.to/reime005/faster-react-page-loads-with-lazy-and-suspense-2o9e</link>
      <guid>https://dev.to/reime005/faster-react-page-loads-with-lazy-and-suspense-2o9e</guid>
      <description>&lt;p&gt;Third-party libraries, images and huge amount of static data can all influence your application bundle size. This can cause unexpected high loading times, which may lead to a bad first site impression. &lt;strong&gt;React.Lazy&lt;/strong&gt; and &lt;strong&gt;React.Suspense&lt;/strong&gt; are common techniques (as of mid 2020), to perform code splitting for bundle size reduction and speeding up page load. In this article I want to show quick you may add code splitting to your React application, highlighting the differences in performance (Lighthouse benchmark/check).&lt;/p&gt;

&lt;h2&gt;
  
  
  The base application
&lt;/h2&gt;

&lt;p&gt;The idea is that we have a React component, that just displays some static data from a JSON file. I have chosen the &lt;a href="https://github.com/skolakoda/programming-quotes-api" rel="noopener noreferrer"&gt;programming-quotes-api&lt;/a&gt; in order to have some data that makes sense. This data is not being fetched at runtime, but put into a local JSON file, which means it will be bundled into the application. To make the data a bit bigger, I have duplicated its content.&lt;/p&gt;

&lt;p&gt;The app boilerplate was created by the common &lt;code&gt;create-react-app&lt;/code&gt; tool as described &lt;a href="https://reactjs.org/docs/create-a-new-react-app.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;. From there on, I have created a React component, call it &lt;code&gt;VeryBigJokesList&lt;/code&gt;, that displays the static content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;preDefinedJokes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./preDefinedJokes.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;VeryBigJokesList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;jokes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;preDefinedJokes&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jokes&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;No jokes found.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;jokes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;joke&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;joke&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;joke&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;en&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
      &lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;VeryBigJokesList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The non-lazy (eager) case
&lt;/h2&gt;

&lt;p&gt;Usually, I would just import the &lt;code&gt;VeryBigJokesList&lt;/code&gt; component and render it in the &lt;code&gt;App&lt;/code&gt; component, created by the boilerplate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;VeryBigJokesList&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./VeryBigJokesList&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App-header"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;VeryBigJokesList&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This causes to the user load all content from &lt;code&gt;VeryBigJokesList&lt;/code&gt; when loading &lt;code&gt;App&lt;/code&gt;, since it will be “placed” in the same final bundle. When building the application via &lt;code&gt;yarn build&lt;/code&gt; or &lt;code&gt;npm run build&lt;/code&gt;, you will see a list of all bundled files of your application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F0%2APcTyTxw0IenkgCXN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F0%2APcTyTxw0IenkgCXN.png" alt="bundle1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the main bundle is yellow highlighted, indicating that its size may be too big. This makes sense, since the JSON data that &lt;code&gt;VeryBigJokesList&lt;/code&gt; includes is roughly this size. When running a Lighthouse performance check, you should also see some loading specific issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F0%2APaG4GHNO-o4nJ4kj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F0%2APaG4GHNO-o4nJ4kj.png" alt="bench1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The lazy case
&lt;/h2&gt;

&lt;p&gt;When planning to use &lt;a href="https://reactjs.org/docs/code-splitting.html#reactlazy" rel="noopener noreferrer"&gt;React.Lazy&lt;/a&gt;, you mostly need to consider the fact that &lt;code&gt;VeryBigJokesList&lt;/code&gt; is being exported via &lt;code&gt;export default&lt;/code&gt; and is put as a child (of any depth) of a React.Suspense component. Suspense allows you to render a fallback component (like a loading indicator), while its content is loading.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;VeryBigJokesList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./VeryBigJokesList&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App-header"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading list...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;VeryBigJokesList&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adjusting &lt;code&gt;VeryBigJokesList&lt;/code&gt; to load lazily was rather simple. If everything worked well, you should see a loading text, before the list is displayed. When building the application, you should also see a difference.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F0%2AsNPj4Gz4PjlIi29f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F0%2AsNPj4Gz4PjlIi29f.png" alt="bundle2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main bundle size has decreased dramatically, since the static JSON content has moved to a different chunk of the bundle. When running a Lighthouse performance check, you should see a difference in loading times.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F0%2AhX8U0S46urm1yCJx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F0%2AhX8U0S46urm1yCJx.png" alt="bench2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://mariusreimer.com/blog/id/faster-react-page-loads-with-lazy-and-suspense" rel="noopener noreferrer"&gt;https://mariusreimer.com&lt;/a&gt; on July 26, 2020.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webpack</category>
      <category>performance</category>
    </item>
    <item>
      <title>Custom Text Highlighting with CSS</title>
      <dc:creator>Marius Reimer</dc:creator>
      <pubDate>Sun, 26 Apr 2020 16:45:17 +0000</pubDate>
      <link>https://dev.to/reime005/custom-text-highlighting-with-css-50b9</link>
      <guid>https://dev.to/reime005/custom-text-highlighting-with-css-50b9</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F0%2AvqUEZlvRDPNaME2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F0%2AvqUEZlvRDPNaME2i.png" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some websites do different things to highlight specific text phrases. This could be text that the user should pay attention at (like a warning), or is just very important (like an item price). I was curious on how to do that.&lt;/p&gt;

&lt;p&gt;The solution is very simple: via CSS, background image and inline span. First, you need to create the image that you want to put as a highlight behind your text. I just used Gimp and a brush tool until I was okay with the result. The image has to be exported as a scalable vector graphic (&lt;strong&gt;svg&lt;/strong&gt;).&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://fonts.googleapis.com/css2?family=Baloo+Bhaina+2:wght@600&amp;amp;display=swap"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Baloo Bhaina 2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;cursive&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fffdf8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nc"&gt;.highlighted-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMjAwMTA5MDQvL0VOIgogICAgICAgICAgICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy1TVkctMjAwMTA5MDQvRFREL3N2ZzEwLmR0ZCI+Cgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgICB3aWR0aD0iMWluIiBoZWlnaHQ9IjAuNWluIgogICAgIHZpZXdCb3g9IjAgMCAzMDAgMTUwIj4KICA8cGF0aAogICAgICAgIGZpbGw9IiNmZmUwMDAiIHN0cm9rZT0ibm9uZSIKICAgICAgICBkPSJNIDEyLjAwLDQ4LjAwCiAgICAgICAgICAgQyAxMi4wMCw1MC4wOSAxMS43OSw1NC45OSAxMi42MCw1Ni43MgogICAgICAgICAgICAgMTUuNTksNjMuMTggMjYuMDksNTYuNjQgMzMuMDAsNjMuMDAKICAgICAgICAgICAgIDMwLjg0LDYzLjE4IDIzLjA1LDYzLjg3IDIxLjgwLDY1LjAyCiAgICAgICAgICAgICAxOC4wMiw2Ny44OCAyMS4yOSw3Ni4zNSAyMS44MCw4MC4wMAogICAgICAgICAgICAgMjEuODAsODAuMDAgMjEuODAsODYuMDAgMjEuODAsODYuMDAKICAgICAgICAgICAgIDIxLjgwLDg2LjAwIDQwLjAwLDg3LjAwIDQwLjAwLDg3LjAwCiAgICAgICAgICAgICAzOS45Myw4OC44OCA0MC4wNiw5MS4wNCAzOC45OCw5Mi42OQogICAgICAgICAgICAgMzcuNTEsOTQuOTMgMzUuMTUsOTQuNzUgMzIuNTksOTYuMjAKICAgICAgICAgICAgIDI4LjMzLDk4LjYxIDI2Ljg3LDEwMi4yMiAyNy4zNCwxMDcuMDAKICAgICAgICAgICAgIDI3LjM0LDEwNy4wMCAzMC4wMiwxMjMuNDEgMzAuMDIsMTIzLjQxCiAgICAgICAgICAgICAzMS44MiwxMjUuNzUgNDAuMDEsMTI3Ljk1IDQzLjAwLDEyOC4wMAogICAgICAgICAgICAgNDMuMDAsMTI4LjAwIDg3LjAwLDEyOC4wMCA4Ny4wMCwxMjguMDAKICAgICAgICAgICAgIDg4LjA4LDEyMS41NiA5MS4xNiwxMjEuODAgOTcuMDAsMTIyLjA0CiAgICAgICAgICAgICA5Ny4wMCwxMjIuMDQgMTA5LjAwLDEyMy4wMCAxMDkuMDAsMTIzLjAwCiAgICAgICAgICAgICAxMDkuMDAsMTIzLjAwIDEyOC4wMCwxMjMuMDAgMTI4LjAwLDEyMy4wMAogICAgICAgICAgICAgMTI4LjAwLDEyMy4wMCAxODIuMDAsMTIyLjAwIDE4Mi4wMCwxMjIuMDAKICAgICAgICAgICAgIDE5NC41OCwxMjEuOTcgMTg4LjQyLDExOS4wMyAyMDEuMDAsMTE5LjAwCiAgICAgICAgICAgICAyMDEuMDAsMTE5LjAwIDI0My4wMCwxMTkuMDAgMjQzLjAwLDExOS4wMAogICAgICAgICAgICAgMjQzLjAwLDExOS4wMCAyNTguMDAsMTE4LjAwIDI1OC4wMCwxMTguMDAKICAgICAgICAgICAgIDI1OS41MywxMDkuMTAgMjY2LjAxLDExMy4zNyAyNzAuNDAsMTA5LjE1CiAgICAgICAgICAgICAyNzIuNjEsMTA3LjAzIDI3Mi4zMCwxMDAuODUgMjcyLjAwLDk4LjAwCiAgICAgICAgICAgICAyNzIuMDAsOTguMDAgMjgwLjAwLDk3LjAwIDI4MC4wMCw5Ny4wMAogICAgICAgICAgICAgMjgwLjAwLDk0LjEwIDI4MC4yNiw4OC41NSAyNzkuMjYsODYuMDIKICAgICAgICAgICAgIDI3Ni40OSw3OC45OCAyNjQuNjMsNzYuODggMjU4LjAwLDc2LjAwCiAgICAgICAgICAgICAyNjUuMTUsNjkuMTkgMjc2LjQwLDczLjAzIDI3NC44NSw2Mi4wNAogICAgICAgICAgICAgMjc0LjQ3LDU5LjM1IDI3My43Myw1OC44NSAyNzIuMDAsNTcuMDAKICAgICAgICAgICAgIDI4MS42OCw1My43NyAyODEuMDAsNTQuMjggMjgxLjAwLDQ0LjAwCiAgICAgICAgICAgICAyODEuMDAsNDQuMDAgMjU4LjAwLDQyLjM4IDI1OC4wMCw0Mi4zOAogICAgICAgICAgICAgMjUwLjAwLDQwLjg0IDI1MS40OCwzOC4wMyAyMzUuMDAsMzguMDAKICAgICAgICAgICAgIDIzNS4wMCwzOC4wMCAxODkuMDAsMzkuMDAgMTg5LjAwLDM5LjAwCiAgICAgICAgICAgICAxODkuMDAsMzkuMDAgMTc3LjAwLDM5LjgyIDE3Ny4wMCwzOS44MgogICAgICAgICAgICAgMTc3LjAwLDM5LjgyIDE1OS4wMCwzOC4wMCAxNTkuMDAsMzguMDAKICAgICAgICAgICAgIDE1OS4wMCwzOC4wMCAxMjguMDAsMzguMDAgMTI4LjAwLDM4LjAwCiAgICAgICAgICAgICAxMTYuOTAsMzguMDIgMTIwLjE2LDM5LjQwIDExMy4wMCw0MC42NwogICAgICAgICAgICAgMTEzLjAwLDQwLjY3IDk3LjAwLDQyLjE3IDk3LjAwLDQyLjE3CiAgICAgICAgICAgICA5Ny4wMCw0Mi4xNyA4Ny4wMCw0My44MyA4Ny4wMCw0My44MwogICAgICAgICAgICAgODcuMDAsNDMuODMgNTcuMDAsNDUuMDAgNTcuMDAsNDUuMDAKICAgICAgICAgICAgIDU3LjAwLDQ1LjAwIDMyLjAwLDQ4LjAwIDMyLjAwLDQ4LjAwCiAgICAgICAgICAgICAzMi4wMCw0OC4wMCAxMi4wMCw0OC4wMCAxMi4wMCw0OC4wMCBaIiAvPgo8L3N2Zz4K')&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;background-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;background-repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;background-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is a &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"highlighted-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;special&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; title&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After the image is created, you could either keep it as a file or convert it to a base64 string to be used within css. Important is, that the &lt;code&gt;background-image&lt;/code&gt; resizes by covering the element, does not repeat and is centred.&lt;/p&gt;

</description>
      <category>css</category>
      <category>html</category>
      <category>design</category>
      <category>style</category>
    </item>
  </channel>
</rss>
