Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature-request]: Allow background-image with gradients #495

Open
GregOnNet opened this issue Jan 17, 2021 · 3 comments
Open

[feature-request]: Allow background-image with gradients #495

GregOnNet opened this issue Jan 17, 2021 · 3 comments

Comments

@GregOnNet
Copy link

Hello @tjoskar,

thank you for providing this neat library.
Currently, I try to do something like this:

TEMPLATE

  <div [lazyload]="backgroundImageWithGradient"></div>

COMPONENT

@Component({ ... })
export class SomeComponent {
  imageUrl
  backgroundImageWithGradient = `linear-gradient(rgba(0,0,0,0.45), rgba(0,0,0,0.7)), url(' + this.imageUrl + ')`;
}

Of course, this fails, since [lazyload] expects an image URL.
It would help me if I could do something like shown above in order to define a gradient on top of the loaded image.

What do you think about it?

@tjoskar
Copy link
Owner

tjoskar commented Jan 17, 2021

Hi @GregOnNet,

This is a great idea. I see a few different options here:

  1. Check wherever lazyload is a URL or CSS-style and act accordingly. I do, however, think this will be hard and probably introduce bugs.
  2. Introduce a new flag that is telling that the string is CSS, something like: <div [lazyload]="backgroundImageWithGradient" resourceType="css"></div>. But i'm not sure about that.
  3. Use a custom hook (this should be possible today):
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { LazyLoadImageModule, IntersectionObserverHooks, Attributes, LAZYLOAD_IMAGE_HOOKS } from 'ng-lazyload-image';
import { AppComponent } from './app.component';

export class LazyLoadImageHooks extends IntersectionObserverHooks {
  setLoadedImage(att: Attributes) {
    if (att.element.dataset.backgroundWithGradient) {
      att.element.style.backgroundImage = att.element.dataset.backgroundWithGradient;
    } else {
      super.setLoadedImage(att);
    }
  }
}

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, LazyLoadImageModule],
  providers: [{ provide: LAZYLOAD_IMAGE_HOOKS, useClass: LazyLoadImageHooks }],
  bootstrap: [AppComponent],
})
export class MyAppModule {}

And then using the following template: <div [lazyload]="imageUrl" [attr.data-background-with-gradient]="backgroundImageWithGradient"></div>

I do however think this should be supported out of the box but I'm not sure how. There is an old, open, PR where we have discussed similar issues.

@GregOnNet
Copy link
Author

Hi,

thanks for the hint.
I will try the hook.

Concerning the API. I agree it would be nice to have this feature out-of-the-box.
Maybe it could be delivered as a separate Directive:

<div [lazyBackground]="imageUrl" [lazyBackroundGradient]="{
  position: "below"|"above",
  definition: "linear-gradient(rgba(0,0,0,0.45), rgba(0,0,0,0.7))"
}">

@tjoskar
Copy link
Owner

tjoskar commented Feb 7, 2021

I think it will be hard to implement this so it scales. What if I want to add no-repeat after the image url, like:

background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 1)), url('...') no-repeat;

And I believe it exists more edge cases. Maybe we can use a template, something like this:

<div [lazyBackground]="imageUrl" [styleToApply]="linear-gradient(rgba(0,0,0,0.45), rgba(0,0,0,0.7)), url('$IMAGE_URL$')">

But should that style also be used for the default/error-image?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants