Friday, May 17, 2024
 Popular · Latest · Hot · Upcoming
1
rated 0 times [  5] [ 4]  / answers: 1 / hits: 26391  / 9 Years ago, tue, february 3, 2015, 12:00:00

I have been looking to change the colour of an image when a click event is used.



I Came across this post, which the first and main response with the Mug works really well.



However, I need to use class, rather than ID, as I need to change the colour of more than one image. When I change the code to getElementsByClassName, instead of byID, it no longer works.



I of course change the ID=mug to class=mug.



I can't see anywhere else in the code that would cause a problem, so any help would be appreciated.



I can't post on the original so adding here. Original link is:
How to change color of an image using jquery



This is the code:



<img src=mug.png id=mug width=25% height=25% onload=getPixels(this) />
<input type=text id=color value=#6491ee />
<input type=button value=change color onclick=changeColor()>

<script type=text/javascript>
var mug = document.getElementById(mug);
var canvas = document.createElement(canvas);
var ctx = canvas.getContext(2d);
var originalPixels = null;
var currentPixels = null;

function HexToRGB(Hex)
{
var Long = parseInt(Hex.replace(/^#/, ), 16);
return {
R: (Long >>> 16) & 0xff,
G: (Long >>> 8) & 0xff,
B: Long & 0xff
};
}

function changeColor()
{
if(!originalPixels) return; // Check if image has loaded
var newColor = HexToRGB(document.getElementById(color).value);

for(var I = 0, L = originalPixels.data.length; I < L; I += 4)
{
if(currentPixels.data[I + 3] > 0)
{
currentPixels.data[I] = originalPixels.data[I] / 255 * newColor.R;
currentPixels.data[I + 1] = originalPixels.data[I + 1] / 255 * newColor.G;
currentPixels.data[I + 2] = originalPixels.data[I + 2] / 255 * newColor.B;
}
}

ctx.putImageData(currentPixels, 0, 0);
mug.src = canvas.toDataURL(image/png);
}

function getPixels(img)
{
canvas.width = img.width;
canvas.height = img.height;

ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, img.width, img.height);
originalPixels = ctx.getImageData(0, 0, img.width, img.height);
currentPixels = ctx.getImageData(0, 0, img.width, img.height);

img.onload = null;
}
</script>


Thanks


More From » colors

 Answers
4

OK, has taken some time but through a combination of the suggestions given and extra searching have found a solution for my needs.



Each of the suggestions got me so far but there were some issues for the specific functionality I needed, so am posting this in case it helps others.



I am using the < svg > element:



I required a main image, and them some smaller images on top that would change colour if the image was clicked on, or if a button outside the main image is clicked.



<div style=position: absolute; top: 0px; left: 0px;><svg version=1.1 xmlns=http://www.w3.org/2000/svg width=0px height=0px><defs><filter id=desaturate> <feColorMatrix 
type=matrix
values=0.5 0 0 0 0
0.2 0 0 0 0
0.9 0 0 0 0
0 0 0 1 0 /></filter></defs></svg></div>


The values set the colour change. It is trial and error atm as I haven't found a good guide to the colours yet but there are enough around to get by.



I had a problem with random spaces and positioning caused by using the < svg > element. So I have put it inside a dive that is absolutely positioned and set the size of the element to '0' '0' so it takes up no space and doesn't affect anything else on the page.



The ID specifies this particular colour. You can then apply this colour change to as many images as you like as follows:



<div style=position: relative; top: 000px; left: 000px; z-index: 1; display: inline;>
<svg class=svgClass version=1.1 id=Layer_1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink width=450px height=900px>
<image xlink:href=main_image.png width=450 height=900 />
<image xlink:href=small_image1.png class=ChangeImageColour ChangeImageColourClick width=79 height=198 x=110px y=100px />
<image xlink:href=small_image2.png class=ChangeImageColour ChangeImageColourClick width=79 height=198 x=150px y=130px /></svg></div>


Again, to avoid position and spacing issues with SVG, I have set the size of the < svg > element for the images to the same size of the main image, and placed them all within a < div > that can then be positioned in the right place on the page. If you want images overlapping in this way, you will need to have all the images within the same < svg > element or you may get display position and spacing issues in some browsers.



You can the position each image individually over the top of the main image using 'x' and 'y'. You must also specify the height and width of the image.



Once you have your < svg > to specify the colour, and your < svg > element for the images, you now just need to apply that colour to the images you want using class and ID attributes and the following code:



<script>
var $shape = $( '.ChangeImageColour' );
$( '.ChangeImageColourClick' ).click(function() {
if ( $shape.attr( 'filter' ) )
$shape.removeAttr( 'filter' );
else
$shape.attr( 'filter', 'url(#desaturate)' );
});
</script>


I want the colour change to happen after a click event ether on an image or a button. Just create a button with the matching 'click' calss, in this case 'ChangeImageColourClick'. So you can create anything to be clicked on and will change the colour. This click adds the ID of the set colour to change (#desaturate). If any matching element already has the ID, it is removed.



This creates the effect of toggling the colour change. It will change the colour of any matching image of the same class.



You can of course not use a click event if not required, or start with the colour change 'on' and click to remove etc.



Note: You can have multiple < svg > elements with images in and apply the same colour change. Just make sure you set the < svg > element dimensions to the exact ones you want, even if it is 0. If you leave it blank then you'll get some spacing issues.



I need to have the images in the same < svg > as they are png images that are occupying the same space on the page. If your images are not overlapping you should use separate < svg > elements or each image or image set, and set the dimensions of the < svg > element to the size of that image and you shouldn't have any issues with odd spacing and positioning in some browsers.



I think that about explains it all.



It works pretty well for what I need, and is a fairly concise bit of coding, especially as you only have to set the colour once and apply to multiple images.



Just be careful of some of the notes I've put to make sure it displays as you need.



Thanks for all the help, will update if there is anything relevant to add.



If you are having any problems then post on here. I'm not an expert but have looked at this a fair bit now and have probably tried and tested most pitfalls


[#67968] Sunday, February 1, 2015, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
efrainjamiry

Total Points: 234
Total Questions: 110
Total Answers: 112

Location: French Southern and Antarctic Lands
Member since Fri, Jan 6, 2023
1 Year ago
;