Create reflected image with HTML Canvas?

2024/2/26 22:38:11

I have the following code which tries to combine a vertical mirrored image with a transparent to background color gradient. When combining these two effects it fails, do I need to overlay a PNG gradient over the canvas instead of trying to get the canvas to perform both operations?

<!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="application/xhtml+xml; charset=UTF-8" /><style type="text/css">body {background-color: #eee;text-align: center;padding-top: 150px;}</style><script type="text/javascript">var img = new Image();img.onload = function() {             var ctx = document.getElementById("output").getContext("2d");// reflect imagectx.translate(0, 75);ctx.scale(1, -1);ctx.drawImage(img, 0, 0, 75, 75);// add gradientvar grad = ctx.createLinearGradient(0, 0, 0, 20);grad.addColorStop(0, 'transparent');grad.addColorStop(1, '#eeeeee');ctx.fillStyle = grad;ctx.fillRect(0, 0, 75, 20);};img.src = "test.jpg";</script>
</head>
<body><div><img src="test.jpg" height="75" width="75" /></div><canvas id="output" width="75" height="20"></canvas>
</body>
</html>
Answer

There is no need for 2 canvas elements. The code below works.Tested it on FireFox 3.0 on Linux.

I have changed the canvas sizes so I could see it better while testing, I made the canvas 200 x 100 pixels. You will need to resize back to your needs (75x20). For testing purposes, I've made the overlay 100x100 pixels so I could see half the image with a gradient.

<!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="application/xhtml+xml; charset=UTF-8" />
<style type="text/css">body {background-color: #eee;text-align: center;padding-top: 150px;}
</style>
<script type="text/javascript">var img = new Image();img.onload = function() {var ctx = document.getElementById("output").getContext("2d");// reflect imagectx.translate(0, 100);ctx.scale(1, -1);ctx.drawImage(img, 0, 0, 200, 100);// add gradientvar grad = ctx.createLinearGradient(0, 0, 0, 100);grad.addColorStop(0.3, 'rgb(255,255,255)');grad.addColorStop(0.7, 'rgba(255,255,255,0)');ctx.fillStyle = grad;ctx.translate(0,0);ctx.rect(0, 0, 100, 100);ctx.fill();};img.src = "img/avatarW3.png";
</script>

<canvas id="output" width="200" height="100" style="border:1px solid black;"></canvas>

Edit to explain some of this:

I think you were basically missing the alpha attribute on the gradient.

grad.addColorStop(0.7, 'rgba(255,255,255,0)');

The fourth parameter is alpha. Also, since you flip the canvas upside down, the gradient is currently drawn upside down (hence the second color stop has the transparency on it, and yet the block is transparent on the top side).

If you wanted to do things correctly, you would need to:

ctx.save();
ctx.translate(0, 100);
ctx.scale(1, -1);
ctx.drawImage(img, 0, 0, 200, 100);
ctx.restore();

And now you can draw your transparent gradient block as you need it.

Also, for me the ctx.fillRect() command did not work. I had to use ctx.rect() and ctx.fill().

Hope this helps.

http://en.ppmy.cn/q/41786.html

Related Q&A

Disable link using javascript

I have following HTML and would like to disable the link using javascript.<a style="white-space: nowrap;" onclick="return InstallWebApp(true);" id="uc_ii_lnkInstall" hr…

Formatted dates in a Google Apps script

Im trying to get a spreadsheet with simple formatted dates when a form is submitted, but all dates, including the timestamp keep getting posted as "Dec 31 1969 2:00PM"... What am I doing wron…

CSS/JS: Animate Inline Element Upon Text Change

When an inline elements text changes, it is usually the case that its computed width or height changes as well.Usually its trivial to transition property changes with CSS, for example, adding a transit…

FileReader.js nothing happens in IE9

I need help setting up Jadriens FileReader.js. I have set up everything as I think this polyfill works. But the callback that fires when everything is initiated doesnt fire in IE9. This is my markup:&l…

How to set an interval, but then stop it after 20 minutes

Currently on my webpage I have a timer that runs a function every 30 seconds:setInterval("someFunction(userId)", 30000); This works fine, but the problem is if 100s of users leave their bro…

Parallax scrolling not working on mobile css

My parallax scrolling is not working on mobile devices, both android and iOS. The code works great for desktop but not for mobile, be it any browser. Background images are not scrolling in parallax eff…

Put 2 svg side by side

I am able to use 2 svg on one screen in d3.js. The Code looks like this and it works great:<svg width="880" height="800" id="svg1"></svg> <svg width="…

Insert br / in a String in Javascript

Lets say, I have a pretty long compund String:var result = string1 + " - " + string2 + " - " + string3;and I display the String in the Website by creating a new list item:var listEl…

Allow only numbers and one dot in input

Using the following code with jQuery:$(#from-amount).keypress(function(event) {if ((event.which != 46 || $(this).val().indexOf(.) != -1) && (event.which < 48 || event.which > 57)) {event.…

Javascript. Optimal way to join 2 sets of objects like in SQL?

Lets assume that we have 2 sets of objects set1 = [{id:1, x:1, y:2}, {id:2, x:2, y:2}] set2 = [{id:1, z:1}, {id:2, z:2}]We want: set3 = set1.join(set2).on(id); >> set3 [{id:1, x:1, y:2, z:1},{id…