transparency to a single image within the canvas - javascript

I am trying to give transparency to a single image that I have created on the canvas, globalAlpha does not work for me because I need to only affect one image and that affects all images.
var canvas = document.getElementById('cvs');
var ctx = canvas.getContext('2d');
var image = new Image();
image.src = "../img/image.jpg";
image.onload = function () {
ctx.drawImage(image, 200, 200, 100, 100);
}
var image1 = new Image();
image1.src = "../img/image.jpg";
image1.onload = function () {
ctx.drawImage(image1, 400, 400, 100, 100);
}

Set globalAlpha to your transparency level, draw the image, return globalAlpha to 1.

You can set the ctx global alpha around render.
image1.onload = function () {
// Save the original alpha
ctx.save();
// Set global alpha
ctx.globalAlpha = 0.5;
// Draw
ctx.drawImage(image1, 400, 400, 100, 100);
// Restore the original alpha
ctx.restore();
}

Related

how to draw on a image background using canvas?

What is wrong with my code.I am trying to load the image background on a canvas and then draw few rectangles on the image canvas.my image is not showing up on the canvas or either is it being completely overwritten my rectangles.
I have followed this SO question, but still, it happens.
//Initialize a new Box, add it, and invalidate the canvas
function addRect(x, y, w, h, fill) {
var rect = new Box;
rect.x = x;
rect.y = y;
rect.w = w
rect.h = h;
rect.fill = fill;
boxes.push(rect);
invalidate();
}
// holds all our rectangles
var boxes = [];
// initialize our canvas, add a ghost canvas, set draw loop
// then add everything we want to intially exist on the canvas
function drawbackground(canvas,ctx,onload){
var img = new Image();
img.onload = function(){
// canvas.width = img.width;
// canvas.height = img.height;
ctx.drawImage(img);
//addRect(200, 200, 200, 200, '#FFC02B');
onload(canvas,ctx);
};
img.src = "https://cdnimages.opentip.com/full/VLL/VLL-LET-G.jpg";
}
function init() {
// canvas = fill_canvas();
canvas = document.getElementById('canvas');
HEIGHT = canvas.height;
WIDTH = canvas.width;
ctx = canvas.getContext('2d');
ghostcanvas = document.createElement('canvas');
ghostcanvas.height = HEIGHT;
ghostcanvas.width = WIDTH;
gctx = ghostcanvas.getContext('2d');
// make draw() fire every INTERVAL milliseconds
setInterval(draw, INTERVAL);
// set our events. Up and down are for dragging,
// double click is for making new boxes
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
canvas.ondblclick = myDblClick;
// add custom initialization here:
drawbackground(canvas,ctx);
//context.globalCompositeOperation = 'destination-atop';
// add an orange rectangle
addRect(200, 200, 200, 200, '#FFC02B');
// add a smaller blue rectangle
addRect(25, 90, 250, 150 , '#2BB8FF');
}
//wipes the canvas context
function clear(c) {
c.clearRect(0, 0, WIDTH, HEIGHT);
}
...
As the Image loads always asynchronously, and you draw your rects synchronously after drawbackground() call, you will get a canvas with only image on it.
You need to create function which will pe passed as third argument to drawbackground, and call addRect in this function instead of drawbackground
PS:
Your code should throw an exception because
onload(canvas,ctx);
will try to call undefined as a function

How would I generate a pulsating effect on an image that is to be drawn inside of a canvas?

var testPhoto = new Image();
testPhoto.src = "http://plan9.bell-labs.com/plan9/img/9logo.jpg"
testPhoto.className = "pulse";
and then:
topSlice.drawImage(testPhoto, 100, 200, 40, 40);
It appears the pulsating effect doesn't work after drawing the image, how should I fix this? I'm following this tutorial for the pulsating effect.
You can use Window.requestAnimationFrame instead and work with blend modes / alpha blending:
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
image = new Image();
image.src = "http://plan9.bell-labs.com/plan9/img/9logo.jpg";
function update(timestamp) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.globalAlpha = Math.sin(timestamp/100) * 0.5 + 0.5;
context.drawImage(image, 0, 0);
window.requestAnimationFrame(update);
}
window.requestAnimationFrame(update);
<canvas id="canvas"></canvas>

How do I extract a portion of an image in canvas and use it as background image for a div?

This is how my code looks:
document.addEventListener('DOMContentLoaded', function () {
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext("2d");
var imageData = ctx.getImageData(0, 0, 300, 300);
var tile = {
'id': 1,
'data': imageData,
'dataUrl': imageData.toDataUrl()
};
var div = document.createElement('div');
div.classList.add('tile');
grid.appendChild(div);
div.style.backgroundImage = ('url(' + tile.dataUrl + ')');
});
I'm trying to extract portion of the image on canvas, from (0,0) with height and width 300px, and convert that imageData object into a dataUrl to be used as a background of a div.
I get an error: imageData.toDataUrl() is not a function. How can I achieve this?
Thanks in advance!
toDataURL is an HTMLCanvasElement method you have to call it from the canvas element itself.
You could draw back your resulted imageData to the canvas after you changed its size to the wanted one, but the easiest solution is to use a second, off-screen canvas, where you will draw the first canvas thanks to the context.drawImage method:
// The crop function
var crop = function(canvas, offsetX, offsetY, width, height, callback) {
// create an in-memory canvas
var buffer = document.createElement('canvas');
var b_ctx = buffer.getContext('2d');
// set its width/height to the required ones
buffer.width = width;
buffer.height = height;
// draw the main canvas on our buffer one
// drawImage(source, source_X, source_Y, source_Width, source_Height,
// dest_X, dest_Y, dest_Width, dest_Height)
b_ctx.drawImage(canvas, offsetX, offsetY, width, height,
0, 0, buffer.width, buffer.height);
// now call the callback with the dataURL of our buffer canvas
callback(buffer.toDataURL());
};
// #main canvas Part
var canvas = document.getElementById('main');
var img = new Image();
img.crossOrigin = "Anonymous";
img.onload = function() {
canvas.width = this.width;
canvas.height = this.height;
canvas.getContext('2d').drawImage(this, 0, 0);
// set a little timeout before calling our cropping thing
setTimeout(function() {
crop(canvas, 100, 70, 70, 70, callback)
}, 1000);
};
img.src = "https://dl.dropboxusercontent.com/s/1alt1303g9zpemd/UFBxY.png";
// what to do with the dataURL of our cropped image
var callback = function(dataURL) {
document.body.style.backgroundImage = 'url(' + dataURL + ')';
}
<canvas id="main" width="284" width="383"></canvas>

Rotate canvas 90 degrees clockwise and update width height

Say we have a canvas:
<canvas id="one" width="100" height="200"></canvas>
And on a button click the canvas gets rotated 90 degrees clockwise (around the center) and the dimensions of the canvas get also updated, so in a sense it looks like this afterwards:
<canvas id="one" width="200" height="100"></canvas>
Note that the id of the canvas is the same.
Imagine simply rotating an image clockwise without it being cropped or being padded.
Any suggestions before I do it the long way of creating a new canvas and rotating and copying pixel by pixel?
UPDATE sample code with suggestion from comments still not working:
function imageRotatecw90(){
var canvas = document.getElementById("one");
var context = canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var myImageData = context.getImageData(0,0, cw,ch);
context.save();
context.translate(cw / 2, ch / 2);
context.rotate(Math.PI/2);
context.putImageData(myImageData, 0, 0);
context.restore();
canvas.width=ch;
canvas.height=cw;
}
FiddleJS
Look at this DEMO.
To achieve the results seen in demo, I made use of canvas.toDataURL to cache the canvas into an image, then reset the canvas to their new dimensions, translate and rotate the context properly and finally draw the cached image back to modified canvas.
That way you easily rotate the canvas without need to redraw everything again. But because anti-aliasing methods used by browser, each time this operation is done you'll notice some blurriness in result. If you don't like this behavior the only solution I could figure out is to draw everything again, what is much more difficult to track.
Here follows the code:
var canvas = document.getElementById("one");
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
// Sample graphic
context.beginPath();
context.rect(10, 10, 20, 50);
context.fillStyle = 'yellow';
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();
// create button
var button = document.getElementById("rotate");
button.onclick = function () {
// rotate the canvas 90 degrees each time the button is pressed
rotate();
}
var myImageData, rotating = false;
var rotate = function () {
if (!rotating) {
rotating = true;
// store current data to an image
myImageData = new Image();
myImageData.src = canvas.toDataURL();
myImageData.onload = function () {
// reset the canvas with new dimensions
canvas.width = ch;
canvas.height = cw;
cw = canvas.width;
ch = canvas.height;
context.save();
// translate and rotate
context.translate(cw, ch / cw);
context.rotate(Math.PI / 2);
// draw the previows image, now rotated
context.drawImage(myImageData, 0, 0);
context.restore();
// clear the temporary image
myImageData = null;
rotating = false;
}
}
}
Rotation
Note it is not possible to rotate a single element.
ctx.save();
ctx.rotate(0.17);
// Clear the current drawings.
ctx.fillRect()
// draw your object
ctx.restore();
Width/height adjustment
The only way I ever found to properly deal with display ratios, screen sizes etc:
canvas.width = 20;// DO NOT USE PIXELS
canvas.height = 40; // AGAIN NO PIXELS
Notice I am intentionally not using canvas.style.width or canvas.style.height. Also for an adjustable canvas don't rely on CSS or media queries to do the transformations, they are a headache because of the pixel ratio differences. JavaScript automatically accounts for those.
Update
You also have to update the width and the height before you draw. Not sure what you are trying to achieve, but I guess this isn't a problem:
Demo here
var canvas = document.getElementById("one");
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
canvas.width = 200;
canvas.height = 400;
// Sample graphic
context.beginPath();
context.rect(10,10,20,50);
context.fillStyle = 'yellow';
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();
var myImageData = context.getImageData(0, 0, cw, ch);
context.save();
context.translate(cw / 2, ch / 2);
context.putImageData(myImageData, 0, 0);
context.rotate(0.20);
If you want to rotate an image by 90 degrees this might be helpful:
export const rotateBase64Image = async (base64data: string) => {
const image = new Image();
image.src = base64data;
return new Promise<string>((resolve, reject) => {
image.onload = function () {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
if (!ctx) throw new Error("cannnot get context '2d'");
canvas.width = image.height;
canvas.height = image.width;
ctx.setTransform(0, 1, -1, 0, canvas.width, 0); // overwrite existing transform
ctx!.drawImage(image, 0, 0);
canvas.toBlob((blob) => {
if (!blob) {
return reject("Canvas is empty");
}
const fileUrl = window.URL.createObjectURL(blob);
resolve(fileUrl);
}, "image/jpeg");
};
});
};
If you don't have image in base64 format you can do it like this:
const handleRotate = async () => {
const res = await fetch(link);
const blob = await res.blob();
const b64: string = await blobToB64(blob);
const rotatedImage = await rotateBase64Image(b64)
setLink(rotatedImage);
}
Here is my blobTob64 function:
export const blobToB64 = async (blob) => {
return new Promise((resolve, _) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
});
};

Loading an image onto a canvas with javaScript

I am currently testing using the <canvas> element to draw all of the backgrounds (I will add effects later to these images later and is the reason I'm not using CSS to load the images). That said, I'm currently having difficulty loading a image on to the canvas. Here is the code:
<html>
<head>
<title>Canvas image testing</title>
<script type="text/javascript">
function Test1() {
var ctx = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
//Loading of the home test image - img1
var img1 = new Image();
img1.src = 'img/Home.jpg';
//drawing of the test image - img1
img1.onload = function () {
//draw background image
ctx.drawimage(img1, 0, 0);
//draw a box over the top
ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
ctx.fillRect(0, 0, 500, 500);
};
}
}
</script>
<style type="text/css">
canvas { border: 2px solid black; width: 100%; height: 98%; }
</style>
</head>
<body onload="Test1();">
<canvas id="canvas" width="1280" height="720"></canvas>
</body>
</html>
I think that I'm not loading the image correctly, but I'm not sure.
There are a few things:
drawimage should be drawImage - note the capital i.
Your getElementById is looking for an element with ID of canvas, but it should be test1. canvas is the tag, not the ID.
Replace the canvas variable (e.g. in your canvas.getContext lines) with ctx, since that's the variable you've used to select your canvas element.
Bind your onload handler before you set the src of the image.
So your function should end up like this:
function Test1() {
var ctx = document.getElementById('test1');
if (ctx.getContext) {
ctx = ctx.getContext('2d');
//Loading of the home test image - img1
var img1 = new Image();
//drawing of the test image - img1
img1.onload = function () {
//draw background image
ctx.drawImage(img1, 0, 0);
//draw a box over the top
ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
ctx.fillRect(0, 0, 500, 500);
};
img1.src = 'img/Home.jpg';
}
}
Using newer JavaScript features:
let img = await loadImage("./my/image/path.jpg");
ctx.drawImage(img, 0, 0);
and the loadImage function looks like this:
function loadImage(url) {
return new Promise(r => { let i = new Image(); i.onload = (() => r(i)); i.src = url; });
}
move the onload event listener to before you set the src for the image.
var img1 = new Image();
//drawing of the test image - img1
img1.onload = function () {
//draw background image
ctx.drawImage(img1, 0, 0);
//draw a box over the top
ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
ctx.fillRect(0, 0, 500, 500);
};
img1.src = 'img/Home.jpg';
Assign your local file resource (url) to image source and draw image using context from canvas you want to load. That's it. See code bellow.
var loadImage = function (url, ctx) {
var img = new Image();
img.src = url
img.onload = function () {
ctx.drawImage(img, 0, 0);
}
}
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var img1 = new Image();
//drawing of the test image - img1
img1.onload = function () {
//draw background image
ctx.drawImage(img1, 0, 0);
//draw a box over the top
ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
ctx.fillRect(0, 0, 500, 500);
};
img1.src = 'img/Home.jpg';
<canvas id="canvas"></canvas>

Categories

Resources