Chrome Canvas Linear Gradient != Firefox Canvas Linear Gradient - firefox

Well , the problem is the next :
canvas = GreenCanvas.get(0).getContext('2d');
grad = canvas.createLinearGradient(0,0,255,0);
grad.addColorStop(0, 'rgb('+r+','+0+','+b+')');
grad.addColorStop(1, 'rgb('+r+','+255+','+b+')');
canvas.fillStyle = grad;
canvas.fillRect(0,0,256,34);
256 pixels . from for example rgb(0,0,0) to rgb(0,255,0)
Chrome 6.0.472: gradient (0,0,0) (0,1,0) (0,2,0) (0,3,0) (0,4,0) ... (0,255,0)
Firefox 3.6.6: gradient (0,0,0) (0,0,0) (0,1,0) (0,2,0) ... (0,255,0)
i would like to see who programs that gradient function in firefox . But anyway , i would like to know if its a real problem , or is that in firefox the gradient is done that manner. Or if it exist another manner to do a well done gradient without using too much memory.

It's known that Chrome has problems with the Canvas gradients at the moment.
I submitted a bug to Chromium because of how many of hixie's (the specification writer) tests were failing on Chrome.
In short, you can't make your 'grad' variable. You have to set it directly.
This works:
var context = document.getElementsByTagName('canvas')[0].getContext('2d');
context.fillStyle = context.createLinearGradient(0, 0, 500, 300);
context.fillStyle.addColorStop(0, '#0000ff');
context.fillStyle.addColorStop(1, '#ff00ff');
context.fillRect(0, 0, 500, 300);
This does NOT work, even though they are SUPPOSED to do the same thing:
var context = document.getElementsByTagName('canvas')[0].getContext('2d');
var g = context.createLinearGradient(0, 0, 500, 300);
g.addColorStop(0, '#0000ff');
g.addColorStop(1, '#ff00ff');
context.fillStyle = g;
context.fillRect(0, 0, 500, 300);
For now, just do it the first way.
Here's the filed bug report from early September.
http://code.google.com/p/chromium/issues/detail?id=54070&can=4&colspec=ID%20Stars%20Pri%20Area%20Feature%20Type%20Status%20Summary%20Modified%20Owner%20Mstone%20OS

Related

jCanvas method drawRect() position issue

I have a problem with jCanvas which is a framework drawing canvas and jquery.
When I set x = 0 , y = 0 The .drawRect output should be same as the pure javascript result.
I tried the document and google but I did not find anything to solve this.
Screen shoot:
Pure js result
jCanvas result
Please help me.
Many thanks.
// Pure javascript
var canvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas.getContext("2d");
ctx.fillStyle = 'blue';
ctx.fillRect(0, 0, 100, 100);
// jCanvas
$('canvas').drawRect({
fillStyle: '#000',
x: 0, y: 0,
width: 100,
height: 100
});
To run this code, please copy and pass to this sanbox.
https://projects.calebevans.me/jcanvas/sandbox/
From jCanvas documentation:
The [.drawRect's] fromCenter property determines if a rectangle’s x and y properties lie at its center (as opposed to its top-left corner). This property is true by default.
So yeah. Your X and Y with jCanvas, refer to the center of the rectangle, unlike canvas' fillRect X and Y, which refer to the top left corner of the rectangle.

Processing rect() causes image to be draw instead of rectangle?

In my game there are enemies wandering around, their draw() method is simple:
core.displayBuffer is a PGraphics object that is draw onto the screen at the end of draw().
if(facingRight) {
core.displayBuffer.image(image,
x, y + offsetY, 80, 80);
} else {
float tX = -core.camera.x+core.game.width/2f + x;
float tY = -core.camera.y+core.game.height/2f+ y;
core.displayBuffer.pushMatrix();
core.displayBuffer.translate(core.camera.x-core.game.width/2f,
core.camera.y-core.game.height/2f);
core.displayBuffer.translate(tX, tY);
core.displayBuffer.scale(-1, 1);
core.displayBuffer.image(image,
-80, offsetY, 80, 80);
core.displayBuffer.popMatrix();
}
Then when we are going to draw walls, we just draw a coloured rectangle like this:
core.displayBuffer.noStroke();
if(destroyed) {
core.displayBuffer.fill(0, 0, 0, 16);
core.displayBuffer.rect(x, y, w, h);
} else {
core.displayBuffer.fill(64);
core.displayBuffer.rect(x, y - WALL_HEIGHT, w, h);
core.displayBuffer.fill(32);
core.displayBuffer.rect(x, y + h - WALL_HEIGHT, w, WALL_HEIGHT);
}
But for some reason, the walls have the texture of the enemies? Here's the loop in which the objects are drawn:
PMatrix displayMatrix = displayBuffer.getMatrix();
PMatrix bloomMatrix = bloomLayer.getMatrix();
PStyle displayStyle = displayBuffer.getStyle();
PStyle bloomStyle = bloomLayer.getStyle();
onScreenObjects.forEach(o -> {
displayBuffer.setMatrix(displayMatrix);
bloomLayer.setMatrix(bloomMatrix);
displayBuffer.style(displayStyle);
bloomLayer.style(bloomStyle);
o.draw(this);
});
displayBuffer.setMatrix(displayMatrix);
bloomLayer.setMatrix(bloomMatrix);
displayBuffer.style(displayStyle);
bloomLayer.style(bloomStyle);
Here's example of the results, red rectangles are around the walls, that are drawn incorrectly.
Also the bullets are flickering for some reason? These 2 bugs don't appear when I don't draw the enemies onto the screen (or I draw just rectangles instead), so that means, that the image() is doing something weird in the background?
Project's source code is at https://github.com/Matrx007/TheLostBits
Ask for additional info if needed!
Nvidia Quadro 4000.
Graphics card driver is from 2016, can't upgrade it, all other games are working fine tho.
Processing version: 3.5.3 (Library)
Operating System and OS version: Windows 10 build 17134
Possible Causes / Solutions:
Maybe that the image() manipulates the current texture being used and rect() uses the texture?
SOLVED
The solution was, that Processing can't draw onto more than one PGraphics at a time. I had beginDraw() called on two PGraphics and I was drawing to both of them at the same time, now I separated them, and the bug is gone! Better explanation here: https://github.com/processing/processing/issues/5863

How to make the blend mode MULTIPLY not make all the image black in p5js

I have this codepen: https://codepen.io/giorgiomartini/pen/OjQpKd?editors=0010
Where I paint some shapes and some text, now I want to add a radial overlay between the shapes and the text.
So I created a drawgradient function and call it between the shapes and the text:
function drawGradient() {
blendMode(MULTIPLY)
for (let r = canvasX; r > 0; --r) {
let lightnes = map(r,0,canvasX,255,0)
fill(0, 0, lightnes)
ellipse(0, 0, r*1.8, r*2)
}
}
I want this gradient to have a multiply blend mode, so that it makes the whole thing a bit darker where the pixels are darker in the gradient.
But all i get is a full black overlay...
In photoshop or gimp, if you add a black and white radial gradient with a multiply blend mode it makes the background darker where there are darker pixles in the gradient.. but here in p5js it just makes everything black.
any ideas what am I doing wrong?
This is the mouseClicked function, and at the bottom, you can see the gradient function being called:
function mouseClicked(){
blendMode(BLEND)
const colsArray = randomColor({luminosity: 'light', format: 'hsl',count: 4})
background(colsArray[0])
translate(width/2, height/2)
////////////////////////////////////////////////////////////////// amt initial range
const arrayOfRandomNumsOfFirstProbStepX = createArrayOfRandomNums(amtOfSpotsInFirstProb,startProbStep,firstProbStepX)
const arrayOfRandomNumsOfFirstProbStepY = createArrayOfRandomNums(amtOfSpotsInFirstProb,startProbStep,firstProbStepY)
const arrayOfRandomNumsOfSecondProbStepX = createArrayOfRandomNums(amtOfSpotsInSecondProb,startProbStep,secondProbStepX)
const arrayOfRandomNumsOfSecondProbStepY = createArrayOfRandomNums(amtOfSpotsInSecondProb,startProbStep,secondProbStepY)
drawLinesAtRandomspots(6,random(50),colsArray)
//args => element, arrayOfRandomNumsOfProbStepX, arrayOfRandomNumsOfProbStepY, elmntSizeMin, elmntSizeMax,rot, colors
drawElmntsOnSomeProbabilityStep('ellipse',arrayOfRandomNumsOfFirstProbStepX, arrayOfRandomNumsOfFirstProbStepY , 10, 80, true, colsArray )
drawElmntsOnSomeProbabilityStep('rect',arrayOfRandomNumsOfSecondProbStepX, arrayOfRandomNumsOfSecondProbStepY, 5, 30, true, colsArray)
drawGradient()
addText()
}
Placing clear() at the beginning of the draw() function will clear the pixels within a buffer. This lets you use blendMode(MULTIPLY) without your overlapping shapes turning black after the first few frames.
If the effect you're going for is a linear gradient, it seems a little weird that you're drawing a bunch of ellipses to the screen.
ellipse(0, 0, r*1.8, r*2)
What do you expect this line to do?
Instead, I would think it would make more sense if you would draw a series of lines, a little bit darker or lighter each time. Here's an example:
function drawGradient() {
blendMode(MULTIPLY);
for (let lineX = 0; lineX < width; lineX++) {
let lightness = map(lineX, 0, width, 0, 255);
stroke(0, lightness)
line(lineX, 0, lineX, height)
}
}
This creates a horizontal gradient that fades from light to dark.
Edit: If you want a radial gradient, right now you're drawing a ton of dark circles on top of each other, so they're "stacking" to just become entirely black. You need to do a combination of drawing fewer circles (every 10 pixels instead of every 1 pixel, for example) and drawing them lighter. Here's an example:
function drawGradient() {
blendMode(MULTIPLY);
for (let r = 600; r > 0; r-=10) {
let lightness = map(r, 0, 600, 20, 0);
fill(0, lightness);
noStroke();
ellipse(0, 0, r, r);
}
}
This code draws circles every 10 pixels, and the darkest circle has an alpha of 20 instead of 255. This causes a much lighter gradient. You'll have to play with the exact values to get the effect you're going for.
If you have a follow-up question, please post a MCVE instead of your whole project. Just a couple of hard-coded shapes and a single gradient function would be enough, as long as we can run it. As of now your code is a little hard to debug because it contains a bunch of stuff not directly related to the problem. Good luck.

Raphael playground effect and fill opacity

I've written the following code:
var w = 800;
var h = 600;
var paper = Raphael(0, 0, w, h);
paper.image("http://static.pourfemme.it/pfmoda/fotogallery/625X0/63617/borsa-alviero-martini-rodeo-drive.jpg", 0, 0, w, h);
var c = paper.circle(400, 300, 1);
c.attr({stroke: "#999", "stroke-width": w*2});
anim = Raphael.animation({r: w*2}, 6000);
c.animate(anim.delay(100));
( http://jsfiddle.net/qAgy7/ )
I need to visualize background image when the circle enlarges its radius, however I have the following problems:
I don't understand why the animation run slowly
Chrome render the effect in different way (I see a polygon not a circle like in
Firefox and IE)
Someone can help me?

How do I get rid of default opacity in HTML5 canvas?

I am trying to draw 2 black lines in HTML5 canvas:
JSFiddle: http://jsfiddle.net/KFNt5/
Javascript:
var canvas = document.createElement('canvas');
canvas.height = 150;
canvas.width = 150;
var canvasContext = canvas.getContext('2d');
canvasContext.beginPath();
// Draw the red line.
canvasContext.strokeStyle = '#000';
canvasContext.moveTo(10, 0);
canvasContext.lineTo(10, 100);
canvasContext.stroke();
// Draw the green line.
canvasContext.moveTo(50, 0);
canvasContext.lineTo(50, 100);
canvasContext.stroke();
document.body.appendChild(canvas);​
However, the line to the right is gray, implying that it is semitransparent. How do I ensure that the default opacity is 100 (not transparent at all)?
The second line is lighter due to anti-aliasing. You can include the following line to ensure that you render each line once and avoid the anti-aliasing effect.
canvasContext.translate(0.5, 0.5);
http://jsfiddle.net/bagWQ/
Your first line is darker because you drew it twice, once for each call to stroke(). The second call to stroke() draws both lines because you didn't start a new path.

Resources