Don’t just copy the @font-face out of Google Fonts URLs

Post pobrano z: Don’t just copy the @font-face out of Google Fonts URLs

I don’t think this is an epidemic or anything, but I’ve seen it done a few times and even advocated for. This is what I mean…

You go to Google Fonts and pick a font like Open Sans, and it gives you either a <link> or an @import with a URL there in which to ready this font for usage on your site.

You can take a peek in there and see what it returns…

It’s just some @font-face declarations, of course!

Now your performance-minded brain kicks off. Wait. So, I make one HTTP request for this stylesheet, and then it makes more HTTP requests for those woff2 files it’s linking up. Screw the middle man here, why not just copy those @font-face blocks right out of here and use them.

You can! But!

The issue is that Google does fancy Google things here and the contents of that original stylesheet changes based on the browser requesting it. That screenshot above is Chrome 66. Here’s Firefox 20 on Windows 7:

It’s different! It’s only got woff, not woff2. If we open that URL in IE 8, we’d get an @font-face block that includes the eot format!

The point is, what that URL gives is very specific to what the current browser needs. That’s a pretty cool thing to abstract away and not worry about. Should new browsers have new formats and new CSS syntax needed, that’ll just come along for the ride.

Not that Google Fonts is perfect with this stuff. For example, by not controlling your own @font-face blocks, you can’t take advantage of font-display, which is a shame. Maybe we’ll get that someday, or maybe it’s worth self-hosting your Google Fonts, which is another whole thing we’ll get into someday.

The post Don’t just copy the @font-face out of Google Fonts URLs appeared first on CSS-Tricks.

The Four Big Ways Jetpack Helps with Image Performance

Post pobrano z: The Four Big Ways Jetpack Helps with Image Performance

We’ve been working with Jetpack around here as a sponsor. It’s a great match because as someone with a bunch of self-hosted WordPress sites, Jetpack is one of those no-brainer plugins for me. Jetpack can do a ton of good things for any site in a variety of very different ways. Here’s one way to think about it: it brings the power of WordPress’ own massive servers to you.

For now, let’s just focus on one angle of what Jetpack can do for you: image performance. Jetpack does a ton for you in this regard, solving some non-trivial performance upgrades. Let’s take a look at what I see as the four big boosts you get from Jetpack on your images.

1) WordPress does responsive images for you

OK, I cheated with the first one because you don’t actually need Jetpack to benefit from this. But it’s an important and foundational concept for fast images. Just by using WordPress, you get basic responsive images for free.

If you already know what I’m talking about, here’s an example of the output you’ll see in the DOM of a published WordPress post with an image in it uploaded via the Media Uploader:

It’s wonderful to get this for free, as writing out responsive images syntax by hand is quite cumbersome.

If you are new to the idea of responsive images, the big idea is this: rather than a single image going to any browser visiting your website, you have multiple images in different sizes and the most-correct one is delivered. Imagine instead of a mobile phone downloading a 1600 pixel wide image (way bigger than it needs), it only downloads a 320-pixel wide image, saving a ton of downloading time.

We’ve written lots about responsive images over the years.

2) You get a CDN

Read a bit about web performance and you’ll be unanimously told: „use a CDN.” A CDN is a Content Delivery Network, essentially web servers designed specifically to make serving assets like images super fast. They call it a network because it isn’t just one server, it’s many servers physically located all over the world so that when your website is requested from different locations all around the world, the files being sent back come from geographically closer locations (faster!). Not to mention it does other clever things like not requiring cookies for each web request like your own server probably does.

Literally, flip a switch in Jetpack and you’ll be using an image CDN:

It’s called Photon.

Site speed is impacted by many factors and one of them is content delivery. Using what is referred to as a content delivery network (or CDN) helps by:

  • Delivering your content from high-speed and dedicated data centers.
  • More files can be downloaded simultaneously by the browser.
  • Distributed data centers (ie in different geographic locations) improve download speeds and provide redundancy.
  • By distributing load and save bandwidth you reduce your existing hosting costs (or keep them in check).

3) You get optimization

Una Kravets calls image optimization an easy performance win for designers. It’s an easy thing to see. Try taking a screenshot of something, exporting something from Photoshop, or grabbing some stock photography. Then drop it onto a tool like ImageOptim and watch the bytes fall away as it optimizes it. Massive savings.

But wouldn’t it be nice if it wasn’t on you to manually optimize all your images before using them? Computers are supposed to help us with menial tasks, right?! When you flip on the CDN feature of Jetpack, your images are now hosted on Photon, and you can see in the Photon docs how it handles things like resizing and quality for you.

4) You get lazy loading

Lazy loading is the idea that you don’t load anything at all unless you need it. In the case of images, don’t download the image unless it’s visible on the page. As in, don’t download an image that is three quarter down an article that a user might never scroll down to, but if they do, then download it.

You know what they say, the fastest web request is one that is never made. Jeremy Wagner, for Google, says:

When we lazy load images and video, we reduce initial page load time, initial page weight, and system resource usage, all of which have positive impacts on performance.

This is another flip-a-switch feature that works on any theme. Turn it on, you got lazy loading.

All Together Now

  1. You get responsive images with WordPress, which by itself can be a major performance win.
  2. With Jetpack, those responsive images are CDN-hosted, providing a speed boost and great caching for the images that are downloaded.
  3. Just because you’re using responsive images and a CDN doesn’t automatically mean those images are optimized, but they are on Photon.
  4. Last, nothing is downloaded at all unless the images are in view (lazy loading), which is the most efficient thing you can do.

Pretty compelling.

The post The Four Big Ways Jetpack Helps with Image Performance appeared first on CSS-Tricks.

Building a RSS Viewer With Vue: Part 2

Post pobrano z: Building a RSS Viewer With Vue: Part 2

Welcome to Part 2 of this mini-series on building a RSS viewer with Vue. In the last post, I walked through how I built my demo using Vue.js and Vuetify on the front end and Webtask on the back end. When I built that initial version, I knew it was exactly thatmdash;an „initial” version. I took some time to work on a few updates, and while I won’t dare call this a „perfect” version, I do think I’ve made some improvements and I’d like to share them with you.

Article Series:

  1. Setup and first iteration
  2. Refinements and final version (This Post)

Before I get started, here are links to the completed demo and source code.

Feel free to fork, file PRs, and report bugs to your heart’s content!

The Plan

When I shared the initial version in Part 1, I outlined some ideas to improve the RSS reader, including:

  • Moving to Vuex.
  • Starting to switch to components in the layout. (Well, I was already using Vuetify components, but I meant custom components for my application.)
  • Using IndexedDB to store feed items for quicker access and offline support.

That was the plan, and like most plans, I wasn’t necessarily able to hit everything in this update (and I’ll explain why at the end). But hopefully you’ll see the improvements as a general „moving in the right direction” for the application. With that out of the way, let’s get started!

Implementing Vuex

I’ll start off discussing the biggest change to the application, the addition of Vuex. As I said in the previous post, Vuex describes itself as a „state management pattern + library” on their „What is Vuex” page. No offense to their documentation, but I had a difficult time wrapping my head around exactly what this meant, from a practical sense.

After having using it in a few small projects now, I’m coming to appreciate what it provides. To me, the core benefit is providing a central interface to your data. If I’ve got a basic Vue app working with an array of values, I may have multiple different methods that modify it. What happens when I begin to have certain rules that must be applied before the data changes? As a simple example, imagine an array of RSS feeds. Before I add a new one, I want to ensure it doesn’t already exist in the list. If I have one method that adds to the feed list, that isn’t a problem, but if I have more, it may become cumbersome to keep that logic in sync across the different methods. I could simply build a utility to do this, but what happens when I have other components in play as well?

While it is absolutely not a one-to-one comparison, I feel like Vuex reminds me of how Providers or Services work in Angular. If I ever want to do work with any data, I’ll ensure I use a central provider to handle all access to that data. That’s how I look at Vuex.

So the big change in this application was to migrate all the data related items to a store. I began by adding the library to my HTML:

<script src="https://unpkg.com/vuex"></script>

Woot! Half-way done! (OK maybe not.)

I then created an instance of my store in my JavaScript file:

const feedStore = new Vuex.Store({
  // lots of stuff here
});

and included it in my Vue app:

let app = new Vue({ 
  el: '#app',
  store:feedStore,
  // lots of stuff here too...
});

Now comes the interesting part. Any time my Vue application needs data, which primarily consists of the list of feeds and the items from those feeds, it’s going to ask the store for them. So, for example, my feeds value is now computed:

feeds() {
  return feedStore.state.feeds;
},

This is now defined in the state portion of my store:

state: {
  allItems: [],
  feeds: [],
  selectedFeed: null
},

Notice that feeds defaults to an empty array. I had previously used the created event of my Vue app to read in the data from localStorage. Now, I ask the store to do that:

created() {
  feedStore.dispatch('restoreFeeds');
},

Back in the store, the logic is pretty much the same:

restoreFeeds(context) {
  let feedsRaw = window.localStorage.getItem('feeds');
  if(feedsRaw) {
    try {
    let feeds = JSON.parse(feedsRaw);
    context.state.feeds = feeds;
    context.state.feeds.forEach(f => {
      context.dispatch('loadFeed', f);
    });
    } catch(e) {
      console.error('Error restoring feed json'+e);
      // bad json or other issue, nuke it
      window.localStorage.removeItem('feeds');
    }
  }
},

I say „pretty much the same” except now I’m doing a bit of error-checking on the value read in from localStorage. But here’s the crucial bit. I already said I failed in terms of switching to IndexedDB, but in theory, I could build a third version of this application with an updated store and my Vue app won’t know the difference. And that’s where I started to get really excited. The more I worked, the more „dumb” my Vue app became and the less tied it was to any particular implementation of storage. Let’s look at the complete Vue app now:

let app = new Vue({ 
  el: '#app',
  store:feedStore,
  data() {
    return {
      drawer:true,
      addFeedDialog:false,
      addURL:'',
      urlError:false,
      urlRules:[],
      selectedFeed:null
    }
  },
  computed: {
    showIntro() {
      return this.feeds.length == 0;
    },
    feeds() {
      return feedStore.state.feeds;
    },
    items() {
      return feedStore.getters.items;
    }
  },
  created() {
    feedStore.dispatch('restoreFeeds');
  },
  methods:{
    addFeed() {
      this.addFeedDialog = true;
    },
    allFeeds() {
            feedStore.dispatch('filterFeed', null);
    },
    addFeedAction() {
      this.urlError = false;
      this.urlRules = [];

      feedStore.dispatch('addFeed', {url:this.addURL})
      .then(res => {
        this.addURL = '';
        this.addFeedDialog = false;
      })
      .catch(e =>{
        console.log('err to add', e);
        this.urlError = true;
        this.urlRules = ["URL already exists."];                                
      });
    },
    deleteFeed(feed) {
      feedStore.dispatch('deleteFeed', feed);
    },
    filterFeed(feed) {
      feedStore.dispatch('filterFeed', feed);
    }
  }
})

What you’ll notice is that pretty much all of the actual logic is now gone and all I’m really doing here is UI stuff. Open a modal here, add an error there, and so forth.

You can view the complete store here, although I apologize for lumping everything together in one file.

Adding a Component

One of the other changes I mentioned was beginning to „component-ize” the view layer. I ended up only making one component, feed-item. This reduced the total number of lines in the HTML a bit:

<v-flex xs12 v-for="item in items" :key="item.link">
  <feed-item :title="item.title" :content="item.content" :link="item.link" :feedtitle="item.feedTitle" :color="item.feedColor" :posted="item.pubDate"></feed-item>
</v-flex>

It isn’t a huge change by any means, but it did make it bit easier for me when I started working on the feed display. As I’m not using a fancy builder yet, I defined my component straight in JavaScript like so:

Vue.component('feed-item', {
  props:[
    'color','title','content','link','feedtitle', 'posted'
  ],
  template: `
  <v-card :color="color">
    <v-card-title primary-title>
      <div class="headline">{Building a RSS Viewer With Vue: Part 2} ({{posted | dtFormat}})</div>
    </v-card-title>
    <v-card-text>
      {{content | maxText }}
    </v-card-text>
    <v-card-actions>
      <v-btn flat target="_new" :href="link">Read on {CSS-Tricks}</v-btn>
    </v-card-actions>
  </v-card>        
  `
});

I’m not doing anything at all fancy in heremdash;there’s no dynamic logic or events or anything like that, but I could certainly add that later where it makes sense. I did finally get around to adding the date and time of posting. If you’re curious about how I built the formatter used for it, read my article Build A i18n Filter Using Vue.js & Native Web Specs.”

The Power of Delete!

Oh, and I finally added a way to delete feeds:

Trash can icon, FTW!

This just fires off a method on the Vue object that, in turn, fires off a call to the store that takes care of removing the feed and items from the UI and then persisting it. A small thing, but, wow, did I wish I had that in the first version when testing. And here is a final shot of everything:

The awesome app in all it’s awesomeness

Next Steps… and What Happened to IndexedDB?

As I said in the beginning, this version is still not perfect but I definitely feel better about it. I highly encourage you to share tips, suggestions, and bug reports in the comments below or on the GitHub repo.

So what happened to IndexedDB support? The issue I ran into was how to properly initialize the database. Vuex stores don’t have a concept of a created process. I could have done something like this:

// dummy code for getting feeds
dispatch('getDB')
.then(() =>
  // do stuff
);

Where the getDB action returns a promise and handles doing a one-time IndexedDB opening and storing the value in the state. I may give this a shot later, and again, what I love about Vuex is that I know I can safely do that without interfering with the rest of the application.


Article Series:

  1. Setup and first iteration
  2. Refinements and final version (This Post)

The post Building a RSS Viewer With Vue: Part 2 appeared first on CSS-Tricks.

How to Create a Lace-Up Text Effect in Adobe Photoshop

Post pobrano z: How to Create a Lace-Up Text Effect in Adobe Photoshop

Final product image
What You’ll Be Creating

This tutorial will show you how to use Photoshop’s layer styles, filters, and adjustments to create a stylish lace-up text effect. Let’s get started!

This text effect was inspired by the many Layer Styles available on GraphicRiver.

Tutorial Assets

The following assets were used during the production of this tutorial:

1. How to Define Patterns

Step 1

Open the 71.jpg image from the Realistic Textile Backgrounds 5 pack. Go to Image > Image Size, change the Width value to 1170, and click OK.

Image Size

Step 2

Go to Edit > Define Pattern, and click OK.

Do that for the rest of the pattern images to add them to the Patterns preset.

Define Pattern

2. How to Create the Background and Text Shape Layers

Step 1

Create a new 1000 x 1000 px document. Click the Create new fill or adjustment layer icon at the bottom of the Layers panel, choose Solid Color, and use the Color #d6dbdb.

Solid Color

Step 2

Create the text using the font The Next Font. Set the Size to 550 pt and the Tracking to 50.

Create the Text

Step 3

Duplicate the text layer and hide it, and right-click the copy to choose Convert to Shape.

Rename the shape layer to Text Shape.

Convert to Shape

Step 4

Duplicate the Text Shape layer 3 times and hide it.

Rename the copy layers from top to bottom to Fill, Outer Stroke, and Stroke.

Keep in mind that you can turn these layers’ visibility on and off during the tutorial to better see what you’re doing with each one of them.

Duplicate the Shape Layer

Step 5

For both the Stroke and Outer Stroke layers, select each of them, and pick the Direct Selection Tool (A) to adjust their shape attributes in the Options bar.

Change the Fill to None, the Stroke Color to any bright color, and the Size to 35. Then click the Set shape stroke type icon to change the Align to Center and the Corners to Round.

Shape Attributes

3. How to Style the Stroke Layer

Double-click the Stroke layer to apply the following layer style:

Step 1

Add a Bevel and Emboss with these settings:

  • Size: 0
  • Uncheck the Use Global Light box
  • Angle: 40
  • Altitude: 48
  • Check the Anti-aliased box
  • Highlight Mode: Overlay
    • Opacity: 60%
  • Shadow Mode: Linear Burn
    • Opacity: 35%
Bevel and Emboss

Step 2

Add a Texture with these settings:

  • Pattern: Rough Cloth
  • Scale: 100%
  • Depth: 1000%
  • Check the Invert box
Texture

Step 3

Add a Pattern Overlay with these settings:

  • Pattern: 71.jpg
Pattern Overlay

Step 4

Change the Stroke layer’s Fill value to 0.

Fill Value

4. How to Style the Outer Stroke Layer

Double-click the Outer Stroke layer to apply the following layer style:

Step 1

Add a Bevel and Emboss with these settings:

  • Style: Stroke Emboss
  • Size: 29
  • Check the Anti-aliased box
  • Highlight Mode: Soft Light
    • Opacity: 35%
  • Shadow Mode: Linear Burn
    • Opacity: 35%
Bevel and Emboss

Step 2

Add a Contour with these settings:

  • Contour: Cove – Deep
  • Check the Anti-aliased box.
Contour

Step 3

Add a Texture with these settings:

  • Pattern: Project Papper
  • Check the Invert box
Texture

Step 4

Add a Stroke with these settings:

  • Size: 3
  • Position: Outside
  • Fill Type: Pattern
  • Pattern: 71.jpg
Stroke

Step 5

Change the Outer Stroke layer’s Fill value to 0.

Fill Value

5. How to Style the Text Shape Layer

Make the Text Shape layer visible, and double-click it to apply the following layer style:

Step 1

Add a Pattern Overlay with these settings:

  • Pattern: Human Skin
  • Scale: 50%
Pattern Overlay

Step 2

Add a Color Overlay with these settings:

  • Color: #edece9
  • Blend Mode: Multiply

You can use any other color you like depending on the result you want.

Color Overlay

This will style the Text Shape layer.

Text Shape

6. How to Create and Style Eyelets

Step 1

Pick the Ellipse Tool and create a 30 x 30 px circle where you want to place the first eyelet.

Then, press-hold the Option key, and create a smaller 17 x 17 px circle inside the one you already have to subtract it and get the main eyelet shape.

You can use the Path Selection Tool to separately select and move the smaller circle inside the bigger one if needed.

Right-click the shape layer and choose Convert to Smart Object.

Create the Eyelet Shape

Double-click the eyelet shape layer to apply the following layer style:

Step 2

Add a Bevel and Emboss with these settings:

  • Size: 7
  • Uncheck the Use Global Light box
  • Angle: 40
  • Altitude: 48
  • Check the Anti-aliased box
  • Highlight Mode: Linear light
    • Opacity: 60%
  • Shadow Mode: Linear Burn
    • Opacity: 35%
Bevel and Emboss

Step 3

Add a Contour with these settings:

  • Contour: Cone
  • Check the Anti-aliased box.
Contour

Step 4

Add a Color Overlay with these settings:

  • Color: #969c9d
Color Overlay

Step 5

Add a Drop Shadow with these settings:

  • Opacity: 100%
  • Distance: 2
  • Size: 3
Drop Shadow

Step 6

Add another Drop Shadow effect instance with these settings:

  • Opacity: 60%
  • Distance: 3
  • Size: 7
Drop Shadow

Step 7

Press-hold the Option key and click-drag the styled eyelet shape to duplicate it. You can press-hold the Shift key while doing so to constrain the movement.

Duplicate the Eyelet Shape

7. How to Modify a Ribbon Image

Step 1

Open the Ribbons image, and use the Quick Selection Tool to select the black ribbon.

Select the Ribbon

Step 2

Press Command-J to duplicate the selected ribbon into a new layer, and use the Rectangular Marquee Tool to select a portion you like of the duplicated ribbon.

Press Command-J again to duplicate that portion in a new layer, and hide the other layers you have.

Duplicate the Ribbon

Step 3

Use the Rectangular Marquee Tool to select the right half of the ribbon, pick the Move Tool, and press the Left Arrow key a couple of times to move the selected part inwards, making the ribbon thinner without losing texture or details.

You might need to repeat the process a couple of times to get the result you like.

Once you do, duplicate the layer to the original text document.

Reduce the Ribbon Size

8. How to Add a Ribbon to an Eyelet

Step 1

The ribbon should be thin enough to fit inside the eyelet shape you have. If it’s not, keep selecting one half of it and moving it inwards until you get the right size.

Duplicate the Ribbon

Step 2

Double-click the ribbon layer to apply an Inner Shadow effect with these settings:

  • Color: #020302
  • Opacity: 100%
  • Distance: 0
  • Size: 5
Inner Shadow

Step 3

Convert the ribbon layer to a Smart Object.

Convert to a Smart Object

Step 4

Press Command-T to enter Free Transform Mode, rotate the ribbon to an angle you like based on the distance you want to create between the eyelet rows, and place one of its ends inside the first eyelet.

You can also resize the ribbon slightly if needed.

Free Transform Mode

Step 5

Press the Warp icon in the Options bar to enter Warp Mode, and click-drag the ribbon’s tip to create a small arc and give the illusion of it being folded into the eyelet.

Press the Return key to commit the changes.

Warp Mode

9. How to Build a Laced-Up Effect

Step 1

Duplicate both eyelet shape layers and drag them downwards. Adjust their position as well as the ribbon’s end so that they meet where you’d like them to.

Place the Ribbon

Step 2

Duplicate the ribbon layer, and go to Edit > Transform > Flip Horizontal.

Place the flipped ribbon’s tip inside the empty top eyelet.

Flip Horizontal

Step 3

With the ribbon layer selected, click the Add layer mask icon at the bottom of the Layers panel, and select the mask’s thumbnail.

Pick the Brush Tool, set the Foreground Color to Black, choose a hard round brush tip with the same Size as the eyelet, and click on the bottom eyelet to erase the ribbon covering it.

Then, erase the extra parts of the ribbon, and repeat that for the other one.

Remove the Extra Parts

Step 4

Double-click the ribbon’s Smart Object thumbnail to open it, add a Hue/Saturation adjustment layer, and change both the Hue and Saturation values to -60.

Save and close the file.

HueSaturation

Step 5

To continue building the laced-up effect, select both the ribbon layers and the bottom eyelet layers, duplicate them, and drag them downwards.

Duplicate the Lace Units

Step 6

Keep doing that for the straight parts of the letters. Once you reach a curved area, duplicate one of the ribbon layers, rotate it so that it’s horizontal again, and place it on top of the last pair of eyelets you have.

You might need to delete the layer mask in order to transform the ribbon, so do that, and add in a new mask to get rid of any extra parts.

End the Lace-Up

Step 7

Take the time to build up the effect, and play around with the placement of the elements to fit each letter’s shape.

Build the Lace-Up Effect

Step 8

Once you’re done, put all the eyelet and ribbon layers in a group and name it Lace.

Lace Group

10. How to Cover Empty Text Areas

Step 1

Select the Fill layer and change its Fill value to 0.

Fill Value

Step 2

Pick the Rectangle Tool, press-hold the Option key, and create rectangles that cover the laced-up parts of the letters you have to remove them.

Remove the Lace-Up Parts

Step 3

Change the Fill layer’s Fill value back to 100%, and click the Path operations icon in the Options bar to choose Merge Shape Components.

Merge Shape Components

Step 4

Pick the Add Anchor Point Tool, and click where you want to extend the shape to cover any more areas.

Add Anchor Point Tool

Step 5

Pick the Convert Point Tool and click any anchor points you added to convert them to corner points.

Convert Point Tool

Step 6

Use the Direct Selection Tool to select and drag the anchor points to create a final shape you like.

Drag the Points

Step 7

Duplicate the Fill shape layer and rename the copy to Stitches.

Stitches Layer

Step 8

In the Options bar, change the Fill to None, the Stroke Size to 2, click the Set shape stroke type icon, and choose the dashed preset.

Stroke Properties

11. How to Style Stitches

Step 1

Right-click the Stroke layer, choose Copy Layer Style, right-click the Fill layer, and choose Paste Layer Style.

Copy and Paste the Layer style

Double-click the Stitches layer to apply the following layer style:

Step 2

Add a Bevel and Emboss with these settings:

  • Size: 1
  • Check the Anti-aliased box
  • Highlight Mode: Linear Light
    • Opacity: 82%
  • Shadow Mode: Linear Burn
    • Opacity: 35%
Bevel and Emboss

Step 3

Add a Contour with these settings:

  • Contour: Gaussian
  • Check the Anti-aliased box.
Contour

Step 4

Add a Color Overlay with these settings:

  • Color: #b5b4b2
Color Overlay

Step 5

Add a Drop Shadow with these settings:

  • Opacity: 100%
  • Distance: 2
  • Spread: 5
  • Size: 5
Drop Shadow

This will style the stitches.

Styled Stitches

12. How to Add Edges

Step 1

Duplicate the Outer Stroke Layer and change its Fill value to 100%.

Fill Value

Step 2

Convert the copy layer to a Smart Object and Command-click its thumbnail to load a selection.

Load a Selection

Step 3

Open the Paths panel, Option-click the Make work path from selection icon at the bottom of the panel, set the Radius to 0.8, and click OK.

Make Work Path

Step 4

Hide the Outer Stroke copy layer, and create a new layer on top of it with the name Edges.

Edges Layer

13. How to Create an Edges Brush

Step 1

Pick the Brush Tool and open the Brush Settings panel.

Choose the Dune Grass tip and adjust its settings as below:

Brush Tip Shape

Brush Tip Shape

Shape Dynamics

Shape Dynamics

Scattering

Scattering

Color Dynamics

Color Dynamics

Step 2

Set the Foreground Color to #212121 and the Background Color to #3f3f3f, and hit the Return key a couple of times until you like the stroke.

Stroke the Work Path

Step 3

Place all the layers you have, except for the Background and Solid Color layers, in a group and name it Text.

Text Group

14. How to Add Drop Shadow and Noise

Step 1

Double-click the Text group to apply Drop Shadow effects with these settings:

  • Opacity: 50%
  • Distance: 2
  • Spread: 5
  • Size: 5
Drop Shadow

Step 2

  • Opacity: 30%
  • Distance: 30
  • Size: 50
Drop Shadow

This will add the final shadows.

Added Shadows

Step 3

Place the 1.jpg image from the Abstract Spotlight Backgrounds pack on top of the Solid Color layer, and resize it to fit within the document so that its bottom part isn’t showing.

Rename the layer to BG Texture and change its Blend Mode to Soft Light.

BG Texture

Step 4

Create a new layer, name it BG Noise, and go to Edit > Fill.

Change the Contents to 50% Gray and click OK.

Gray Fill

Step 5

Convert the BG Noise layer to a Smart Object, and change its Blend Mode to Soft Light.

Convert to a Smart Object

Step 6

Go to Filter > Noise > Add Noise, change the Amount to 10 and the Distribution to Uniform, and check the Monochromatic box.

Add Noise Filter

15. How to Make the Final Changes

Step 1

Add a Levels adjustment layer on top of the Text group, change its Blend Mode to Luminosity, and change the Shadows value to 5 and the Highlights to 237.

Levels

Step 2

Add another Levels adjustment layer on top of all layers, choose the Blue channel, and change the Output Shadows value to 7.

Blue Channel Levels

Step 3

Create a new layer on top of all layers, name it High Pass, and press Command-Option-Shift-E to create a stamp.

Convert the layer to a Smart Object and change its Blend Mode to Soft Light.

High Pass Layer

Step 4

Go to Filter > Other > High Pass, and change the Radius value to 1.

High Pass Filter

Step 5

Duplicate the BG Noise layer, place the copy on top of all layers, expand the Smart Filters list, and double-click the Noise tab to change the Amount to 7.

Add Noise Filter

Congratulations, You’re Done!

In this tutorial, we created a couple of shape layers and adjusted their shape attributes to create the different text parts.

Then, we styled the layers, created the eyelets, and added the ribbon.

After that, we worked with the different elements to build the laced-up effect, and created a brush tip to add some fuzzy edges.

Finally, we made some final adjustments to finish off the effect.

Please feel free to leave your comments, suggestions, and outcomes below.

Final Result

Agregator najlepszych postów o designie, webdesignie, cssie i Internecie