بلاگ

  • Building a Real-Time Dithering Shader

    Building a Real-Time Dithering Shader


    In this post, we’ll take a closer look at the dithering-shader project: a minimal, real-time ordered dithering effect built using GLSL and the Post Processing library.

    Rather than just creating a one-off visual effect, the goal was to build something clean, composable, and extendable: a drop-in shader pass that brings pixel-based texture into modern WebGL pipelines.

    What It Does

    This shader applies ordered dithering as a postprocessing effect. It transforms smooth gradients into stylized, binary (or quantized) pixel patterns, simulating the visual language of early bitmap displays, dot matrix printers, and 8-bit games.

    It supports:

    • Dynamic resolution via pixelSize
    • Optional grayscale mode
    • Composability with bloom, blur, or other passes
    • Easy integration via postprocessing‘s Effect class

    Fragment Shader

    Our dithering shader implementation consists of two main components:

    1. The Core Shader

    The heart of the effect lies in the GLSL fragment shader that implements ordered dithering:

    bool getValue(float brightness, vec2 pos) {
    
    // Early return for extreme values
    if (brightness > 16.0 / 17.0) return false;
    if (brightness < 1.0 / 17.0) return true;
    
    // Calculate position in 4x4 dither matrix
    vec2 pixel = floor(mod(pos.xy / gridSize, 4.0));
    int x = int(pixel.x);
    int y = int(pixel.y);
    
    // 4x4 Bayer matrix threshold map
    // ... threshold comparisons based on matrix position
    
    }

    The getValue function is the core of the dithering algorithm. It:

    • Takes brightness and position: Uses the pixel’s luminance value and screen position
    • Maps to dither matrix: Calculates which cell of the 4×4 Bayer matrix the pixel belongs to
    • Applies threshold: Compares the brightness against a predetermined threshold for that matrix position
    • Returns binary decision: Whether the pixel should be black or colored

    Key Shader Features

    • gridSize: Controls the size of the dithering pattern
    • pixelSizeRatio: Adds pixelation effect for enhanced retro feel
    • grayscaleOnly: Converts the image to grayscale before dithering
    • invertColor: Inverts the final colors for different aesthetic effects

    2. Pixelation Integration

    float pixelSize = gridSize * pixelSizeRatio;
    vec2 pixelatedUV = floor(fragCoord / pixelSize) * pixelSize / resolution;
    baseColor = texture2D(inputBuffer, pixelatedUV).rgb;

    The shader combines dithering with optional pixelation, creating a compound retro effect that’s perfect for game-like visuals.

    Creating a Custom Postprocessing Effect

    The shader is wrapped using the Effect base class from the postprocessing library. This abstracts away the boilerplate of managing framebuffers and passes, allowing the shader to be dropped into a scene with minimal setup.

    export class DitheringEffect extends Effect {
      uniforms: Map<string, THREE.Uniform<number | THREE.Vector2>>;
    
      constructor({
        time = 0,
        resolution = new THREE.Vector2(1, 1),
        gridSize = 4.0,
        luminanceMethod = 0,
        invertColor = false,
        pixelSizeRatio = 1,
        grayscaleOnly = false
      }: DitheringEffectOptions = {}) {
        const uniforms = new Map<string, THREE.Uniform<number | THREE.Vector2>>([
          ["time", new THREE.Uniform(time)],
          ["resolution", new THREE.Uniform(resolution)],
          ["gridSize", new THREE.Uniform(gridSize)],
          ["luminanceMethod", new THREE.Uniform(luminanceMethod)],
          ["invertColor", new THREE.Uniform(invertColor ? 1 : 0)],
          ["ditheringEnabled", new THREE.Uniform(1)],
          ["pixelSizeRatio", new THREE.Uniform(pixelSizeRatio)],
          ["grayscaleOnly", new THREE.Uniform(grayscaleOnly ? 1 : 0)]
        ]);
    
        super("DitheringEffect", ditheringShader, { uniforms });
        this.uniforms = uniforms;
      }
    
     ...
    
    }

    Optional: Integrating with React Three Fiber

    Once defined, the effect is registered and applied using @react-three/postprocessing. Here’s a minimal usage example with bloom and dithering:

    <Canvas>
      {/* ... your scene ... */}
      <EffectComposer>
        <Bloom intensity={0.5} />
        <Dithering pixelSize={2} grayscale />
      </EffectComposer>
    </Canvas>

    You can also tweak pixelSize dynamically to scale the effect with resolution, or toggle grayscale mode based on UI controls or scene context.

    Extending the Shader

    This shader is intentionally kept simple, a foundation rather than a full system. It’s easy to customize or extend. Here are some ideas you can try:

    • Add color quantization: convert color.rgb to indexed palettes
    • Pack depth-based dither layers for fake shadows
    • Animate the pattern for VHS-like shimmer
    • Interactive pixelation: use mouse proximity to affect u_pixelSize

    Why Not Use a Texture?

    Some dithering shaders rely on threshold maps or pre-baked noise textures. This one doesn’t. The matrix pattern is deterministic and screen-space based, which means:

    • No texture loading required
    • Fully procedural
    • Clean pixel alignment

    It’s not meant for photorealism. It’s for styling and flattening. Think more zine than render farm.

    Final Thoughts

    This project started as a side experiment to explore what it would look like to bring tactile, stylized “non-photorealism” back into postprocessing workflows. But I found it had broader use cases, especially in cases where design direction favors abstraction or controlled distortion.

    If you’re building UIs, games, or interactive 3D scenes where “perfect” isn’t the goal, maybe a little pixel grit is exactly what you need.



    Source link

  • 6.51 Million Google Clicks! 💵

    6.51 Million Google Clicks! 💵


    Yesterday Online PNG Tools smashed through 6.50M Google clicks and today it’s smashed through 6.51M Google clicks! That’s 10,000 new clicks in a single day – the smash train keeps on rollin’!

    What Are Online PNG Tools?

    Online PNG Tools offers a collection of easy-to-use web apps that help you work with PNG images right in your browser. It’s like a Swiss Army Knife for anything PNG-related. On this site, you can create transparent PNGs, edit icons, clean up logos, crop stamps, change colors of signatures, and customize stickers – there’s a tool for it all. The best part is that you don’t need to install anything or be a graphic designer. All tools are made for regular people who just want to get stuff done with their images. No sign-ups, no downloads – just quick and easy PNG editing tools.

    Who Created Online PNG Tools?

    Online PNG Tools were created by me and my team at Browserling. We’ve build simple, browser-based tools that anyone can use without needing to download or install anything. Along with PNG tools, we also work on cross-browser testing to help developers make sure their websites work great on all web browsers. Our mission is to make online tools that are fast, easy to use, and that are helpful for everyday tasks like editing icons, logos, and signatures.

    Who Uses Online PNG Tools?

    Online PNG Tools and Browserling are used by everyone – from casual users to professionals and even Fortune 100 companies. Casual users often use them to make memes, edit profile pictures, or remove backgrounds. Professionals use them to clean up logos, design icons, or prepare images for websites and apps.

    Smash too and see you tomorrow at 6.52M clicks! 📈

    PS. Use coupon code SMASHLING for a 30% discount on these tools at onlinePNGtools.com/pricing. 💸



    Source link

  • 6.53 Million Google Clicks! 💵

    6.53 Million Google Clicks! 💵


    Yesterday Online PNG Tools smashed through 6.52M Google clicks and today it’s smashed through 6.53M Google clicks! That’s 10,000 new clicks in a single day – the smash train keeps on rollin’!

    What Are Online PNG Tools?

    Online PNG Tools offers a collection of easy-to-use web apps that help you work with PNG images right in your browser. It’s like a Swiss Army Knife for anything PNG-related. On this site, you can create transparent PNGs, edit icons, clean up logos, crop stamps, change colors of signatures, and customize stickers – there’s a tool for it all. The best part is that you don’t need to install anything or be a graphic designer. All tools are made for regular people who just want to get stuff done with their images. No sign-ups, no downloads – just quick and easy PNG editing tools.

    Who Created Online PNG Tools?

    Online PNG Tools were created by me and my team at Browserling. We’ve build simple, browser-based tools that anyone can use without needing to download or install anything. Along with PNG tools, we also work on cross-browser testing to help developers make sure their websites work great on all web browsers. Our mission is to make online tools that are fast, easy to use, and that are helpful for everyday tasks like editing icons, logos, and signatures.

    Who Uses Online PNG Tools?

    Online PNG Tools and Browserling are used by everyone – from casual users to professionals and even Fortune 100 companies. Casual users often use them to make memes, edit profile pictures, or remove backgrounds. Professionals use them to clean up logos, design icons, or prepare images for websites and apps.

    Smash too and see you tomorrow at 6.54M clicks! 📈

    PS. Use coupon code SMASHLING for a 30% discount on these tools at onlinePNGtools.com/pricing. 💸



    Source link

  • Elastic Grid Scroll: Creating Lag-Based Layout Animations with GSAP ScrollSmoother

    Elastic Grid Scroll: Creating Lag-Based Layout Animations with GSAP ScrollSmoother


    You’ve probably seen this kind of scroll effect before, even if it doesn’t have a name yet. (Honestly, we need a dictionary for all these weird and wonderful web interactions. If you’ve got a talent for naming things…do it. Seriously. The internet is waiting.)

    Imagine a grid of images. As you scroll, the columns don’t move uniformly but instead, the center columns react faster, while those on the edges trail behind slightly. It feels soft, elastic, and physical, almost like scrolling with weight, or elasticity.

    You can see this amazing effect on sites like yzavoku.com (and I’m sure there’s a lot more!).

    So what better excuse to use the now-free GSAP ScrollSmoother? We can recreate it easily, with great performance and full control. Let’s have a look!

    What We’re Building

    We’ll take CSS grid based layout and add some magic:

    • Inertia-based scrolling using ScrollSmoother
    • Per-column lag, calculated dynamically based on distance from the center
    • A layout that adapts to column changes

    HTML Structure

    Let’s set up the markup with figures in a grid:

    <div class="grid">
      <figure class="grid__item">
        <div class="grid__item-img" style="background-image: url(assets/1.webp)"></div>
        <figcaption class="grid__item-caption">Zorith - L91</figcaption>
      </figure>
      <!-- Repeat for more items -->
    </div>

    Inside the grid, we have many .grid__item figures, each with a background image and a label. These will be dynamically grouped into columns by JavaScript, based on how many columns CSS defines.

    CSS Grid Setup

    .grid {
      display: grid;
      grid-template-columns: repeat(var(--column-count), minmax(var(--column-size), 1fr));
      grid-column-gap: var(--c-gap);
      grid-row-gap: var(--r-gap);
    }
    
    .grid__column {
      display: flex;
      flex-direction: column;
      gap: var(--c-gap);
    }

    We define all the variables in our root.

    In our JavaScript then, we’ll change the DOM structure by inserting .grid__column wrappers around groups of items, one per colum, so we can control their motion individually. Why are we doing this? It’s a bit lighter to move columns rather then each individual item.

    JavaScript + GSAP ScrollSmoother

    Let’s walk through the logic step-by-step.

    1. Enable Smooth Scrolling and Lag Effects

    gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
    
    const smoother = ScrollSmoother.create({
      smooth: 1, // Inertia intensity
      effects: true, // Enable per-element scroll lag
      normalizeScroll: true, // Fixes mobile inconsistencies
    });

    This activates GSAP’s smooth scroll layer. The effects: true flag lets us animate elements with lag, no scroll listeners needed.

    2. Group Items Into Columns Based on CSS

    const groupItemsByColumn = () => {
      const gridStyles = window.getComputedStyle(grid);
      const columnsRaw = gridStyles.getPropertyValue('grid-template-columns');
    
      const numColumns = columnsRaw.split(' ').filter(Boolean).length;
    
      const columns = Array.from({ length: numColumns }, () => []); // Initialize column arrays
    
      // Distribute grid items into column buckets
      grid.querySelectorAll('.grid__item').forEach((item, index) => {
        columns[index % numColumns].push(item);
      });
    
      return { columns, numColumns };
    };

    This method groups your grid items into arrays, one for each visual column, using the actual number of columns calculated from the CSS.

    3. Create Column Wrappers and Assign Lag

    const buildGrid = (columns, numColumns) => {
    
      const fragment = document.createDocumentFragment(); // Efficient DOM batch insertion
      const mid = (numColumns - 1) / 2; // Center index (can be fractional)
      const columnContainers = [];
    
      // Loop over each column
      columns.forEach((column, i) => {
        const distance = Math.abs(i - mid); // Distance from center column
        const lag = baseLag + distance * lagScale; // Lag based on distance from center
    
        const columnContainer = document.createElement('div'); // New column wrapper
        columnContainer.className = 'grid__column';
    
        // Append items to column container
        column.forEach((item) => columnContainer.appendChild(item));
    
        fragment.appendChild(columnContainer); // Add to fragment
        columnContainers.push({ element: columnContainer, lag }); // Save for lag effect setup
      });
    
      grid.appendChild(fragment); // Add all columns to DOM at once
      return columnContainers;
    };

    The lag value increases the further a column is from the center, creating that elastic “catch up” feel during scroll.

    4. Apply Lag Effects to Each Column

    const applyLagEffects = (columnContainers) => {
      columnContainers.forEach(({ element, lag }) => {
        smoother.effects(element, { speed: 1, lag }); // Apply individual lag per column
      });
    };

    ScrollSmoother handles all the heavy lifting, we just pass the desired lag.

    5. Handle Layout on Resize

    // Rebuild the layout only if the number of columns has changed on window resize
    window.addEventListener('resize', () => {
      const newColumnCount = getColumnCount();
      if (newColumnCount !== currentColumnCount) {
        init();
      }
    });

    This ensures our layout stays correct across breakpoints and column count changes (handled via CSS).

    And that’s it!

    Extend This Further

    Now, there’s lots of ways to build upon this and add more jazz!

    For example, you could:

    • add scroll-triggered opacity or scale animations
    • use scroll velocity to control effects (see demo 2)
    • adapt this pattern for horizontal scroll layouts

    Exploring Variations

    Once you have the core concept in place, there are four demo variations you can explore. Each one shows how different lag values and scroll-based interactions can influence the experience.

    You can adjust which columns respond faster, or play with subtle scaling and transforms based on scroll velocity. Even small changes can shift the rhythm and tone of the layout in interesting ways. And don’t forget: changing the look of the grid itself, like the image ratio or gaps, will give this a whole different feel!

    Now it’s your turn. Tweak it, break it, rebuild it, and make something cool.

    I really hope you enjoy this effect! Thanks for checking by 🙂



    Source link

  • 6.54 Million Google Clicks! 💵

    6.54 Million Google Clicks! 💵


    Yesterday Online PNG Tools smashed through 6.53M Google clicks and today it’s smashed through 6.54M Google clicks! That’s 10,000 new clicks in a single day – the smash train keeps on rollin’!

    What Are Online PNG Tools?

    Online PNG Tools offers a collection of easy-to-use web apps that help you work with PNG images right in your browser. It’s like a Swiss Army Knife for anything PNG-related. On this site, you can create transparent PNGs, edit icons, clean up logos, crop stamps, change colors of signatures, and customize stickers – there’s a tool for it all. The best part is that you don’t need to install anything or be a graphic designer. All tools are made for regular people who just want to get stuff done with their images. No sign-ups, no downloads – just quick and easy PNG editing tools.

    Who Created Online PNG Tools?

    Online PNG Tools were created by me and my team at Browserling. We’ve build simple, browser-based tools that anyone can use without needing to download or install anything. Along with PNG tools, we also work on cross-browser testing to help developers make sure their websites work great on all web browsers. Our mission is to make online tools that are fast, easy to use, and that are helpful for everyday tasks like editing icons, logos, and signatures.

    Who Uses Online PNG Tools?

    Online PNG Tools and Browserling are used by everyone – from casual users to professionals and even Fortune 100 companies. Casual users often use them to make memes, edit profile pictures, or remove backgrounds. Professionals use them to clean up logos, design icons, or prepare images for websites and apps.

    Smash too and see you tomorrow at 6.55M clicks! 📈

    PS. Use coupon code SMASHLING for a 30% discount on these tools at onlinePNGtools.com/pricing. 💸



    Source link

  • DICH™ Fashion: A New Era of Futuristic Fashion

    DICH™ Fashion: A New Era of Futuristic Fashion


    The Reset

    I hadn’t planned on creating a fashion interface. I just needed a reboot. At the time, I was leading art direction at the studio, juggling multiple projects, and emotionally, I was simply exhausted. I joined an Awwwards Masterclass to rediscover the joy of playing with design. I wanted to learn Webflow. I wanted to explore GSAP. But more than that, I wanted to create something unapologetically weird and beautiful.

    That seed grew into DICH™, Design Independent Creative House. What started as a design playground became a statement.

    Designing the Unfuturistic Future

    We made a conscious decision: no dark mode. No glitch filters. Most futuristic UIs feel cold. We wanted warmth, softness, a vision of the future that is poetic, not synthetic.

    Each section had its own visual temperature. Soft gradients, air, pastel dust. Typography was crucial. The T-12 font had those strange numeric ligatures that felt alien but elegant. Video, color, typography — all speaking the same language.

    We built moodboards, UX pillars, and rhythm plans. That process, taught in the Masterclass, changed how we approached layout. It wasn’t about grids. It was about flow.

    Building the Entry Ritual (Preloader)

    The preloader wasn’t just an aesthetic flex. It solved three key problems:

    • Our media-heavy site needed time to load
    • Browsers block autoplaying audio without user interaction
    • We wanted to introduce mood and rhythm before the scroll even began

    It was animated in After Effects and exported to Lottie, then embedded into Webflow and animated using GSAP.

    The Enter button also triggered sound. It was our “permission point” for browser playback.

    // Fade out overlay
    gsap.to(preloaderBlack, {
      opacity: 0,
      duration: 0.25,
      onComplete: () => preloaderBlack.style.display = "none"
    });
    
    // Animate entry lines
    gsap.fromTo(line, { width: 0 }, {
      width: '100%',
      duration: 1.25,
      delay: 1,
      ease: 'power2.out'
    });
    
    // Show enter button
    gsap.delayedCall(5.25, () => {
      preloaderEnterButton.classList.add('is-active');
    });

    Section-Aware Navigation

    We wanted the navigation to feel alive, to reflect where you were on the page.

    So we built a scroll-aware section indicator that updated with a scramble effect. It changed dynamically using this script:

    const updateIndicator = (newTitle) => {
      if (newTitle !== currentSection) {
        currentSection = newTitle;
        indicator.setAttribute('data-text', newTitle);
        scrambleAnimate(indicator, newTitle, false);
      }
    };

    The Monster That Followed You

    We modeled a monster in Blender, with arms, eyes, and floaty weirdness, then exported it to Spline. We wanted it to follow the user’s cursor.

    At first, we used .fbx.

    Huge mistake. The file was massive. FPS dropped. Memory exploded. We tried simplifying textures, removing light bounces, optimizing geometry — no dice.

    Then someone on the team said, “What if it’s the format?”

    We re-exported in .gbl and instantly it worked. Light. Fast. Fluid.

    Frame That Doesn’t Break

    One big challenge: a decorative frame that scales on every screen without distortion. SVG alone stretched in weird ways.

    Our solution:

    • Split each edge into its own div or SVG
    • Use absolute positioning
    • Use vw/vh for SVG scaling, em for div spacing
    @media (min-width: 992px) {
      .marquee-css {
        display: flex;
        overflow: hidden;
      }
      .marquee_element {
        white-space: nowrap;
        animation: marquee-horizontal 40s linear infinite;
      }
      @keyframes marquee-horizontal {
        0% {
          transform: translateX(0);
        }
        100% {
          transform: translateX(-100%);
        }
      }
    }

    Cursor Coordinates

    Live coordinate HUD under the cursor — perfectly suited to our site’s theme, so we decided to include it.

    document.addEventListener('DOMContentLoaded', function () {
      if (window.innerWidth <= 768) return;
      const xCoord = document.getElementById('x-coordinate');
      const yCoord = document.getElementById('y-coordinate');
      let mouseX = 0;
      let mouseY = 0;
      let lastX = -1;
      let lastY = -1;
      let ticking = false;
      function formatNumber(num) {
        return num.toString().padStart(4, '0');
      }
      function updateCoordinates() {
        if (mouseX !== lastX || mouseY !== lastY) {
          xCoord.textContent = formatNumber(mouseX % 10000);
          yCoord.textContent = formatNumber(mouseY % 10000);
          lastX = mouseX;
          lastY = mouseY;
        }
        ticking = false;
      }
      document.addEventListener('mousemove', (event) => {
        mouseX = event.clientX;
        mouseY = event.clientY;
        if (!ticking) {
          ticking = true;
          requestAnimationFrame(updateCoordinates);
        }
      });
    });
    

    Stones That Scroll

    We placed a 3D stone (also from Blender) into Spline, gave it orbital motion, and connected it to scroll using Webflow Interactions.

    It felt like motion with gravity — guided, yet organic.

    Pixel Tracer

    With coordinate tracking already in place, we easily applied it to our section and later enhanced it with a pixel tracer inspired by Jean Mazouni’s displacement effect.

    Unicorn Everywhere

    The cursor wasn’t just a pointer, it became a vibe.

    We used Unicorn Studio to create custom cursor trails and animations that followed the user like echoes of intent. Three variations in total:

    • One for the landing screen — minimal, hypnotic.
    • One for the project case study — denser, electric.
    • One for transitions — barely-there glimmer, like a memory.

    Each version added tension and curiosity. It wasn’t flashy for the sake of it — it gave rhythm to hovering, a pulse to the interaction. Suddenly, the cursor wasn’t just a tool. It was part of the interface’s voice.

    Footer Letters with Physics

    Our footer was a personal moment. We wanted the word “DICH” to be hidden inside animated lines and revealed on hover using canvas and brightness sampling.

    This one took the longest. We tried Perlin noise, sine curves, and springs, but none worked as we’d hoped or produced results that were sufficiently readable — until we found an old Domestika course that showed getImageData() logic.

    const typeData = typeContext.getImageData(0, 0, typeCanvasWidth, typeCanvasHeight).data;

    For the smoothness of the lines we gave up straight cuts and switched to quadratic curves:

    context.quadraticCurveTo(prev.x, prev.y, (prev.x+curr.x)/2, (prev.y+curr.y)/2);

    Lazy Load + Safari Nightmares

    We had to optimize. Hard.

    • Every visual block was lazy-loaded using IntersectionObserver
    • Safari compatibility issues — reworked unsupported animations for Safari and added fallbacks for AVIF images (even lighter than WebP) to maximize optimization.
    • Heavy sections only rendered after the preloader finished
    const io = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          const el = entry.target;
          el.classList.add('active');
          const images = el.querySelectorAll('img[data-src]');
          images.forEach((img) => (img.src = img.dataset.src));
          observer.unobserve(el);
        }
      });
    });

    404, But Make It Fashion

    Most 404 pages apologize. Ours seduced.

    We treated the error page like a runway — not a dead-end, but an invitation. Instead of a sad emoji or a bland “page not found,” you get a full-screen glitch-dream: warped typography, soft scans, and a single message that flickers like a memory.

    Technically, it was simple — a standalone Webflow page. But visually, it extended the DICH world: same typographic tension, same surreal softness. We even debated adding background audio, but silence won — it made the page feel like a moment suspended in time.

    What We Learned

    • File formats matter more than you think
    • Glitches aren’t as magical as thoughtful motion
    • GSAP is our best friend
    • Webflow is powerful when paired with code
    • You don’t need a big plan to make something that matters

    Closing

    I almost gave up. More than once. But every time the team cracked a bug, designed a transition, or made a visual more strange — it reminded me why we build.

    DICH™ was a challenge, a love letter, and a reset. And now it’s yours to explore.

    Visit the DICH™ site

    Credits

    Creation Direction: BL/S®

    Art / Creative Director: Serhii Polyvanyi

    Webflow Designer: Ihor Romankov

    Support Developer: Kirill Trachuk

    PM: Julia Nikitenko

    Designed and built with Webflow, GSAP, Spline, AE, and possibly too much coffee.





    Source link

  • 6.55 Million Google Clicks! 💵

    6.55 Million Google Clicks! 💵


    Yesterday Online PNG Tools smashed through 6.54M Google clicks and today it’s smashed through 6.55M Google clicks! That’s 10,000 new clicks in a single day – the smash train keeps on rollin’!

    What Are Online PNG Tools?

    Online PNG Tools offers a collection of easy-to-use web apps that help you work with PNG images right in your browser. It’s like a Swiss Army Knife for anything PNG-related. On this site, you can create transparent PNGs, edit icons, clean up logos, crop stamps, change colors of signatures, and customize stickers – there’s a tool for it all. The best part is that you don’t need to install anything or be a graphic designer. All tools are made for regular people who just want to get stuff done with their images. No sign-ups, no downloads – just quick and easy PNG editing tools.

    Who Created Online PNG Tools?

    Online PNG Tools were created by me and my team at Browserling. We’ve build simple, browser-based tools that anyone can use without needing to download or install anything. Along with PNG tools, we also work on cross-browser testing to help developers make sure their websites work great on all web browsers. Our mission is to make online tools that are fast, easy to use, and that are helpful for everyday tasks like editing icons, logos, and signatures.

    Who Uses Online PNG Tools?

    Online PNG Tools and Browserling are used by everyone – from casual users to professionals and even Fortune 100 companies. Casual users often use them to make memes, edit profile pictures, or remove backgrounds. Professionals use them to clean up logos, design icons, or prepare images for websites and apps.

    Smash too and see you tomorrow at 6.56M clicks! 📈

    PS. Use coupon code SMASHLING for a 30% discount on these tools at onlinePNGtools.com/pricing. 💸



    Source link

  • 6.52 Million Google Clicks! 💵

    6.52 Million Google Clicks! 💵


    Yesterday Online PNG Tools smashed through 6.51M Google clicks and today it’s smashed through 6.52M Google clicks! That’s 10,000 new clicks in a single day – the smash train keeps on rollin’!

    What Are Online PNG Tools?

    Online PNG Tools offers a collection of easy-to-use web apps that help you work with PNG images right in your browser. It’s like a Swiss Army Knife for anything PNG-related. On this site, you can create transparent PNGs, edit icons, clean up logos, crop stamps, change colors of signatures, and customize stickers – there’s a tool for it all. The best part is that you don’t need to install anything or be a graphic designer. All tools are made for regular people who just want to get stuff done with their images. No sign-ups, no downloads – just quick and easy PNG editing tools.

    Who Created Online PNG Tools?

    Online PNG Tools were created by me and my team at Browserling. We’ve build simple, browser-based tools that anyone can use without needing to download or install anything. Along with PNG tools, we also work on cross-browser testing to help developers make sure their websites work great on all web browsers. Our mission is to make online tools that are fast, easy to use, and that are helpful for everyday tasks like editing icons, logos, and signatures.

    Who Uses Online PNG Tools?

    Online PNG Tools and Browserling are used by everyone – from casual users to professionals and even Fortune 100 companies. Casual users often use them to make memes, edit profile pictures, or remove backgrounds. Professionals use them to clean up logos, design icons, or prepare images for websites and apps.

    Smash too and see you tomorrow at 6.53M clicks! 📈

    PS. Use coupon code SMASHLING for a 30% discount on these tools at onlinePNGtools.com/pricing. 💸



    Source link

  • End of May Sale! 🎁

    End of May Sale! 🎁


    At Browserling and Online Tools we love sales.

    We just created a new automated End of May Sale.

    Now each month, on the last day of May, we show a 50% discount offer to all users who visit our site.

    Buy Now!

    🔥 onlinetools.com/pricing

    🔥 browserling.com/#pricing

    What Is Browserling?

    Browserling is an online service that lets you test how other websites look and work in different web browsers, like Chrome, Firefox, or Safari, without needing to install them. It runs real browsers on real machines and streams them to your screen, kind of like remote desktop but focused on browsers. This helps web developers and regular users check for bugs, suspicious links, and weird stuff that happens in certain browsers. You just go to Browserling, pick a browser and version, and then enter the site you want to test. It’s quick, easy, and works from your browser with no downloads or installs.

    What Are Online Tools?

    Online Tools is an online service that offers free, browser-based productivity tools for everyday tasks like editing text, converting files, editing images, working with code, and way more. It’s an all-in-one Digital Swiss Army Knife with 1500+ utilities, so you can find the exact tool you need without installing anything. Just open the site, use what you need, and get things done fast.

    Who Uses Browserling and Online Tools?

    Browserling and Online Tools are used by millions of regular internet users, developers, designers, students, and even Fortune 100 companies. Browserling is handy for testing websites in different browsers without having to install them. Online Tools are used for simple tasks like resizing or converting images, or even fixing small file problems quickly without downloading any apps.

    Buy a subscription now and see you next time!

    🔥 onlinetools.com/pricing

    🔥 browserling.com/#pricing



    Source link

  • 3D Cards in Webflow Using Three.js and GLB Models

    3D Cards in Webflow Using Three.js and GLB Models


    I’ve always been interested in finding simple ways to bring more depth into web interfaces, not just through visuals, but through interaction and space.

    In this demo, I explored how flat UI cards can become interactive 3D scenes using GLB models, Three.js, and Webflow. Each card starts as a basic layout but reveals a small, self-contained environment built with real-time rendering and subtle motion.

    It’s a lightweight approach to adding spatial storytelling to familiar components, using tools many designers already work with.

    Welcome to My Creative World

    I’m always drawn to visuals that mix the futuristic with the familiar — space-inspired forms, minimal layouts, and everyday elements seen from a different angle.

    Most of my projects start this way: by reimagining ordinary ideas through a more immersive or atmospheric lens.

    It All Started with a Moodboard

    This one began with a simple inspiration board:

    From that board, I picked a few of my favorite visuals and ran them through an AI tool that converts images into GLB 3D models.

    The results were surprisingly good! Abstract, textured, and full of character.

    The Concept: Flat to Deep

    When I saw the output from the AI-generated GLB models, I started thinking about how we perceive depth in UI design, not just visually, but interactively.

    That led to a simple idea: what if flat cards could reveal a hidden spatial layer? Not through animation alone, but through actual 3D geometry, lighting, and camera movement.

    I designed three UI cards, each styled with minimal HTML and CSS in Webflow. On interaction, they load a unique GLB model into a Three.js scene directly within the card container. Each model is lit, framed, and animated to create the feeling of a self-contained 3D space.

    Building the Web Experience

    The layout was built in Webflow using a simple flexbox structure with three cards inside a wrapper. Each card contains a div that serves as the mounting point for a 3D object.

    The GLB models are rendered using Three.js, which is integrated into the project with custom JavaScript. Each scene is initialized and handled separately, giving each card its own interactive 3D space while keeping the layout lightweight and modular.

    Scene Design with Blender

    Each GLB model was prepared in Blender, where I added a surrounding sphere to create a sense of depth and atmosphere. This simple shape helps simulate background contrast and encloses the object in a self-contained space.

    Lighting played an important role; especially with reflective materials like glass or metal. Highlights and soft shadows were used to create that subtle, futuristic glow.

    The result is that each 3D model feels like it lives inside its own ambient environment, even when rendered in a small card.

    Bringing It Together with Three.js

    Once the models were exported from Blender as .glb files, I used Three.js to render them inside each card. Each card container acts as its own 3D scene, initialized through a custom JavaScript function.

    The setup involves creating a basic scene with a perspective camera, ambient and directional lighting, and a WebGL renderer. I used GLTFLoader to load each .glb file and OrbitControls to enable subtle rotation. Zooming and panning are disabled to keep the interaction focused and controlled.

    Each model is loaded into a separate container, making it modular and easy to manage. The camera is offset slightly for a more dynamic starting view, and the background is kept dark to help the lighting pop.

    Here’s the full JavaScript used to load and render the models:

    // Import required libraries
    import * as THREE from 'three';
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
    import gsap from 'gsap';
    
    /**
     * This function initializes a Three.js scene inside a given container
     * and loads a .glb model into it.
     */
    function createScene(containerSelector, glbPath) {
      const container = document.querySelector(containerSelector);
    
      // 1. Create a scene
      const scene = new THREE.Scene();
      scene.background = new THREE.Color(0x202020); // dark background
    
      // 2. Set up the camera with perspective
      const camera = new THREE.PerspectiveCamera(
        45, // Field of view
        container.clientWidth / container.clientHeight, // Aspect ratio
        0.1, // Near clipping plane
        100  // Far clipping plane
      );
      camera.position.set(2, 0, 0); // Offset to the side for better viewing
    
      // 3. Create a renderer and append it to the container
      const renderer = new THREE.WebGLRenderer({ antialias: true });
      renderer.setSize(container.clientWidth, container.clientHeight);
      container.appendChild(renderer.domElement);
    
      // 4. Add lighting
      const light = new THREE.DirectionalLight(0xffffff, 4);
      light.position.set(30, -10, 20);
      scene.add(light);
    
      const ambientLight = new THREE.AmbientLight(0x404040); // soft light
      scene.add(ambientLight);
    
      // 5. Set up OrbitControls to allow rotation
      const controls = new OrbitControls(camera, renderer.domElement);
      controls.enableZoom = false; // no zooming
      controls.enablePan = false;  // no dragging
      controls.minPolarAngle = Math.PI / 2; // lock vertical angle
      controls.maxPolarAngle = Math.PI / 2;
      controls.enableDamping = true; // smooth movement
    
      // 6. Load the GLB model
      const loader = new GLTFLoader();
      loader.load(
        glbPath,
        (gltf) => {
          scene.add(gltf.scene); // Add model to the scene
        },
        (xhr) => {
          console.log(`${containerSelector}: ${(xhr.loaded / xhr.total) * 100}% loaded`);
        },
        (error) => {
          console.error(`Error loading ${glbPath}`, error);
        }
      );
    
      // 7. Make it responsive
      window.addEventListener("resize", () => {
        camera.aspect = container.clientWidth / container.clientHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(container.clientWidth, container.clientHeight);
      });
    
      // 8. Animate the scene
      function animate() {
        requestAnimationFrame(animate);
        controls.update(); // updates rotation smoothly
        renderer.render(scene, camera);
      }
    
      animate(); // start the animation loop
    }
    
    // 9. Initialize scenes for each card (replace with your URLs)
    createScene(".div",  "https://yourdomain.com/models/yourmodel.glb");
    createScene(".div2", "https://yourdomain.com/models/yourmodel2.glb");
    createScene(".div3", "https://yourdomain.com/models/yourmodel3.glb");

    This script is added via a <script type="module"> tag, either in the Webflow page settings or as an embedded code block. Each call to createScene() initializes a new card, linking it to its corresponding .glb file.

    How This Works in Practice

    In Webflow, create three containers with the classes .div, .div2, and .div3. Each one will act as a canvas for a different 3D scene.

    Embed the JavaScript module shown above by placing it just before the closing </body> tag in your Webflow project, or by using an Embed block with <script type="module">.

    Once the page loads, each container initializes its own Three.js scene and loads the corresponding GLB model. The result: flat UI cards become interactive, scrollable 3D objects — all directly inside Webflow.

    This approach is lightweight, clean, and performance-conscious, while still giving you the flexibility to work with real 3D content.

    Important Note for Webflow Users

    This setup works in Webflow, but only if you structure it correctly.

    To make it work, you’ll need to:

    • Host your Three.js code externally using a bundler like Vite, Parcel, or Webpack
    • Or bundle the JavaScript manually and embed it as a <script type="module"> in your exported site

    Keep in mind: Webflow’s Designer does not support ES module imports (import) directly. Pasting the code into an Embed block won’t work unless it’s already built and hosted elsewhere.

    You’ll need to export your Webflow project or host the script externally, then link it via your project settings.

    Final Thoughts

    Thanks for following along with this project. What started as a simple moodboard turned into a small experiment in mixing UI design with real-time 3D.

    Taking flat cards and turning them into interactive scenes was a fun way to explore how much depth you can add with just a few tools: Webflow, Three.js, and GLB models.

    If this gave you an idea or made you want to try something similar, that’s what matters most.
    Keep experimenting, keep learning, and keep building.



    Source link