I'm using the p5 library so functions like fill() rect() ellipse() but is there a way to change the opacity of a shape so even if I fill() it I can still see the shapes behind it?
You need to fill the shape with a transparent color. The fill() color can be specified in many different ways. For instance with the 3 color channels (red, green, blue) and the alpha channel.
e.g.: Red color 50% transparency
fill(255, 0, 0, 127);
Refer to the fill documentation for all of the different options.
I'm not certain if you're creating color variables, but using setAlpha could help to adjust the alpha value only as needed. If you just need to set the alpha when you set the color, Rabbid76's answer will do just fine.
Below is an example borrowed from the setAlpha reference page.
var squareColor;
function setup() {
createCanvas(400, 400);
// assign our color variable to change the alpha later
squareColor = color(100, 50, 100);
}
function draw() {
clear();
background(200);
// In the default RGB mode the transparency (alpha) value range is between 0 and 255
squareColor.setAlpha(128 + 128 * sin(millis() / 1000));
fill(squareColor);
rect(20, 20, 60, 60);
}
<script src="https://cdn.jsdelivr.net/npm/p5#1.4.0/lib/p5.min.js"></script>
What you have to do is give the shapes a transparent color, so then you can see behind the shapes.
background(220);
// The color of the first Shape
// The first parameter is the redness, the second is the greenness, the third is the blueness, and the fourth parameter is called "Alpha" which determines the transparency
fill(255,0,0,50);
// The first Shape
circle(200,200,200);
// The color of the second Shape
fill(0,255,0,50);
// The second shape
circle(200,200,150)
If what you're asking is just to see the outline of the shapes, you can simply draw the smaller shapes on the canvas AFTER you draw the larger shapes. Nonetheless, I would recommend reading this article.
Related
I am constructing a radial gradient filled circle in easelJS for a javascript canvas animation:
const blur1 = new createjs.Shape();
const endColor = this.hexToRGBA(data.settings.startColor,0);
blur1.circleCmd = blur1.graphics.beginRadialGradientFill([data.settings.startColor,endColor], [.25, .9], 0, 0, 0, 0, 0, 50).command;
blur1.graphics.drawCircle(0,0,50);
I am using the command function so that I can later update that fill.
In a request animation frame, I'd like to be able to say update the fill of this circle to the current color - a color value I'm tweening. So I have:
thisBlur1.circleCmd.style.props.colors[0] = curColor;
thisBlur1.circleCmd.style.props.colors[1] = this.hexToRGBA(curColor,0);
I see that it sets the properties of the circle properly, but it doesn't update the color on the screen, so I'm guessing that the style.props.colors array is read-only? Or maybe I need to just completely redraw the circle each frame? I'd like to avoid that, as there are a number of other properties which can change at any frame for this circle.
How do I update the gradient fill of a circle in easelJS?
Your approach is pretty close. You can't modify gradient properties directly due to how the Canvas creates gradients. Instead, call the radialGradient function on your fill command:
thisBlur1.circleCmd.radialGradient([...newColors], [.25, .9], 0, 0, 0, 0, 0, 5);
I recently answered a question about tweening gradients, which you can read here: How to animate an EaselJS gradient using TweenJS?
I'm trying to overlay this black rectangle:
By filling another rectangle of the same size on top of it that has a semi-transparent, gradient paint (should look something like this):
I know I can do a transparent paint with the following:
g2d.fillStyle = "rgba(100, 3, 3, 0.5)";
I also know how to do a gradient paint:
var grd=g2d.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"blue");
g2d.fillStyle=grd;
However, I do not know how to combine both the gradient and transparency properties together as one paint to use on my rectangle. How can I do this?
There are two ways:
Global alpha
Set global (consider it a "master alpha") right before drawing something:
ctx.globalAlpha = 0.5; // [0, 1]
ctx.fillRect( ... );
Color alpha
Or define the colors themselves with alphas:
grd.addColorStop(0, "rgba(255,0,0, 0.5)"); // 50% alpha
grd.addColorStop(1, "rgba(0,0,255, 0.5)");
Worth to notice: if you use the latter approach and for example set 0% opacity on one end, the color will still matter as it is interpolated to the point where it becomes fully transparent. In the meanwhile the color definition will bleed through. I.e. don't just set black (unless black is what you need).
First draw the gradient:
var grd=g2d.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"blue");
g2d.fillStyle=grd;
Then draw the semi-transparent background:
g2d.fillStyle = "rgba(200,0,0,0.5)";
g2d.fillRect(x,y,w,h);
I want to implement a clothing design website, but I'm encountering a problem.
I have 1 image shirt, 1 image cloth. I draw shirt to canvas. Now, I want to change cloth shirt by image cloth. But I do not know how to do it.
Example: http://sbhvietnam.vn/shirt-by-hand.html
You can use composite modes to achieve this. Provided the images are loaded and the background behind the image is transparent, and you have set up canvas and context (here ctx) you could do something like this:
/// clear if you reuse this method to avoid pixelated outline
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
/// draw shirt shape
ctx.drawImage(imgShirt, 0, 0);
/// change composite mode for next draw
ctx.globalCompositeOperation = 'source-atop'; /// source-in is an option
/// draw cloth image on top and it will take the shape of the shirt image.
ctx.drawImage(imgCloth, 0, 0);
/// reset composite mode to default mode
ctx.globalCompositeOperation = 'source-over';
Notice that if you should choose to use source-in instead of source-atop you will have to redraw imgShirt every time you want to change the image on top of it.
You can wrap it up in a function you call each time you need to redraw the cloth.
using flotchart.org , I would like to substitute the default 'circle' shape to represent a point, with just a similar circle, but filled with the color of the series; by example, with color "red" associated to a certain series:
the symbol I would like to represent is, using HTML5 canvas API:
var ctx=c.getContext("2d");ctx.beginPath(); ctx.arc(100,75,3,0,2*Math.PI); ctx.fillStyle="red"; ctx.fill();
But I can't obtain the result, coding what suggested by flotchart documentation.
As suggested in above doc, in options I wrote the custom function:
points: {
show: true,
radius: 2,
symbol:
function fullCircle(ctx, x, y, radius, shadow) {
ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
ctx.fill();
},
The ctx.fill do not work as desired: the circle is filled with BLACK color and just after pointing, instead I would like to fill the circle with the color associated with the corresponding series, before focusing the point...
sorry for my ignorance about canvas ctx...
there is a combination of flot settings to draw filled circles (discs) to represent series points
quoted from the documentation https://github.com/flot/flot/blob/master/API.md
"fill" is whether the shape should be filled. For lines, this produces
area graphs. You can use "fillColor" to specify the color of the fill.
If "fillColor" evaluates to false (default for everything except
points which are filled with white), the fill color is auto-set to the
color of the data series. You can adjust the opacity of the fill by
setting "fill" to a number between 0 (fully transparent) and 1 (fully
opaque).
so you simply set series.points.fillColor option to false (to use series color, or to whatever color you like).
and series.points.fill to 1 for full opacity. Just play around with the fiddle.
Here is the JsFiddle.
I'm trying to figure out why drawing a shape, then drawing over it in a new color (as though to highlight it), and then re-drawing the original (un-highlighting it) is leaving traces of the highlighted color.
I've reproduced the issue in this fiddle. The wedge is drawn in a light-blue color. There's a red button that'll draw over it in red, then another button that re-draws the original shape. All parameters are identical (except for the color), but yet after clicking the button to reset the color, there's a faint trace of red over the wedge.
Before:
After:
Here's the relevant code:
drawWedge(250, 250, 200, 0, 18, "rgb(150, 254, 223)");
$("#red").click(function () {
drawWedge(250, 250, 200, 0, 18, "rgb(255, 0, 0)");
});
$("#back").click(function () {
drawWedge(250, 250, 200, 0, 18, "rgb(150, 254, 223)");
});
function d2r(degrees) {
return degrees * (Math.PI / 180.0);
}
function drawWedge(centerX, centerY, r, start, end, color) {
context.beginPath();
context.moveTo(centerX, centerY);
context.arc(centerX, centerY, r, d2r(start), d2r(end), false);
context.closePath();
context.fillStyle = color;
context.fill();
}
This question was already answered, but I wanted to give a little more thorough explanation.
When you draw at a diagonal, your passing through "parts" of pixels (show in my example). So what does the browser do to the part of the pixel outside of the shape? It uses anti-aliasing (anti-aliasing is always on by default for browsers) to color the rest of the pixel (if you didnt have anti-aliasing the line would look jagged). If you notice, the faint trace of red is not a bright red because its getting blended due to anti-aliasing. And the reason you see it is because when you draw your shape on the canvas, the faint trace of red is not part of your shape, its part of the pixel on the outside of your shape.
Now as the answer mentioned, you can call clearRect to clear the canvas. However, you should read this SO question as it explains things in more detail (the selected answer is not as good as the second answer). Also, ever wonder why they call it a "canvas"? Think of an actual art canvas used by artists, once they paint on the canvas there is no way to take it off unless you get a new canvas or paint over it!
When drawing on canvas, it just keeps stacking things on top of each other until you clear it. The easiest way to clear it is ctx.clearRect(0,0,width,height)
I put that in your drawWedge function here:
http://jsfiddle.net/X7deh/1