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

Missing full gradients support for canvas background #4232

Closed
sandor opened this issue Aug 21, 2017 · 31 comments · Fixed by #5684
Closed

Missing full gradients support for canvas background #4232

sandor opened this issue Aug 21, 2017 · 31 comments · Fixed by #5684

Comments

@sandor
Copy link

sandor commented Aug 21, 2017

Is it possible now with 2.0.0 to set a gradient for the canvas object?

@asturur
Copy link
Member

asturur commented Aug 21, 2017

i think it has always ben possible, if there are difficulties, is time to fix it.

As of now you have to enlive the gradient on your self i think.

canvas.backgroundColor = myGradient.toLive()

@asturur
Copy link
Member

asturur commented Aug 21, 2017

Please share your use case with a fiddle

@sandor
Copy link
Author

sandor commented Aug 21, 2017

Not sure if i understand this right – but maybe you could give a hint on this fiddle?

http://jsfiddle.net/tmchz9h0/5/

@asturur
Copy link
Member

asturur commented Aug 21, 2017

http://jsfiddle.net/tmchz9h0/9/

this is an example that show that is possible, just hard to do and uncomfrotable.
I will not make it for release fo 2.0.0, but immediately after yes.

@sandor
Copy link
Author

sandor commented Aug 21, 2017

thank you very much! it is workin with 2.0.0-beta3

@sandor
Copy link
Author

sandor commented Aug 22, 2017

One additional question to this approach – should this be working also (defining coords with %)?

var grad = new fabric.Gradient({ type: 'linear', coords: { x1: "50%", y1: "0%", x2: "50%", y2: "100%", }, colorStops: [ { color: leftColor, offset: 0, }, { color: rightColor, offset: 1, } ] });

Or did you worked on the gradient angle function (I know I was reading about this somewhere)... ?

@ncou
Copy link
Collaborator

ncou commented Aug 30, 2017

@asturur : why is it "hard to do and unconfortable" ? It looks like you can pass a pattern object, but also a gradient object to the .setBackgroundColor() function.

http://jsfiddle.net/tmchz9h0/10/

But this information is not present in the documentation (it say : a string or a pattern object, it doesn't speak about a gradient object).

Am i missing something ?

@asturur
Copy link
Member

asturur commented Aug 30, 2017

well there is a difference between the object structure of a gradient when you want to set with the 'setGradient' method or when you want to create it with constructor.

that is bad.

Also the objects have a setGradient method and the canvas not.

I would like to get a simpler gradient interface but that is more breaking changes and i do not want to do them now.

@asturur
Copy link
Member

asturur commented Aug 30, 2017

@ncou yes the docs are probably outdated

@ncou
Copy link
Collaborator

ncou commented Aug 30, 2017

thank you, now it's more clear.

as always my 2 cents opinion : adding a setGradient() function to the canvas object, could be an overkill, today setting a background with fabric.js is not really clear if you don't read carfully the doc => you can use "setBackgroundImage()" with an url, an image object, a rect object [who can include a pattern object], and you can use "setBackgroundColor()" with a rgb string, a pattern object, and a gradient object.

@asturur
Copy link
Member

asturur commented Aug 30, 2017

i guess the safest is to deprecate both, keep them and add a generic setBackground that can handle both plus gradients and patterns.

@ncou
Copy link
Collaborator

ncou commented Aug 30, 2017

this could be a really clean solution, having one entry point to set a background is more easy.
Perhaps a bit tricky to for those who want to add both a background color AND a picture background.

@asturur
Copy link
Member

asturur commented Aug 30, 2017

you just call it twice. needs just a better doc and explanation.

@sandor
Copy link
Author

sandor commented Aug 31, 2017

@asturur while we are on this: there where some plans to introduce an angle for gradients instead of x1,x2,y1,y2 –. Are they abbandoned now?

@asturur
Copy link
Member

asturur commented Aug 31, 2017

no they are not.

the plan is making gradients simpler in some way, but mantain svg compatibility.

svg heavily relies on that coords and gradient transform, while who creates gradients by code could easily use something easier.

like percentages and angles.

@asturur asturur changed the title Canvas Gradients in 2.0.0 ? Missing full gradients support for canvas background Sep 1, 2017
@asturur
Copy link
Member

asturur commented Sep 1, 2017

From @ncou

Thank you.
I encounter a strange behaviors => I could make the gradientTransform work when i set the gradiant using "setGradient()" on a rect, but i create a new object calling directly the gradient object, i could not make it work.
I checked in the constructor (initialize function) and it should take my matrix.

Here is my fiddle :
http://jsfiddle.net/tmchz9h0/17/
TEST 1 is ok (if you uncomment the line 61, the rect with the transformed radial is applied).
TEST 2 is ko if i use a setbackgroundcolor with the new fabric.Gradient object created.

I even tried something like : grad.gradientTransform = fabric.parseTransformAttribute([1,0,0,2,1,1]); after creating my Gradient object. but without success.

@dedanirungu
Copy link

I have tried to change the linear gradient to radial but it did not work.

http://jsfiddle.net/sckkfj10/

@ncou
Copy link
Collaborator

ncou commented Nov 19, 2017

you need to use the correct parameters (r1 and r2 are missing).
http://jsfiddle.net/sckkfj10/1/

@Alwenjohn
Copy link

how can i set the canvas background with color picker?

@asturur
Copy link
Member

asturur commented Aug 17, 2018

@Alwenjohn we can t really help with application problems here, please open a stackoverflow question and link it here eventually

@rikkarv
Copy link

rikkarv commented Apr 17, 2019

I tried:
canvas.backgroundColor = myGradient.toLive()

However when I do json stringify from canvas.toObject() to store the canvas in the database for later upload I get "{"version":"2.7.0","objects":[],"background":{}}" because the value of 'background' property is an 'CanvasGradient'

@asturur
Copy link
Member

asturur commented Apr 27, 2019

i think gradients are supported if i'm not wrong.
Just assign a gradient fabric object?

@rikkarv
Copy link

rikkarv commented Apr 29, 2019 via email

@rikkarv
Copy link

rikkarv commented Apr 29, 2019

However I have found that when zooming the canvas or using toDataURL with multiplier (https://jsfiddle.net/8d30cfj1/1/) the gradient doesn't scale.
I believe that this is not the same behaviour that background images have.

@asturur
Copy link
Member

asturur commented Apr 30, 2019

oh that is weird. it should scale. i ll check.

@asturur asturur added bug and removed feature labels May 1, 2019
@asturur
Copy link
Member

asturur commented May 1, 2019

there is a flag in fabric for background zoom. It was a contentested option, some people thought it should scale other though it should not. Did you try it?

@asturur asturur removed the bug label May 1, 2019
@asturur
Copy link
Member

asturur commented May 1, 2019

@asturur
Copy link
Member

asturur commented May 1, 2019

Doesn't work with it either, is a bug.
probably something easy, like the gradient is done before the zoom is applied, an easy fix with random side effects.

@rikkarv
Copy link

rikkarv commented May 1, 2019 via email

@brandsmakr
Copy link

anyone who wants to solve this problem can set a gradient as a background by setting css background as a gradient using javascript.

const clrs = () => {
let allGradientClrs = "";
colors.map((gClr, index) => {
if (colors.length - 1 !== index) {
allGradientClrs += gClr.color.hex + ",";
} else {
allGradientClrs += gClr.color.hex;
}
});
return allGradientClrs;
};

const handleBgGradientOfPreviwer = ()=>{
let previwer = document.getElementsByClassName("upper-canvas");
for (let classInt = 0; classInt < previwer.length; classInt++) {
// } else
if (bgType === "radiant") {

    if (gradientType === "linear") {
      if (colors && colors.length > 0) {
        previwer[
          classInt
        ].style.background = `linear-gradient(30deg,${clrs()})`;
      } else {
        previwer[
          classInt
        ].style.background = `linear-gradient(#ffff00, #ffff00`;
      }
    } else if (gradientType === "radial") {
      if (colors && colors.length > 0) {
        previwer[classInt].style.background = `radial-gradient(${clrs()})`;
      } else {
        previwer[classInt].style.background =
          "radial-gradient(#ffff00, #ffff00)";
      }
    } else if (gradientType === "conic") {
      if (colors && colors.length > 0) {
        previwer[
          classInt
        ].style.background = `conic-gradient(from 45deg, ${clrs()})`;
      } else {
        previwer[classInt].style.background =
          "conic-gradient(#ffff00, #ffff00)";
      }
    }
  }
}

}

@brandsmakr
Copy link

brandsmakr commented Feb 14, 2023

Now I have try this one and is working fine.
You can also try this one
var canvas = window._canvas = new fabric.Canvas('c');

var grad = new fabric.Gradient({
type: 'linear',
coords: {
x1: 0,
y1: 0,
x2: canvas.width,
y2: canvas.height,
},
colorStops: [
{
color: 'rgb(166,111,213)',
offset: 0,
},
{
color: 'rgba(106, 72, 215, 0.5)',
offset: 0.5,
},
{
color: '#200772',
offset: 1,
}
]});
canvas.backgroundColor = grad.toLive(canvas.contextContainer);
canvas.renderAll();
canvas.calcOffset();

you can also study it from here
https://copyprogramming.com/howto/background-gradient-in-fabric-js

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

Successfully merging a pull request may close this issue.

7 participants