HTML5 Canvas, shadowColor & shadowBlur - html

My question is regarding this shadowBlur feature used on the 2nd (outer) rectangle below. The shadowBlur feature is applied to every shape after this rectangle. (If you comment out the shadowColor and shadowBlur lines 21 & 22, and then uncomment the shadowColor and shadowBlur lines on lines 14 & 15, you should see what I mean.) My question is, how do I apply shadowBlur to one specific portion of the Canvas drawing without applying the feature to every succeeding portion of the Canvas. In this example I have tried creating separate variable for each canvas and context, but the problem still persists.
Attribution: These examples are based on examples from html5canvastutorials.com
<!DOCTYPE html>
<html lang="en"
<head>
<script type="text/javascript">
function addRect(){
var canvas1=document.getElementById("myCanvas");
var ctx=canvas1.getContext("2d");
var canvas3=document.getElementById("myCanvas");
var ctx3=canvas3.getContext("2d");
ctx.rect(60,60,180,80);
ctx.fillStyle="green";
//ctx.shadowColor="black";
//ctx.shadowBlur = 10;
ctx.fill();
ctx3.lineWidth = 3;
ctx3.strokeStyle='red';
ctx3.shadowColor="black";
ctx3.shadowBlur = 10;
ctx3.strokeRect(45,45,210,110);
}
function addOval(){
var canvas2=document.getElementById("myCanvas");
var context=canvas2.getContext("2d");
// define center of oval
var centerX = 288;
var centerY = 250;
// define size of oval
var height = 100;
var width = 250;
var controlRectWidth = width * 1.33;
context.beginPath();
context.moveTo(centerX,centerY - height/2);
// draw left side of oval
context.bezierCurveTo(centerX-controlRectWidth/2,centerY-height/2,
centerX-controlRectWidth/2,centerY+height/2,
centerX,centerY+height/2);
// draw right side of oval
context.bezierCurveTo(centerX+controlRectWidth/2,centerY+height/2,
centerX+controlRectWidth/2,centerY-height/2,
centerX,centerY-height/2);
context.fillStyle="red";
context.fill();
context.lineWidth=5;
context.strokeStyle="blue";
context.stroke();
context.closePath();
}
</script>
</head>
<body onload="addRect(); addOval();">
<canvas id="myCanvas" width="700" height="400">
Your browser does not support the canvas element.
</canvas>
</body>
</html>

Use either this:
ctx.save();
ctx.shadowColor="black";
ctx.shadowBlur = 10;
ctx.strokeRect(45,45,210,110);
ctx.restore();
Or this:
ctx.shadowColor="black";
ctx.shadowBlur = 10;
ctx.strokeRect(45,45,210,110);
ctx.shadowColor= undefined;
ctx.shadowBlur = undefined;
I am not sure about 'undefined' in second case - something to nullify/reset the value.

var canvas3=document.getElementById("myCanvas");
var ctx3=canvas1.getContext("2d");
change canvas1 to canvas3 in the second line. Your ctx3 is actually pointing to canvas1 which i think is wrong.

You can also consider setting the shadow color to "transparent" instead of undefined or null. This also seems to do the trick.

Related

HTML5 Canvas image resize on Chrome & easeljs

I'm struggling to make smooth image resized in canvas in Chrome. In firefox it works well, but in Chrome I'm stuck on making it smooth.
Here is the jsfiddle
http://jsfiddle.net/flashmandv/oxtrypmy/
var AVATAR_SIZE = 100;
var WHITE_BORDER_SIZE = 3;
var stage = new createjs.Stage("canvas");
var avCont = new createjs.Container();
stage.addChild(avCont);
avCont.x = avCont.y = 20;
//add white circle
var whiteBorderCircle = new createjs.Shape();
var radius = (AVATAR_SIZE+WHITE_BORDER_SIZE*2)/2;
whiteBorderCircle.graphics.beginFill("white").drawCircle(radius, radius, radius);
avCont.addChild(whiteBorderCircle);
//add avatar image mask
var avatarMask = new createjs.Shape();
avatarMask.graphics.beginFill("red").drawCircle(AVATAR_SIZE/2+WHITE_BORDER_SIZE, AVATAR_SIZE/2+WHITE_BORDER_SIZE, AVATAR_SIZE/2);
//add avatar image
var image = new Image();
image.onload = function(){
var bitmap = new createjs.Bitmap(image);
bitmap.mask = avatarMask;
var bounds = bitmap.getBounds();
bitmap.scaleX = (AVATAR_SIZE+WHITE_BORDER_SIZE*2) / bounds.width;
bitmap.scaleY = (AVATAR_SIZE+WHITE_BORDER_SIZE*2) / bounds.height;
avCont.addChild(bitmap);
stage.update();
};
image.src = 'http://files.sharenator.com/sunflowers-s800x800-423444.jpg';
Notice the jagged image
Please help
It is due to how clipping works in Chrome. Clip masks are pretty brutal in Chrome while in Firefox you get anti-aliasing along the non-straight edges.
Here is a proof-of-concept for this (run this in Chrome and in FF to see the difference):
http://jsfiddle.net/r65fcqoy/
The only way to get around this is to use composite modes instead, which basically means you need to rewrite your code unless the library you're using support this in some way.
One use of a composite mode is to use it to fill anything inside an existing drawing on the canvas.
We'll first create the filled circle we want the image to appear inside
Change comp mode to source-in and draw image
Then we go back to normal comp mode and draw the outer border
Here is an approach using vanilla JavaScript where you can control how you plug things together - this is maybe not what you're after but there is really not much option if the library as said doesn't support comp mode instead of clipping:
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
img = new Image,
x = 70, y =70;
var AVATAR_SIZE = 100;
var WHITE_BORDER_SIZE = 3;
var radius = (AVATAR_SIZE+WHITE_BORDER_SIZE*2)/2;
img.onload = function() {
// first draw the circle for the inner image:
ctx.arc(x, y, AVATAR_SIZE*0.5, 0 , 2*Math.PI);
ctx.fill();
// now, change composite mode:
ctx.globalCompositeOperation = 'source-in';
// draw image in top
ctx.drawImage(img, x-AVATAR_SIZE*0.5, y-AVATAR_SIZE*0.5,
AVATAR_SIZE, AVATAR_SIZE);
// change back composite mode to default:
ctx.globalCompositeOperation = 'source-over';
// now draw border
ctx.beginPath();
ctx.arc(x, y, radius + 5, 0, 2*Math.PI);
ctx.closePath();
ctx.lineWidth = 10;
ctx.strokeStyle = '#ffa94e';
ctx.stroke();
};
img.src = 'http://i.stack.imgur.com/PB8lN.jpg';
<canvas id=canvas width=500 height=180></canvas>
Another solution to this would be in onload function to add another shape above the masked image to simply cover the jagged edges of the clipping mask

How to draw on canvas on mousedown?

I am looking to simply add a dot to the canvas.
I have the following code:
var canv = document.getElementById("myCanvas");
var context = canv.getContext("2d");
var radius = 5;
var putPoint = function(e){
context.beginPath();
context.arc(e.clientX, e.clientY, radius, 0, Math.PI*2);
context.fill();
}
canv.addEventListener('mousedown', putPoint);
I was learning how to do this with a video tutorial. However they were setting the canvas
as the full width/height of the browser window, whereas my canvas is on 400px * 400px and is contained within a div. I think this is the problem.
So my question is are the "e.client" parameters not working because of my canvas being only
a small part of the window?
If so, how can I track the mouse co-ordinates on my canvas?
You must adjust e.clientX/e.clientY by the offset of the canvas element.
Otherwise you're miscalculating the position of your mouse and your dot is probably being drawn outside the bounds of your canvas.
Here's your code modified to take the canvas offset into account.
var putPoint = function(e){
var BB=canvas.getBoundingClientRect();
var offsetX=BB.left;
var offsetY=BB.top;
var mouseX=e.clientX-BB.left;
var mouseY=e.clientY-BB.top;
context.beginPath();
context.arc(mouseX,mouseY,radius,0,Math.PI*2);
context.fill();
}

is mouse in user drawn area on canvas

Basically, a user uploads a picture and then can paint on it, and save the result. Another user can then view the photo and if they click in the same area as painted, something happens.
So user 1 can make an area click-able for user 2 by drawing on the photo.
now the upload bit is fine, and painting with help from a tutorial and example I've got sussed out. But defining what area is click-able is a bit harder. For something like a rectangle its easy enough, I made an example.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var button = new Object();
button.x = 50;
button.y = 50;
button.width = 50;
button.height = 50;
button.rgb = "rgb(0, 0, 255)";
function drawbutton(buttonobject)
{
context.fillStyle = buttonobject.rgb;
context.fillRect (buttonobject.x, buttonobject.y, buttonobject.width, buttonobject.height);
context.strokeRect(buttonobject.x, buttonobject.y, buttonobject.width, buttonobject.height);
}
drawbutton(button);
function checkIfInsideButtonCoordinates(buttonObj, mouseX, mouseY)
{
if(((mouseX > buttonObj.x) && (mouseX < (buttonObj.x + buttonObj.width))) && ((mouseY > buttonObj.y) && (mouseY < (buttonObj.y + buttonObj.height))))
return true;
else
return false;
}
$("#myCanvas").click(function(eventObject) {
mouseX = eventObject.pageX - this.offsetLeft;
mouseY = eventObject.pageY - this.offsetTop;
if(checkIfInsideButtonCoordinates(button, mouseX, mouseY))
{
button.rgb = "rgb(0, 255, 0)";
drawbutton(button);
} else {
button.rgb = "rgb(255, 0, 0)";
drawbutton(button);
}
});
but when it comes to other shapes like circles, or just someone smothering the page, how would you go about detecting that ?
one thought I had was using the edited layer, making it hidden, and detecting a pixel color of say blue, from here but that limits the color use of the photo and im not entirely sure how to implement it. any other ideas ?
EDIT:
I figured out circles after some tinkering, using Pythagoras theorem to see if mouse coordinates are smaller than the radius, but this assumes circle center of 0,0, so then offset mouse by circles actual center. example
function checkIfInsideButtonCoordinates(buttonObj, mouseX, mouseY) {
actualX = mouseX - buttonObj.x
actualY = mouseY - buttonObj.y
mousesqX = actualX * actualX
mousesqY = actualY * actualY
sqR = buttonObj.r * buttonObj.r
sqC = mousesqX + mousesqY
if (sqC < sqR) return true;
else return false;
}
Here’s how to test whether user#2 is inside user#1’s paintings
Create a second canvas used to hit-test whether user#2 is inside of user#1’s paintings.
The hit-test canvas is the same size as the drawing canvas, but it only contains user#1’s paintings…not the image.
When user#1 is painting, also draw their paintings on the hit canvas.
When user#1 is done painting, save all their paintings from the hit canvas.
You have at least 2 ways to save user#1’s paintings from the hit canvas:
Serialize all the canvas commands needed to recreate the shapes/paths that user#1 paints.
Save the hit canvas as an image using canvas.toDataURL.
When user#2 clicks, check if the corresponding pixel on the hit canvas is filled or is transparent (alpha>0).
// getImageData for the hit-test canvas (this canvas just contains user#1's paintings)
imageDataData=hitCtx.getImageData(0,0,hit.width,hit.height).data;
// look at the pixel under user#2's mouse
// return true if that pixel is filled (not transparent)
function isHit(x,y){
var pixPos=(x+y*hitWidth)*4+3;
return( imageDataData[pixPos]>10)
}
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/etA5a/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:15px; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var hit=document.getElementById("hit");
var hitCtx=hit.getContext("2d");
var user2=document.getElementById("user2");
var ctx2=user2.getContext("2d");
var canvasOffset=$("#user2").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var imageDataData;
var hitWidth=hit.width;
var img=document.createElement("img");
img.onload=function(){
// left canvas: image+user#1 paintings
ctx.globalAlpha=.25;
ctx.drawImage(img,0,0);
ctx.globalAlpha=1.00;
scribble(ctx,"black");
// mid canvas: just user#1 paintings (used for hittests)
scribble(hitCtx,"black");
// right canvas: user#2
ctx2.drawImage(img,0,0);
imageDataData=hitCtx.getImageData(0,0,hit.width,hit.height).data;
}
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";
function scribble(context,color){
context.beginPath();
context.moveTo(70,2);
context.lineTo(139,41);
context.lineTo(70,41);
context.closePath();
context.rect(39,54,22,30);
context.arc(73,115,3,0,Math.PI*2,false);
context.fillStyle=color;
context.fill();
}
function handleMouseMove(e){
var mouseX=parseInt(e.clientX-offsetX);
var mouseY=parseInt(e.clientY-offsetY);
// If user#2 has a hit on user#1's painting, mid-canvas turns red
var color="black";
if(isHit(mouseX,mouseY)){ color="red"; }
scribble(hitCtx,color);
}
function isHit(x,y){
var pixPos=(x+y*hitWidth)*4+3;
return( imageDataData[pixPos]>10)
}
$("#user2").mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
</script>
</head>
<body>
<p>Left: original image with user#1 painting</p>
<p>Mid: user#1 painting only (used for hit-testing)</p>
<p>Right: user#2 (move mouse over hit areas)</p>
<canvas id="canvas" width=140 height=140></canvas>
<canvas id="hit" width=140 height=140></canvas>
<canvas id="user2" width=140 height=140></canvas><br>
</body>
</html>

using globalCompositeOperation with lines?

I'm trying to make a clock with HTML 5's canvas element.
What i'm trying to do is make a line for every second, and then erase the previous line.
I want to erase the previous line with drawing another line using the globalCompositeOperation='xor'; but it doesn't work!
Here is the code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Clock</title>
</head>
<body onload="spin()">
<canvas id="myCanvas" width="578" height="400"></canvas>
<script>
var firstTime = 0;
var prevX=null;
var prevY=null;
function spin() {
//get the canvas element
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
//get the right angle for the clock hand
var date = new Date;
var seconds = date.getSeconds();
var a = seconds*6;
var angleRadian = a*Math.PI/180;
var angle = 1/2*Math.PI - angleRadian;
if(a > 360)
a = 0;
//Erase the previous line, if it has been drawn.
if(prevX!=null)
erasePrevLine(angle, canvas, context);
//draw line
drawLine(angle, 100, canvas, context);
//repeat for the next second
setTimeout(spin, 500);
}
function drawLine(angle, radius, canvas, context) {
var centerX = canvas.width/2;
var centerY = canvas.height/2;
var xTarget = centerX + Math.cos(angle)*radius;
var yTarget = centerY - Math.sin(angle)*radius;
//save this state to be erased
prevX = xTarget;
prevY = yTarget;
//draw
context.beginPath();
context.moveTo(centerX,centerY);
context.lineTo(xTarget, yTarget);
context.stroke();
}
function erasePrevLine(angle, canvas, context) {
context.globalCompositeOperation = 'xor';
var centerX = canvas.width/2;
var centerY = canvas.height/2;
prevAngle = angle + (Math.PI/180*6);
var xTarget = prevX;
var yTarget = prevY;
//draw on the previous line
context.beginPath();
context.moveTo(centerX,centerY);
context.lineTo(xTarget, yTarget );
context.stroke();
}
</script>
</body>
</html>
And here is the live example: http://jsfiddle.net/pyerT/1/
Anybody knows the answer? it works fine with shapes and texts..
globalCompositeOperation (xor) will not work on a rotating line like a “clock hand”….here’s why:
Assume you draw a vertical line. Then draw a second vertical line to the right of the first. Assume the second vertical line overlaps the first line by half.
Canvas.globalCompositeOperation=”xor” causes overlapping areas to be removed, so the second line removes half the first line and also half of itself.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/e24KU/
function drawLine(){
ctx.globalCompositeOperation="xor";
ctx.strokeStyle="red";
ctx.lineWidth=10;
ctx.beginPath();
ctx.moveTo(posX,10);
ctx.lineTo(posX,100);
ctx.stroke();
posX+=5;
}
This is a Fiddle of a “clock hand” sweeping around a centerpoint: http://jsfiddle.net/m1erickson/hW2EY/
However, if we try to use “xor” on a rotating line, the lines overlay at an angle and therefore the xor is incomplete.
Here is a Fiddle showing the line “xor” being ineffective when rotated: http://jsfiddle.net/m1erickson/f7hHx/
[Edited: new code was supplied by OP allowing for an expanded answer]
I looked at your new code and am suggesting some changes and optimizations.
As I said in my original answer, you cannot effectively erase a line that was drawn at an angle. This is due to anti-aliasing that the browser does automatically—antiAliasing for canvas cannot be turned off.
Here is a Fiddle of the results after the changes: http://jsfiddle.net/m1erickson/9QD65/
Changes:
Believe it or not: It is usual to completely erase and completely redraw the canvas during each animation loop! Canvas really is quick enough to handle these redraws—especially now that canvas is GPU accelerated. If you absolutely need to optimize your performance, you can define “dirty” areas of the canvas that must be erased/redrawn and leave the other areas as previously drawn. In practice, once you need this type of performance, your canvas is so complicated that it’s more efficient to completely clear/redraw than to try to define the dirty areas.
Optimizations:
Moved canvas,context,centerX,centerY out of the animation loop since these values can be computed once and reused.
Here is my suggested code for you to look at:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Clock</title>
</head>
<body onload="spin()">
<canvas id="myCanvas" width="578" height="400"></canvas>
<script>
var firstTime = 0;
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX=canvas.width/2;
var centerY=canvas.height/2;
var canvasWidth=canvas.width;
var canvasHeight=canvas.height;
function spin() {
//get the right angle for the clock hand
var date = new Date;
var seconds = date.getSeconds();
var a = seconds*6;
var angleRadian = a*Math.PI/180;
var angle = 1/2*Math.PI - angleRadian;
if(a > 360)
a = 0;
//draw line
drawLine(angle, 100, canvas, context, "black",1);
//repeat for the next second
setTimeout(spin, 500);
}
function drawLine(angle, radius, canvas, context) {
var xTarget = centerX + Math.cos(angle)*radius;
var yTarget = centerY - Math.sin(angle)*radius;
//clear the canvas
context.clearRect(0,0,canvasWidth,canvasHeight);
//draw
context.save();
context.beginPath();
context.moveTo(centerX,centerY);
context.lineTo(xTarget, yTarget);
context.stroke();
context.restore()
}
</script>
</body>
</html>

How to change the opacity (alpha, transparency) of an element in a canvas element?

Using the HTML5 <canvas> element, I would like to load an image file (PNG, JPEG, etc.), draw it to the canvas completely transparently, and then fade it in. I have figured out how to load the image and draw it to the canvas, but I don't know how to change its opacity.
Here's the code I have so far:
var canvas = document.getElementById('myCanvas');
if (canvas.getContext)
{
var c = canvas.getContext('2d');
c.globalAlpha = 0;
var img = new Image();
img.onload = function() {
c.drawImage(img, 0, 0);
}
img.src = 'image.jpg';
}
Will somebody please point me in the right direction like a property to set or a function to call that will change the opacity?
I am also looking for an answer to this question, (to clarify, I want to be able to draw an image with user defined opacity such as how you can draw shapes with opacity) if you draw with primitive shapes you can set fill and stroke color with alpha to define the transparency. As far as I have concluded right now, this does not seem to affect image drawing.
//works with shapes but not with images
ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
I have concluded that setting the globalCompositeOperation works with images.
//works with images
ctx.globalCompositeOperation = "lighter";
I wonder if there is some kind third way of setting color so that we can tint images and make them transparent easily.
EDIT:
After further digging I have concluded that you can set the transparency of an image by setting the globalAlpha parameter BEFORE you draw the image:
//works with images
ctx.globalAlpha = 0.5
If you want to achieve a fading effect over time you need some kind of loop that changes the alpha value, this is fairly easy, one way to achieve it is the setTimeout function, look that up to create a loop from which you alter the alpha over time.
Some simpler example code for using globalAlpha:
ctx.save();
ctx.globalAlpha = 0.4;
ctx.drawImage(img, x, y);
ctx.restore();
If you need img to be loaded:
var img = new Image();
img.onload = function() {
ctx.save();
ctx.globalAlpha = 0.4;
ctx.drawImage(img, x, y);
ctx.restore()
};
img.src = "http://...";
Notes:
Set the 'src' last, to guarantee that your onload handler is called on all platforms, even if the image is already in the cache.
Wrap changes to stuff like globalAlpha between a save and restore (in fact use them lots), to make sure you don't clobber settings from elsewhere, particularly when bits of drawing code are going to be called from events.
Edit: The answer marked as "correct" is not correct.
It's easy to do. Try this code, swapping out "ie.jpg" with whatever picture you have handy:
<!DOCTYPE HTML>
<html>
<head>
<script>
var canvas;
var context;
var ga = 0.0;
var timerId = 0;
function init()
{
canvas = document.getElementById("myCanvas");
context = canvas.getContext("2d");
timerId = setInterval("fadeIn()", 100);
}
function fadeIn()
{
context.clearRect(0,0, canvas.width,canvas.height);
context.globalAlpha = ga;
var ie = new Image();
ie.onload = function()
{
context.drawImage(ie, 0, 0, 100, 100);
};
ie.src = "ie.jpg";
ga = ga + 0.1;
if (ga > 1.0)
{
goingUp = false;
clearInterval(timerId);
}
}
</script>
</head>
<body onload="init()">
<canvas height="200" width="300" id="myCanvas"></canvas>
</body>
</html>
The key is the globalAlpha property.
Tested with IE 9, FF 5, Safari 5, and Chrome 12 on Win7.
This suggestion is based on pixel manipulation in canvas 2d context.
From MDN:
You can directly manipulate pixel data in canvases at the byte level
To manipulate pixels we'll use two functions here - getImageData and putImageData.
getImageData usage:
var myImageData = context.getImageData(left, top, width, height);
The putImageData syntax:
context.putImageData(myImageData, x, y);
Where context is your canvas 2d context, and x and y are the position on the canvas.
So to get red green blue and alpha values, we'll do the following:
var r = imageData.data[((x*(imageData.width*4)) + (y*4))];
var g = imageData.data[((x*(imageData.width*4)) + (y*4)) + 1];
var b = imageData.data[((x*(imageData.width*4)) + (y*4)) + 2];
var a = imageData.data[((x*(imageData.width*4)) + (y*4)) + 3];
Where x is the horizontal offset, y is the vertical offset.
The code making image half-transparent:
var canvas = document.getElementById('myCanvas');
var c = canvas.getContext('2d');
var img = new Image();
img.onload = function() {
c.drawImage(img, 0, 0);
var ImageData = c.getImageData(0,0,img.width,img.height);
for(var i=0;i<img.height;i++)
for(var j=0;j<img.width;j++)
ImageData.data[((i*(img.width*4)) + (j*4) + 3)] = 127;//opacity = 0.5 [0-255]
c.putImageData(ImageData,0,0);//put image data back
}
img.src = 'image.jpg';
You can make you own "shaders" - see full MDN article here
You can. Transparent canvas can be quickly faded by using destination-out global composite operation. It's not 100% perfect, sometimes it leaves some traces but it could be tweaked, depending what's needed (i.e. use 'source-over' and fill it with white color with alpha at 0.13, then fade to prepare the canvas).
// Fill canvas using 'destination-out' and alpha at 0.05
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = "rgba(255, 255, 255, 0.05)";
ctx.beginPath();
ctx.fillRect(0, 0, width, height);
ctx.fill();
// Set the default mode.
ctx.globalCompositeOperation = 'source-over';
I think this answers the question best, it actually changes the alpha value of something that has been drawn already. Maybe this wasn't part of the api when this question was asked.
Given 2d context c.
function reduceAlpha(x, y, w, h, dA) {
let screenData = c.getImageData(x, y, w, h);
for(let i = 3; i < screenData.data.length; i+=4){
screenData.data[i] -= dA; //delta-Alpha
}
c.putImageData(screenData, x, y );
}
Set global Alpha draw the object that has opacity then set back to normal.
//////////////////////// circle ///////////////////////
ctx.globalAlpha = 0.75;
ctx.beginPath();
ctx.arc(x1, y1, r1, 0, Math.PI*2);
ctx.fillStyle = colour;
ctx.fill();
ctx.closePath();
ctx.globalAlpha = 1;
How i made it..on canvas i first draw rect in a selfrun function 0,0,canvas.width,canvas.height as a background of canvas and i set globalAlpha to 1 .then i draw other shapes in ather own functions and set their globalAlpha to 0.whatever number they dont affect each other even images.
Like Ian said, use c.globalAlpha = 0.5 to set the opacity, type up the rest of the settings for the square, then follow up with c.save();. This will save the settings for the square then you can c.rect and c.fillStyle the square how you want it. I chose not to wrap it with c.restore afterwards and it worked well
If you use jCanvas library you can use opacity property when drawing. If you need fade effect on top of that, simply redraw with different values.
You can't. It's immediate mode graphics. But you can sort of simulate it by drawing a rectangle over it in the background color with an opacity.
If the image is over something other than a constant color, then it gets quite a bit trickier. You should be able to use the pixel manipulation methods in this case. Just save the area before drawing the image, and then blend that back on top with an opacity afterwards.