How to draw transparent image with html5 canvas element - javascript

I am targeting google chrome. Is it possible to draw transparent images on a canvas? By transparent I mean the drawing the entire image at something like 50% opacity.

You can do this using the globalAlpha property, like this:
<!DOCTYPE HTML>
<html>
<body>
<canvas height="100" width="100" id="myCanvas"></canvas>
<script>
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.globalAlpha = 0.5;
var myImage = new Image();
myImage.src = "someImage.jpg";
myImage.onload = function()
{
context.drawImage(myImage, 0, 0, 100, 100);
};
</script>
</body>
</html>
And yes, it does work with images. Verified with IE 9, FF 5, Safari 5, and Chrome 12 on Win 7.

The canvas element has a global alpha attribute that lets you apply partial transparency to anything you draw.

It's possible if you iterate thru the canvas' image-data and set the alpha value manually, then export the transparent image with the canvas.toDataURL method and insert it into another canvas.

Related

How to scale x and y coordinates of a span over an image as the image resizes?

I threw together a quick fiddle of what I'm talking about: https://jsfiddle.net/4zokey2f/1/.
Notice if you drag the corner of your browser the image changes size but the span (red box over the tent) does not stay over the tent as the image is resizing. It's worth noting that in my problem I'm passing the x and y values inline like style={left: this.state.xValue, top: this.state.yValue} (it's a react component so those are just stored in local state).
I have the original image size that the initial x and y are calculated from, I just don't know the proper way to scale them with the image resize?
Thanks!
I have the same issue before when I was working on my friend's school project. What I do is center the background-position (vertical & horizontal) for both elements, like in your case the figure & span. Once both are centered, I use vw & vh to adjust the message box. You can check this updated fiddle of yours https://jsfiddle.net/4zokey2f/2/ also, I add min-width & max-width on the holder/container, just to add some boundaries or limits. Hope this helps.
I'd probably try to use something like canvas or svg to generate the image on the fly.
Canvas example:
<img id="parados"
src="http://www.thatdrop.com/wp-content/uploads/2017/03/parados-700x694.jpg"
alt="The Scream" style="display: none">
<canvas id="myCanvas" width="700" height="694"
style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
window.onload = function() {
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var img = document.getElementById("parados");
ctx.drawImage(img,0,0);
ctx.fillStyle = "#FF0000";
ctx.fillRect(650,500,50,50);
ctx.fillStyle = "black";
ctx.font = "30px Arial";
ctx.fillText("1",660,540);
};
</script>
<style>
canvas {
width: 100%
}
</style>
jsfiddle: https://jsfiddle.net/PantsStatusZero/2g612hLn/1/

HTML5 canvas clip() doesn't work in Chrome when rotation is applied

I'm trying to use a clip region on a canvas and it stops working as soon as the coordinate system is rotated by any non zero value:
window.onload = function() {
var canvas = document.getElementById("mainCanvas");
var ctx = canvas.getContext("2d");
ctx.rotate(Math.PI / 8); // !!! Clipping doesn't work with any non zero value
ctx.beginPath();
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.stroke();
ctx.clip(); // !!! Image below is invisible in Chrome when clip() is enabled
var objectImage = document.getElementById("test");
ctx.drawImage(objectImage, 0, 0);
}
<canvas id="mainCanvas" width="320" height="240" style = "border:1px solid #d3d3d3;"></canvas>
<img id="test" width="0" height="0" src="https://dl.dropboxusercontent.com/u/4111969/test.png">
The code works fine in Firefox:
But in Chrome the image inside the rectangle is empty:
Translate and scale transformations seem to work fine, but not the rotate. Am I doing something wrong? If it's a bug in Chrome, is there a good workaround?
Edit:
My system is:
Chrome "Version 49.0.2623.87 m", Windows 7 Home Premium SP1, ASUS R7 250X graphics card. I can reproduce the problem every time.
I found that the problem goes away if I turn off hardware acceleration in the browser settings. As I understand this means there's probably a problem with my graphics card driver.
Is there a way for my webpage to force the software rendering in Chrome?
In Chrome, drawImage() is done before Image loaded, you have to check like this:
<!DOCTYPE HTML>
<html>
<script>
window.onload = function() {
var canvas = document.getElementById("mainCanvas");
var ctx = canvas.getContext("2d");
ctx.rotate(Math.PI / 8); // !!! Clipping doesn't work with any non zero value
ctx.beginPath();
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.stroke();
ctx.clip();
//Make sure the Image is loaded
var objectImage= new Image();
objectImage.src="https://dl.dropboxusercontent.com/u/4111969/test.png"
objectImage.onload =function()
{
ctx.drawImage(objectImage, 0, 0);
}
}
</script>
<body>
<img id="test" width="0" height="0" src="https://dl.dropboxusercontent.com/u/4111969/test.png">
<canvas id="mainCanvas" width="320" height="240" style = "border:1px solid #d3d3d3; margin:0; padding:0"></canvas>
</body>
</html>
The problem seems to be related to the browser hardware acceleration. Everything works fine as soon as I turn it off.
However, I don't know if it's possible for my web page to disable hardware acceleration.

CamanJS initialize on canvas with image (RETINA BUG)

EDITED:
It turned out it's a retina bug. Not replicable on other screens.
Referring Camanjs clear canvas when init Caman()? and posted there http://jsfiddle.net/m1erickson/R4kJM/ CamanJS should accept the canvas with data s argument. Ale documentation seemed to confirmed this fact. But somehow the fiddle is not working. The blue thing disappears once CamanJS initialize.
The code again:
http://jsfiddle.net/m1erickson/R4kJM/
HTML:
<canvas id="original" width=100 height=100></canvas>
JS:
var canvas = document.getElementById("original");
var ctx = canvas.getContext("2d");
// make a drawing on the original canvas
ctx.fillStyle = "blue";
ctx.fillRect(20, 20, 60, 40);
// modify the original drawing
Caman("#original", function () {
this.brightness(75).render();
});
It's the bug in CamanJS. The issue still and work around described here.
https://github.com/meltingice/CamanJS/issues/188

Faded image edges on canvas using getImageData

Using getImageData, I'm trying to create a radial fade effect on an image where point(0,0) has an alpha of 0 and point(img.width, img.height) has an alpha of 0.5 sort of like this:
(The last point has an alpha of 1.0, but imagine it's 0.5.)
I've been able to create a linear alpha increase in my for loop using
imgData.data[i+3]=i/imgData.length;
but the left edge (obviously) becomes more defined as the loop iterates.
I've tried using two loops, one to create row "breaks" in the array, and the other to handle the alpha manipulation like so:
for(var j=0;j<imgData.height;j++){
for(var i=0;i<imgData.data.length;i+=4){
imgData.data[i+3] = 0 + 125 * i/imgData.data.length;
}
}
but the performance of this is really slow and it doesn't achieve the fade that I'm looking for. I'm also not sure I'm doing that properly. I also tried Faster Canvas Pixel Manipulation with Typed Arrays as outlined on the Mozilla Hacks site, but the image wasn't even drawn to the canvas using that method. (I'm using Chrome - not sure if that's the issue or if it's my code.)
Any ideas?
EDIT: Thanks to markE for the great solution - it's beautifully quick. I mentioned this in my comment to him, but here's the full code for creating a greyscale image (part of my requirements) that has the fade pictured in mark's demo.
img_width = window.innerWidth/2.5;
img_height = img_width * (9/16);
//hidden_ctx is hidden behind a background layer
var g1=hidden_ctx.createRadialGradient(500,500,550,500,500,650);
g1.addColorStop(0.00,"rgba(0,0,0,0.7)");
g1.addColorStop(0.30,"rgba(0,0,0,0.35)");
g1.addColorStop(1.00,"rgba(0,0,0,0.00)");
hidden_ctx.fillStyle=g1;
hidden_ctx.fillRect(0, 0, img_width, img_height);
hidden_ctx.globalCompositeOperation="source-in";
//custom drawImage method where selected[num] contains
//contains images & metadata
drawIt(hidden_ctx, selected[num].image[0], 0, 0, img_width, img_height);
imgData=hidden_ctx.getImageData(0, 0, img_width, img_height);
// invert colors
for (var i=0;i<imgData.data.length;i+=4)
{
grayscaled = 0.34 * imgData.data[i] + 0.5 * imgData.data[i + 1] + 0.16 * imgData.data[i + 2];
imgData.data[i]=grayscaled;
imgData.data[i+1]=grayscaled;
imgData.data[i+2]=grayscaled;
}
//places the converted image in the lower right corner where
//WIDTH/HEIGHT is window.innerWidth/window.innerHeight
ctx.putImageData(imgData, WIDTH-img_width, HEIGHT-img_height);
You can use compositing to achieve a fade effect more efficiently.
draw a radial gradient that fades to transparent in the top-left corner.
Adjust the radial gradient to meet your design needs.
set compositing to source-in which causes any subsequent draws to only appear over existing non-transparent pixels.
draw your image (the image will fade the same way your radial gradient did)
Using compositing is especially efficient if the device has a GPU because compositing will use it.
Example code and a Demo: http://jsfiddle.net/m1erickson/thqamsLk/
<!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>
canvas{ background-color: lightgray; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/reef.jpg";
function start(){
canvas.width=img.width;
canvas.height=img.height;
var g1=ctx.createRadialGradient(500,500,550,500,500,650);
g1.addColorStop(0.00,"rgba(0,0,0,1.00)");
g1.addColorStop(0.30,"rgba(0,0,0,0.75)");
g1.addColorStop(1.00,"rgba(0,0,0,0.00)");
ctx.fillStyle=g1;
ctx.fillRect(0,0,cw,ch);
ctx.globalCompositeOperation="source-in";
ctx.drawImage(img,0,0);
}
}); // end $(function(){});
</script>
</head>
<body>
<h4>Fading an image using compositing</h4>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

How to get a image id in canavs html5 when clicked on that image?

Here is my code:
<body>
<canvas id="myCanvas" width="1100" height="600" style="border:1px solid #c3c3c3; cursor:move">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=new Image();
img.src="image.jpg";
img.id="im";
img.onload = function(){
ctx.drawImage(img,0,0,100,100);
autoRun();
};
function autoRun(){
ctx.clearRect(0, 0, 1100,600);
img.id="im";
ctx.drawImage(img,Math.floor((Math.random()*1000)+1),Math.floor((Math.random()*500)+1),70,70);
setTimeout('autoRun()',1000);
}
</script>
</body>
Here I am using the random method for setting the X and Y coordinates hence the image will move dynamically will move the area of canvas ...
setTimeout('autoRun()',1000);
The above line will call the autorun function javascript for every sec and that function will clear the canvas and redraw the image with new coordinates....
Now i would like to get the id of the image when we click on it. How can I do that?
EDIT- This would not work !
Should this work for you ? Or are there any other complications ?
//This would bind to all image, but you can use
//other jquery selectors to select your perticular
//image
$('img').click(function(){
var my_id = $(this).attr('id');
return false;
});
EDIT
"..The image itself is not available in the DOM, you just created it temporarily to draw it into the canvas. So the canvas holds the content of the image, the image itself is not in the DOM"
Select image within canvas with jQuery
I think you should segment the shape of your image (defining its boundary pixels) and then check if when you click inside the canvas, the point selected (the mouse position when clicking) is inside the image shape.
This can be a solution for your problem.

Categories