Skew transformation HTML5 canvas - javascript

I'm trying to implement skew transformation using the "x" axis with HTML5 canvas, but my code fails... Here is my JavaScript:
function init() {
var canvas = document.getElementById('skewTest'),
context = canvas.getContext('2d'),
angle = Math.PI / 4;
img = document.createElement('img');
img.src = 'img.gif';
img.onload = function () {
context.setTransform(1, Math.tan(angle), 1, 1, 0, 0);
context.clearRect(0, 0, 200, 200);
context.drawImage(img, 0, 0, 100, 100);
}
}
I'll be very glad if I see working example in JsFiddle.
Thank you in advance!

The correct matrix of skewing in only one direction is
context.setTransform(1, Math.tan(angle), 0, 1, 0, 0);
// ^
With the number at ^ being 1, you are skewing the image in the y-direction by 45° as well.
Sample: http://jsbin.com/etecay/edit#html,live

Canvas can't support direct transform; instead use the below code:
ctx.lineWidth = 100;
ctx.strokeStyle = "rgba(255, 255, 255, 0.5)";
ctx.strokeRect(0, 0, 640, 480);
ctx.lineWidth = 4;
ctx.strokeStyle = "#5E81AB";
ctx.strokeRect(50, 50, 540, 380);

Related

Old items reappear on canvas after clearing it [duplicate]

I'm using this script on the body onmousemove function:
function lineDraw() {
// Get the context and the canvas:
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
// Clear the last canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// Draw the line:
context.moveTo(0, 0);
context.lineTo(event.clientX, event.clientY);
context.stroke();
}
It's supposed to clear the canvas each time I move the mouse around, and draw a new line, but it isn't working properly.
I'm trying to solve it without using jQuery, mouse listeners or similar.
Here is a demo: https://jsfiddle.net/0y4wf31k/
You should use "beginPath()". That is it.
function lineDraw() {
var canvas=document.getElementById("myCanvas");
var context=canvas.getContext("2d");
context.clearRect(0, 0, context.width,context.height);
context.beginPath();//ADD THIS LINE!<<<<<<<<<<<<<
context.moveTo(0,0);
context.lineTo(event.clientX,event.clientY);
context.stroke();
}
Be advised that ctx.clearRect() does not work properly on Google Chrome. I spent hours trying to solve a related problem, only to find that on Chrome, instead of filling the rectangle with rgba(0, 0, 0, 0), it actually fills the rectangle with rgba(0, 0, 0, 1) instead!
Consequently, in order to have the rectangle filled properly with the required transparent black pixels, you need, on Chrome, to do this instead:
ctx.fillStyle = "rgba(0, 0, 0, 0)";
ctx.fillRect(left, top, width, height);
This should, of course, work on all browsers providing proper support for the HTML5 Canvas object.
And beginPath() and stroke() we need to use.
This code works same as clearRect(...)
ctx.beginPath();
ctx.fillStyle = "rgba(0, 0, 0, 255)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.stroke();
If you're getting a blacked out screen using this method
ctx.beginPath()
ctx.fillStyle = "rgba(0, 0, 0, 255)"
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.stroke();
then switch all the 0's in rgba to 255
ctx.beginPath();
ctx.fillStyle = "rgba(255, 255, 255, 255)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.stroke();
Try with context.canvas.width = context.canvas.width:
function lineDraw() {
var canvas=document.getElementById("myCanvas");
var context=canvas.getContext("2d");
//context.clearRect(0, 0, context.width,context.height);
context.canvas.width = context.canvas.width;
context.moveTo(0,0);
context.lineTo(event.clientX,event.clientY);
context.stroke();
}
Demo HERE

Stitching several canvas images together into one image in canvas using JavaScript

I want to stitch several images together into a one image.
Below are my images.
1st image :
2nd image :
3rd image :
4th image :
I want to stitch above all images into one like below
Final image :
I tried below code
let imgEle1 = document.querySelectorAll(".image")[0];
let imgEle2 = document.querySelectorAll(".image")[1];
let imgEle3 = document.querySelectorAll(".image")[2];
let imgEle4 = document.querySelectorAll(".image")[3];
let resEle = document.querySelector(".result");
var context = resEle.getContext("2d");
let BtnEle = document.querySelector(".Btn");
BtnEle.addEventListener("click", () => {
resEle.width = imgEle1.width;
resEle.height = imgEle1.height;
context.globalAlpha = 1.0;
context.drawImage(imgEle1, 0, 0);
context.globalAlpha = 0.5;
context.drawImage(imgEle2, 0, 0);
context.globalAlpha = 0.5;
context.drawImage(imgEle3, 0, 0);
context.globalAlpha = 0.5;
context.drawImage(imgEle4, 0, 0);
});
but getting output as below
Expanding on my comment, your calls to drawImage are all in the same location...
For the effect you show, the solution is to add a bit of offset to the locations.
Here is some sample code:
var image = `<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40"/></svg>`;
var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
context.globalAlpha = 0.5;
var img = new Image();
img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(image);
img.onload = function() {
// draw images with offset
context.translate(40, 40)
context.drawImage(img, -20, 0);
context.drawImage(img, 20, 0);
context.drawImage(img, 0, -20);
context.drawImage(img, 0, 20);
// draw images with NO offset
context.translate(140, 0)
context.drawImage(img, 0, 0);
context.drawImage(img, 0, 0);
context.drawImage(img, 0, 0);
context.drawImage(img, 0, 0);
}
<canvas id=canvas width=600 height=160></canvas>
I'm using just one hardcoded SVG image to show what is possible, but you can certainly add other images latter like you have in your sample code.

Drawing lights on a canvas

Hi i'm trying to draw lights in a canvas like this:
<canvas id="myCanvas" width="600" height="300"></canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "rgba(0,0,0,0.75)";
ctx.fillRect(0,0,300,300);
ctx.clearRect(0,0,300,300);
var grd = ctx.createRadialGradient(150,150,0,150,150,150);
grd.addColorStop(0, "rgba(255,255,0,0)");
grd.addColorStop(1, "rgba(0,0,0,0.75)");
ctx.fillStyle = grd;
ctx.fillRect(0,0,300,300);
ctx.clearRect(300,0,600,300);
var grd = ctx.createRadialGradient(450,150,0,450,150,150);
grd.addColorStop(0, "rgba(255,255,0,0)");
grd.addColorStop(1, "rgba(0,0,0,0.75)");
ctx.fillStyle = grd;
ctx.fillRect(300,0,600,300);
</script>
The problem is when the lights overlap
<canvas id="myCanvas" width="500" height="300"></canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "rgba(0,0,0,0.75)";
ctx.fillRect(0,0,300,300);
ctx.clearRect(0,0,300,300);
var grd = ctx.createRadialGradient(150,150,0,150,150,150);
grd.addColorStop(0, "rgba(255,255,0,0)");
grd.addColorStop(1, "rgba(0,0,0,0.75)");
ctx.fillStyle = grd;
ctx.fillRect(0,0,300,300);
ctx.clearRect(200,0,500,300);
var grd = ctx.createRadialGradient(350,150,0,350,150,150);
grd.addColorStop(0, "rgba(255,255,0,0)");
grd.addColorStop(1, "rgba(0,0,0,0.75)");
ctx.fillStyle = grd;
ctx.fillRect(200,0,500,300);
</script>
I need the lights come together and not overlap
also i need to see an image below the canvas
how can i Solve ?
that's the effect i'm looking for
I've used 2 canvas, 1 for scenery and 1 above for lights
This is almost what i'm looking for , but it remains a bit 'darker where the lights overlap, there is too little light in the center of each light, and it looks like a white light instead of a yellow light
http://jsfiddle.net/vgmc4m87/
Thanks
If you really want to overlap those two gradients, I would suggest a few things,
Get rid of the clearRect()
Change
grd.addColorStop(0, "rgba(255,255,0,0)"); grd.addColorStop(1, "rgba(0,0,0,0.75)");
Such that the second color stop has 0 alpha component, this way the gradient will actually fade out as it goes towards the edge of the circle. And you can actually overlap circles only if they're fading towards the end.
Don't use fillRect(), use arcs instead.
See, https://jsfiddle.net/fL4xffnq/3/. I've not preserved colours, but it should give you a good idea on how to proceed.
jsFiddle : https://jsfiddle.net/CanvasCode/p3k7cwqs/
javascript
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");
var image = new Image();
image.src = "http://images4.fanpop.com/image/photos/16000000/Beautiful-Cat-cats-16096437-1280-800.jpg";
image.onload = function () {
ctx.drawImage(image, 0, 0, 500, 400);
var grd = ctx.createRadialGradient(150, 150, 0, 0, 150, 200);
grd.addColorStop(0, "rgba(255,255,0,1)");
grd.addColorStop(1, "rgba(0,0,0,0)");
ctx.beginPath();
ctx.fillStyle = grd;
ctx.arc(150, 150, 200, 0, Math.PI * 2, false)
ctx.fill();
var grd = ctx.createRadialGradient(350, 150, 0, 350, 150, 200);
grd.addColorStop(0, "rgba(255,255,0,1)");
grd.addColorStop(1, "rgba(0,0,0,0)");
ctx.beginPath();
ctx.fillStyle = grd;
ctx.arc(350, 150, 200, 0, Math.PI * 2, false)
ctx.fill();
};
Adding to #nisargjhaveri's answer setting ctx.globalCompositeOperation = "lighter" creates a nice effect.
function drawBackground() {
var can = document.getElementById('background');
var ctx = can.getContext('2d');
var grd = ctx.createLinearGradient(0, 0, 0, 150);
grd.addColorStop(0, "rgba(0,255,255,1)");
grd.addColorStop(1, "rgba(30,100,200,1)");
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 500, 150);
var grd = ctx.createLinearGradient(0, 150, 0, 300);
grd.addColorStop(0, "rgba(15,75,25,1)");
grd.addColorStop(1, "rgba(30,150,50,1)");
ctx.fillStyle = grd;
ctx.fillRect(0, 150, 500, 300);
}
drawBackground();
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var bg = document.getElementById("background");
var x1 = 150;
var y1 = 150;
var x2 = 350;
var y2 = 150;
var step1 = {
x: 1,
y: 1
};
var step2 = {
x: -1,
y: 1
};
function loop() {
ctx.save();
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.clearRect(0, 0, 500, 300);
// Create a white to transparent gradient for the circles
// Circle one
var grd = ctx.createRadialGradient(x1, y1, 0, x1, y1, 150);
grd.addColorStop(.75, "rgba(255,255,0,1)");
grd.addColorStop(1, "rgba(255,255,0,0)");
ctx.beginPath();
ctx.fillStyle = grd;
ctx.arc(x1, y1, 150, 0, Math.PI * 2, false)
ctx.fill();
// Circle two
var grd = ctx.createRadialGradient(x2, y2, 0, x2, y2, 150);
grd.addColorStop(.75, "rgba(255,255,255,1)");
grd.addColorStop(1, "rgba(255,255,255,0)");
ctx.beginPath();
ctx.fillStyle = grd;
ctx.arc(x2, y2, 150, 0, Math.PI * 2, false)
ctx.fill();
// Fill the white part with the background image.
ctx.globalCompositeOperation = "source-atop";
ctx.drawImage(bg, 0, 0, bg.width, bg.height);
// Fill the transparent part with gray.
ctx.globalCompositeOperation = "destination-atop"
ctx.fillStyle = "rgba(63,63,63,1)";
ctx.fillRect(0, 0, c.width, c.height);
// clear the globalCompositeOperation
ctx.restore();
step1.x = x1 > c.width ? -1 : x1 < 0 ? 1 : step1.x;
step1.y = y1 > c.height ? -1 : y1 < 0 ? 1 : step1.y;
step2.x = x2 > c.width ? -1 : x2 < 0 ? 1 : step2.x;
step2.y = y2 > c.height ? -1 : y2 < 0 ? 1 : step2.y;
x1 += step1.x;
y1 += step1.y;
x2 += step2.x;
y2 += step2.y;
setTimeout(loop, 1000 / 60);
}
loop()
<canvas id="background" width="500" height="300" style='display:none'></canvas>
<canvas id="myCanvas" width="500" height="300"></canvas>

Java Script html5 Canvas

On button click I just want to put element in the canvas, but it's not working. Here is the code I have written:
<script language="javascript" type="text/javascript">
function image()
{
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.clear();
ctx.setTransform(-1, 0, 0, 1, 200, 200);
context.clear(true)
var imgobj=new Image();
imgobj.onload=function()
{
ctx.drawImage(imgobj,69,50);
}
imgobj.src='images.jpg';
}
function circle()
{
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.clear();
// do some more drawing
ctx.setTransform(-1, 0, 0, 1, 200, 200);
// do some drawing with the new transform
context.clear(true);
ctx.beginPath();
ctx.arc(95,50,40,0,2*Math.PI);
ctx.stroke();
}
function line()
{
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.clear();
// do some more drawing
ctx.setTransform(-1, 0, 0, 1, 200, 200);
// do some drawing with the new transform
context.clear(true);
ctx.moveTo(0,0);
ctx.lineTo(200,100);
ctx.stroke();
</script>
</head>
<body>
<h1>Demo of HTM5</h1>
<div class="canvas1" align="left">
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #000000;">
</canvas>
<p><button onclick="circle()"> Draw Circle</button></p>
<p><button onclick="line()"> Draw Line</button></p>
<p><button onclick="image()"> Display Image</button></p>
</div>
</body>
</html>
There is no ctx.clear() method on the context object, try instead with:
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
You are also using an unassigned context which you should remove.
Also there is no need to look-up canvas inside the function each time, just do it once in global scope.
And also, in your line method you're missing a beginPath() call.
See fiddle here
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
function image() {
/// use this to clear canvas
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.setTransform(-1, 0, 0, 1, 200, 200);
var imgobj = new Image();
imgobj.onload = function () {
ctx.drawImage(imgobj, 69, 50);
}
imgobj.src = 'images.jpg';
}
function circle() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// do some more drawing
ctx.setTransform(-1, 0, 0, 1, 200, 200);
// do some drawing with the new transform
ctx.beginPath();
ctx.arc(95, 50, 40, 0, 2 * Math.PI);
ctx.stroke();
}
function line() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// do some more drawing
ctx.setTransform(-1, 0, 0, 1, 200, 200);
// do some drawing with the new transform
ctx.beginPath(); /// add a beginPath here
ctx.moveTo(0, 0);
ctx.lineTo(200, 100);
ctx.stroke();
}
I think, you are using some wrong approach to clear the canvas. There is no method clear for canvas to clear it.
instead you should use: .clearRect(0, 0, 300, 300);
Here is the sample code:
function circle(){
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.clearRect(0, 0, 300, 300);
// do some more drawing
ctx.setTransform(-1, 0, 0, 1, 200, 200);
ctx.beginPath();
ctx.arc(95,50,40,0,2*Math.PI);
ctx.stroke();
}
function line(){
var c = document.getElementById('myCanvas');
var ctx = c.getContext('2d');
ctx.clearRect(0, 0, 300, 300);
ctx.setTransform(-1, 0, 0, 1, 200, 200);
// do some drawing with the new transform
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(200,100);
ctx.stroke();
}
jsfiddle: http://jsfiddle.net/FumBm/3/
Also, there is no variable with name context in your script. :)

clearRect function doesn't clear the canvas

I'm using this script on the body onmousemove function:
function lineDraw() {
// Get the context and the canvas:
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
// Clear the last canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// Draw the line:
context.moveTo(0, 0);
context.lineTo(event.clientX, event.clientY);
context.stroke();
}
It's supposed to clear the canvas each time I move the mouse around, and draw a new line, but it isn't working properly.
I'm trying to solve it without using jQuery, mouse listeners or similar.
Here is a demo: https://jsfiddle.net/0y4wf31k/
You should use "beginPath()". That is it.
function lineDraw() {
var canvas=document.getElementById("myCanvas");
var context=canvas.getContext("2d");
context.clearRect(0, 0, context.width,context.height);
context.beginPath();//ADD THIS LINE!<<<<<<<<<<<<<
context.moveTo(0,0);
context.lineTo(event.clientX,event.clientY);
context.stroke();
}
Be advised that ctx.clearRect() does not work properly on Google Chrome. I spent hours trying to solve a related problem, only to find that on Chrome, instead of filling the rectangle with rgba(0, 0, 0, 0), it actually fills the rectangle with rgba(0, 0, 0, 1) instead!
Consequently, in order to have the rectangle filled properly with the required transparent black pixels, you need, on Chrome, to do this instead:
ctx.fillStyle = "rgba(0, 0, 0, 0)";
ctx.fillRect(left, top, width, height);
This should, of course, work on all browsers providing proper support for the HTML5 Canvas object.
And beginPath() and stroke() we need to use.
This code works same as clearRect(...)
ctx.beginPath();
ctx.fillStyle = "rgba(0, 0, 0, 255)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.stroke();
If you're getting a blacked out screen using this method
ctx.beginPath()
ctx.fillStyle = "rgba(0, 0, 0, 255)"
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.stroke();
then switch all the 0's in rgba to 255
ctx.beginPath();
ctx.fillStyle = "rgba(255, 255, 255, 255)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.stroke();
Try with context.canvas.width = context.canvas.width:
function lineDraw() {
var canvas=document.getElementById("myCanvas");
var context=canvas.getContext("2d");
//context.clearRect(0, 0, context.width,context.height);
context.canvas.width = context.canvas.width;
context.moveTo(0,0);
context.lineTo(event.clientX,event.clientY);
context.stroke();
}
Demo HERE

Categories

Resources