JavaScript filter hueRotate does not work - javascript

I am trying to change an image's (#bgImage) hue when hovering over a button (profIcon) in JavaScript. This type of button is created with JS, and there are 9 of them.
Here is the code that creates a DOM image element, sets it's source, position, size and transition. Finally it appends it to it's container. The image appears correctly, where it should be.
I am using quickID in place of document.getElementById, and it is working without error.
var bgImage = document.createElement("img");
bgImage.id = "bgImage";
bgImage.src = "./resources/images/backgrounds/profession/selector.jpg";
bgImage.style.position = "absolute";
bgImage.style.left = "0px";
bgImage.style.top = "0px";
bgImage.style.width = "100%";
bgImage.style.height = "100%";
bgImage.style.zIndex = 1;
bgImage.style.webkitTransition = "all 0.5s ease";
quickID("centerdiv").appendChild(bgImage);
Here is the code that runs when I hover over an image:
profIcon.onmouseover = function () {
var thisNr = this.id.substr(8); //last char of the profIcon ID; number between 0 and 8
var newHue = profTomb[thisNr][3]; //this contains the value and only that.
console.log(newHue); //always returns the correct value
quickID(this.id).style.webkitFilter = "grayscale(0%)"; //this part works, too
quickID("bgImage").style.webkitFilter = "hueRotate(" + newHue + "deg)";
}
My problem: for some reason, the filter does not apply. newHue is either a positive (75), or a negative (-23) value and it's inserted correctly, as it appears in the console log. I only use webkit vendor prefix as I use Google Chrome.
I waited up to 1 minute with my mouse cursor over the image, thinking my system needs time to process the transformation, but nothing happened.
Does anyone knows what is the problem?

The correct string to use is hue-rotate, not hueRotate. The following should work:
quickID("bgImage").style.webkitFilter = "hue-rotate(" + newHue + "deg)";

Related

Calculate div number with distance

I'm making a carousel like a casino roulette but i can't find the way to know which div number is when i make the animation. I'm trying to calculate by distance when i make the animation loop but i doesn't work
Here's my example
https://codepen.io/anon/pen/xXbpJr?page=1&
var giftamount = 10;
var gw = $('.gift').outerWidth(true);
var giftcenter = gw/2;
var cycle = 7;
var containercenter = $('.boxwrapper').outerWidth(true)/2;
for(var i = 0; i <=5; i++)
{
var giftduplicate = $('.giftwrapper').children().clone(true,true);
$('.giftwrapper').append(giftduplicate);
}
$('.button').click(function(){
var btn = $(this);
btn.hide();
var randomgift = Math.floor((Math.random() * 10) + 1);
var distance = giftamount * gw * cycle + containercenter + (randomgift*gw) - giftcenter;
console.log(distance);
$( ".giftwrapper" ).css({left: "0"});
$('.giftwrapper').animate({left: "-="+distance},10000,function(){
alert('You Won Gift' + randomgift);
btn.show();
});
});
i get the wrong number of div, i tried a lot of combination but it doesn't work
You can try and substitute this for the distance
var distance = giftamount * cycle * gw + (randomgift*gw) - containercenter -24;
The idea is the following: with distance=- containercenter; you would move to be left-aligned with the center of the container.
To that you add a certain number of cycles giftamount * cycle * gw and finally a random number of gift elements ((randomgift*gw)).
I could not figure out where the constant -24 comes from. I hard-coded and it needs to be better defined but I guess it might depend on some margins/approximations/jQuery/CSS/??
Now you should see that the animation always stops at the same point within the gift element (in the middle). To add a random deviation you could ad a small deviation dev (that lets you stay within the gift element) like this:
var dev = Math.random()*(giftcenter+1);
var distance = giftamount * cycle * gw + (randomgift*gw) - containercenter -24 +dev;
Updated demo: https://codepen.io/anon/pen/RLNeBX
If you want to get the prize that is underneath the pointer (the vertical red bar), you actually do not have to compute the distance. Instead, you can make use of a really handy but somewhat less known DOM API method known as elementFromPoint(x, y), where you can obtain a reference to the topmost DOM node under the x,y coordinate of the page.
In order for this to work, x and y will have to correspond to the visual center of the pointer, which can we can simply calculate by using:
var $pointer = $('.rafflebox .pointer');
var pointerX = $pointer.offset().left + $pointer.width() * 0.5;
var pointerY = $pointer.offset().top + $pointer.height() * 0.5;
In jQuery's animation callback, you simply can retrieve the element (aka the prize) underneath this coordinate:
// Hide pointer first, otherwise it will be returned as the topmost element
$pointer.hide();
// Get element from pointer's visual center
var prize = document.elementFromPoint(pointerX, pointerY);
// Show it again
$pointer.show();
Now you have the correct reference to the DOM node, it is up to you to decide what kind of metadata you want to store in the "prize" DOM node. For example, you can embed a HTML5 data- attribute in your HAML:
%img{:src => "http://placehold.it/125x125?text=Prize+#{i}", :data => {:prize => "Prize #{i}"}}
...which simply stores the text Prize (n) (where n is the prize number) in the attribute data-prize, and we can access it later using:
var prize = document.elementFromPoint(pointerX, pointerY);
console.log($(prize).data('prize'));
When we replace part of your code with what I have suggested, you get this:
// Get visual center of pointer
var $pointer = $('.rafflebox .pointer');
var pointerX = $pointer.offset().left + $pointer.width() * 0.5;
var pointerY = $pointer.offset().top + $pointer.height() * 0.5;
$( ".giftwrapper" ).css({left: "0"});
$('.giftwrapper').animate({left: "-="+distance},10000,function(){
// Hide pointer first, otherwise it will be returned as the topmost element
$pointer.hide();
// Get element from pointer's visual center
var prize = document.elementFromPoint(pointerX, pointerY);
// Show it again
$pointer.show();
alert('You Won Gift ' + $(prize).data('prize'));
btn.show();
});
Here is your updated pen with a working example: https://codepen.io/terrymun/pen/dVPdMg
Updated example
There is a very small chance that the pointer will land in between prizes. To prevent this, you will want to use padding instead of margin on the .gift element:
.gift {
// Change margin to padding
padding: 0px 4px;
}
...and perform additional checks on the returned prize node:
// Hide pointer first, otherwise it will be returned as the topmost element
$pointer.hide();
// Get element from pointer's visual center
var $prize = $(document.elementFromPoint(pointerX, pointerY));
// If prize lands on the .gift element instead
if(!$prize.is('img'))
$prize = $prize.find('img')
// Show it again
$pointer.show();
alert('You Won Gift' + $prize.data('prize'));
btn.show();
The pen here is simply a fork of the original solution, but with exaggerated horizontal padding to increase the chance of the pointer landing in between iamges: https://codepen.io/terrymun/pen/rGaJmY

ajax undefined after a thousand iterations

When creating an animation I try to use javascript for additional effects, namely snow being piled up and falling off the edges of the foreground. I figured that the javascript could do the "calculations" on a <canvas> that had the image, then send the "snow" to a php script that would create the png images. This is all placed on my local "server" because that is the only one that can write files.
<html>
<head>
<title>Making Snow</title>
</head>
<body bgcolor="black">
<canvas id="canvas" width="1920px" height="1080px"></canvas>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
var canvas;
var ctx;
var frame=-530;
var simg = new Image()
var dimg = new Image()
onload = function()
{
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
simg.src = "prodB/C/DGB.0530.png"
}
simg.onload = function()
{
var ipo=3;
// Initialize all pixels on the screen/page
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(simg,0,0);
document.title = "Making Snow " + (frame+530) + " / 7000";
snowdraw();
}
dimg.onerror = function()
{
dimg.src = "../imagewriting/snow" + zeroFill(frame+530,4) + ".png";
}
dimg.onload = function()
{
frame++;
if(frame<530)
simg.src = "prodB/C/DGB.0530.png"
else if(frame>4400)
simg.src = "prodB/C/DGB.4400.png"
else
simg.src = "prodB/C/DGB." + zeroFill(frame,4) + ".png"
}
var snowdraw = function()
{
var temp;
var canvasData = "";
// console.log(screen);
// Animation
// Choose a random pixel at the top of the screen
if(frame<7000)
{
for(ny=canvas.height-2; ny>=0; ny--)
{ // Iterate through all the pixels starting from the bottom right corner.
for(nx=canvas.width-2; nx>=0; nx--)
{
canvasData=canvasData+"1";
}
}
$.ajax({
method: "POST",
url: "makesnow.php",
data:{ imgData: canvasData, frame: (frame+530) }
})
.done(function( msg ) {
dimg.src = "../imagewriting/snow" + zeroFill(frame+530,4) + ".png";
});
}
else
{
document.title = "COMPLETE";
}
}
// http://stackoverflow.com/questions/1267283/how-can-i-create-a-zerofilled-value-using-javascript
// by Peter Bailey http://stackoverflow.com/users/8815
function zeroFill( number, width )
{
width -= number.toString().length;
if ( width > 0 )
{
return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
}
return number + ""; // always return a string
}
</script>
</html>
However, on the 1640th frame (or more precisely frame=1110) ajax is suddenly undefined. The image snow1640.png is created, but the browser tells me ajax is not defined and won't advance passed Making Snow 1640 / 7000. Because of the small random nature for each "snow flake" I can't just pick it up from where I left off, as the snow would jump from one frame to the next. Though I did try that at one point and ajax still stopped after that frame.
I first ran it on the local machine running Firefox (http://127.0.0.1/...) then moved onto another machine on the network which is more powerful running Chrome and both died on that same frame. Thought it might be a memory or file limit so I moved the complete frames out of there. Still nothing.
EDIT: Code now snippit of just the problem.
Also, console.log for data and ajax.responseText seem to be generally empty, both during successful "renders" and when it starts iterating ajax is not defined (every other line empty, every other error).
EDIT: New development! Turns out that the error ReferenceError: ajax is not defined anyways gets called between frames (and the 404 when asking dimg if image was created).
EDIT: By typing in console.log($.ajax) after onload and commenting out simg.src I got function ajax().
Error persists, this time I expanded it to reveal the following:
success http://127.0.0.1/ag/makesnowBC.html 197:7
j http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 2:27131
fireWith http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 2:27949
x http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 4:22242
b http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 4:26298
EDIT: Changed the code to now use Synchronous ajax. This time there are no error messages what so ever, but it still stops at 1640.

Get image dimensions with JavaScript using innerHTML

I'm working on an AJAX function that receives image URLs. However, I won't be using a node append to insert it. I'm using innerHTML, which makes it difficult to get the file dimensions.
At the moment, I'm using a function which is returning somewhat mixed results. Sometimes it gets the actual dimensions, other times it returns "0" as the image dimensions.
This is my function:
var url = "http://placekitten.com.s3.amazonaws.com/homepage-samples/408/287.jpg";
var width = getDimensions(url)[0];
var height = getDimensions(url)[1];
var insert = '<img src="'+url+'" width="'+width+'" height="'+height+'" />';
function getDimensions(path) {
var img = new Image();
img.src = path;
return [img.width, img.height];
}
Not sure why it's acting inconsistently though. Does anyone have any suggestions?
I was thinking it might be something to do with the AJAX inserting the image before it loads the dimensions, although not really sure.
Here's a fiddle, which seems to work as expected, but like I said, it's inconsistent.
http://jsfiddle.net/aH5re/1/
EDIT
Here is a second fiddle with a much larger image. I noticed it's a lot more inconsistent than a smaller image file
http://jsfiddle.net/aH5re/2/
You'll have to wait for the image to finish loading before you can get the dimensions properly and reliably. What's currently happening is that it's returning the dimensions before the image is potentially fully loaded. If you have it already cached you may be getting correct dimensions but on a large image uncached you're not going to get reliable results.
Have a look at this demo about how you could perhaps achieve that.
http://jsfiddle.net/robschmuecker/aH5re/5/
Javascript:
var url = "http://www.hdwallpapers.in/download/transformers_4_age_of_extinction-2560x1440.jpg";
var div = document.querySelector('div');
alert('loading image now');
var button = document.querySelector('.test');
getDimensions(url);
button.addEventListener('click', function () {
div.innerHTML = insert;
});
function getDimensions(path) {
var img = new Image();
img.src = path;
img.onload = function () {
alert('loaded');
var width = img.width;
var height = img.height;
insert = '<img src="' + url + '" width="' + width + '" height="' + height + '" />';
button.disabled = false
};
}

Image.complete is true after onload, but after onload second image not anymore

I'm using Javascript to load 2 images and drawing them on a canvas.
I use the onload event of an image to drawn the images after they are both loaded.
var loadedImagesCount = 0;
var NUM_OF_TILES=2;
window.onload=function(){
background.onload = imageOnLoad();
background.src ="background.png";
layer1 = document.getElementById("layer1");
ctx1 = layer1.getContext("2d");
character.onload = imageOnLoad();
character.src ="character.png";
layer2 = document.getElementById("layer2");
ctx2 = layer2.getContext("2d");
}
function imageOnLoad(){
loadedImagesCount++;
window.alert(''+loadedImagesCount+ ' ' + background.complete + ' ' + character.complete);
if (loadedImagesCount==NUM_OF_TILES) drawAll();
}
The imageOnLoad() is called twice (as expected). The first time is says (through an alert) that both images are loaded. The second time it says that the character image is loaded, but the background image not anymore? How is this possible? Why would it unload the image again? After a refresh this does not happen anymore, it only happens the first time you load the page.
And because the background is not loaded, when the canvas is drawn, only the character is being drawn.
This maybe because you have not declared background as a global variable outside of the window.onload function. So background is not the variable you think it is.
Check this code that works as expected and is derived from yours and notice how background and characters are "vared" outside of the window.onload function :
<html>
<script language="javascript">
var loadedImagesCount = 0;
var NUM_OF_TILES=2;
var background;
var character;
window.onload=function(){
background = document.getElementById("background");
character = document.getElementById("character");
background.onload = imageOnLoad();
background.src ="HSHOP.jpg";
character.onload = imageOnLoad();
character.src ="HSHOP 2.jpg";
}
function imageOnLoad(){
loadedImagesCount++;
window.alert(''+loadedImagesCount+ ' ' + background.completes + ' ' + character.complete);
//if (loadedImagesCount==NUM_OF_TILES) drawAll();
}
</script>
<body>
<img id="background"/>
<img id="character"/>
</body>
</html>
Quick note : As a general rule try to clean up your code as much as possible before posting it so that it is easier for us to find what's going wrong.
Problem solved. The onload variable needs a method without the parentheses, if you use the parentheses it will call the method immediately.

JavaScript Preloader in Modal Div from HTML Table concatenates to new img URL

This code is meant for a real estate website I am updating for my company. Basically, There is a table with the property name, address, etc, and an image. Originally, I was coding this website in ASP.net switch over to regular Javascript for a few reasons (hosting overhead etc).
Sections of this code are from a few different tutorials out there, one of which is an ASP.net modal div image "enlarger" tutorial, which is sort of the basis combined with a few other sites. I have yet to comment in their names etc, but I plan on giving them credit in the code. Thier links are below before I post my code.
http://archive.aspsnippets.com/post/2009/07/06/Image-Gallery-using-ASPNet-GridView-control.aspx
My code is essentially as follows (I will trim the fat and excess line breaks in the style section):
First are the modal style tags from that tutorial by Mudassar Khan (partially relevant):
<style>
body {margin:0;padding:0;height:100%;}
.modal {display: none;position: absolute;top: 0px;left: 0px;background-color:black;z-index:100;opacity: 0.8; filter: alpha(opacity=60);-moz-opacity:0.8;min-height: 100%;}
&#divImage{display: none;z-index: 1000;position: fixed;top: 0;left: 0;background-color:White;height: 550px;width: 600px;padding: 3px;border: solid 1px black;}
<style>
Then comes his script, which I may have tweaked here and there:
<script type="text/javascript">
function LoadDiv(url) {
var img = new Image();
var bcgDiv = document.getElementById("divBackground");
var imgDiv = document.getElementById("divImage");
var imgFull = document.getElementById("imgFull");
var imgLoader = document.getElementById("imgLoader");
img.src = url;
var tcopy = img.src.slice(0,(img.src.length-4)) + "_big.png";
img.src = tcopy;
img.onload = function () {
imgFull.src = tcopy
imgFull.style.display = "block";
imgLoader.style.display = "none";
};
var width = document.body.clientWidth;
if (document.body.clientHeight > document.body.scrollHeight) {
bcgDiv.style.height = document.body.clientHeight + "px";
}
else {
bcgDiv.style.height = document.body.scrollHeight + "px";
}
imgDiv.style.left = (width - 650) / 2 + "px";
imgDiv.style.top = "20px";
bcgDiv.style.width = "100%";
bcgDiv.style.display = "block";
imgDiv.style.display = "block";
return false;
}
function HideDiv() {
var bcgDiv = document.getElementById("divBackground");
var imgDiv = document.getElementById("divImage");
var imgFull = document.getElementById("imgFull");
imgLoader.style.display = "block"; // I added as it seems to bring back the loader gif
if (bcgDiv != null) {
bcgDiv.style.display = "none";
imgDiv.style.display = "none";
imgFull.style.display = "none";
}
}
</script>
Now All this above script gets called upon a onClick Event Handler on an image of each of the real estate companies properties. This will work well to both preload images with the little animated gif and the close button works fine. It works on more than one image, BUT if the image is already preloaded, I cant think of a way to force the redisplay of an already preloaded image if a user clicks on the photo, then clicks close to hide the div tag and then clicks on the same preloaded image.
That event handler looks like this:
img onClick="return LoadDiv(this.src);" src="http://www.ourcompany.com/images/prop_thumbs/Some_plaza.png" style="min-width:200 px;max-height:150 px;max-width:200 px;"
I thought global booleans would work, but then I realized, theres no telling which and what is preloaded, so the boolean might not help if you can't pass something meaningful back and forth.
I'm not asking any one to do my work for me, however I would appreciate suggestions in the right direction.
Regards and TIA!
You could make a array of all of the images with key values of loaded. For instance.
image_list = {image1:false,image2:true,image3:false};
true and false being loaded or not loaded. When an image is clicked just update the array.
image_list[image1] = true;
Did this really quick, so my syntax might be off, feel free to correct me or berate me...
Yay!!! Figured it out with the help of both jhanifen and the guy who did the tutorial I used (he actually emailed me). My code is below (its an excerpt, but you'll get the idea):
images = new Array(30);
//need to define each image to be in array
images[0]="website/images/prop_thumbs/property1_big.png";
images[1]="website/images/prop_thumbs/property2_big.png";
images[2]="website/images/prop_thumbs/property3_big.png";
//This continues for some time
imagesLoaded = new Array(30);
// per stack overflow person suggestion make array of bool values; initialize them all to false on page load
function onLoadScript() {
for (i = 0; i < imagesLoaded.length; ++ i)
{
imagesLoaded [i] = false;
}
}
// the above is called onLoad in body tag
// Changes the script for Loading the Div tag are below:
function LoadDiv(imgNum) {
var img = new Image();
var bcgDiv = document.getElementById("divBackground");
var imgDiv = document.getElementById("divImage");
var imgFull = document.getElementById("imgFull");
var imgLoader = document.getElementById("imgLoader");
img.src = images[imgNum];
if(imagesLoaded[imgNum] = true)
{ // this statement triggers same as onload below!
imgFull.src = img.src
imgFull.style.display = "block";
imgLoader.style.display = "none";
}
img.onload = function () {
imgFull.src = img.src
imgFull.style.display = "block";
imgLoader.style.display = "none";
imagesLoaded[imgNum] = true;
};
The rest of the document is the same except I changed the onClick event handler for the property images to LoadDiv(and some sequential number);
Thanks to all for your help! Particular props to both Mudassar Khan and jhanifen!

Categories

Resources