I am trying to detect if an image was clicked. To give some context, I am making a cookie clicker game where if you click it 10 times, a new image will appear which will give double points. For the first image I used
document.querySelector('#clickme1').onclick=scooore;
Then I am adding new images with the following function:
function show_image(src, width, height, alt) {
var img = document.createElement("img");
img.src = src;
img.width = width;
img.height = height;
img.alt = alt;
document.body.appendChild(img);
}
My problem is how do I add to my variable (scree) since it is local and the first way needs to use a whole diff function.
function scooore() {
scree = scree + 1;
document.getElementById("scorez").innerHTML = "Image has been clicked " + scree + " times";
Been working for 40+ mins on this probably 1 line of code solution and couldn't find a solution so turning to the nice people at stack overflow
In addition to the code I posted below, what will really help you as you continue to develop your project is if you have an array of data for each image (whether that is an object or another array).
// Put on outside so that image may change instead of clone
var img = document.createElement("img")
// Fill out initial image specs
img.src = src
img.width = width
img.height = height
img.alt = alt
function show_image(src, width, height, alt) {
img.src = src
img.width = width
img.height = height
img.alt = alt
}
var scree = 0
function scooore() {
scree++
document.getElementById("scorez").innerHTML = "Image has been clicked " + scree + " times"
// If score is divisible by 10
if (scree % 10 === 0) {
show_image(src, width, height, alt)
}
}
document.querySelector('#clickme1').onclick = scrooore()
Related
I'm trying to change the size of an image with JavaScript. The jS file is separate from the HTML page.
I want to set the height and width of an image in the JS file. Any good ways on doing this?
Once you have a reference to your image, you can set its height and width like so:
var yourImg = document.getElementById('yourImgId');
if(yourImg && yourImg.style) {
yourImg.style.height = '100px';
yourImg.style.width = '200px';
}
In the html, it would look like this:
<img src="src/to/your/img.jpg" id="yourImgId" alt="alt tags are key!"/>
You can change the actual width/height attributes like this:
var theImg = document.getElementById('theImgId');
theImg.height = 150;
theImg.width = 150;
If you want to resize an image after it is loaded, you can attach to the onload event of the <img> tag. Note that it may not be supported in all browsers (Microsoft's reference claims it is part of the HTML 4.0 spec, but the HTML 4.0 spec doesn't list the onload event for <img>).
The code below is tested and working in: IE 6, 7 & 8, Firefox 2, 3 & 3.5, Opera 9 & 10, Safari 3 & 4 and Google Chrome:
<img src="yourImage.jpg" border="0" height="real_height" width="real_width"
onload="resizeImg(this, 200, 100);">
<script type="text/javascript">
function resizeImg(img, height, width) {
img.height = height;
img.width = width;
}
</script>
Changing an image is easy, but how do you change it back to the original size after it has been changed? You may try this to change all images in a document back to the original size:
var i,L=document.images.length;
for(i=0;i<L;++i){
document.images[i].style.height = 'auto'; //setting CSS value
document.images[i].style.width = 'auto'; //setting CSS value
// document.images[i].height = ''; (don't need this, would be setting img.attribute)
// document.images[i].width = ''; (don't need this, would be setting img.attribute)
}
you can see the result here
In these simple block of code you can change the size of your image ,and make it bigger when the mouse enter over the image , and it will return to its original size when mouve leave.
html:
<div>
<img onmouseover="fifo()" onmouseleave="fifo()" src="your_image"
width="10%" id="f" >
</div>
js file:
var b=0;
function fifo() {
if(b==0){
document.getElementById("f").width = "300";
b=1;
}
else
{
document.getElementById("f").width = "100";
b=0;
}
}
Direct manipulation
HTML tag declaration for image:
<img id="my-img" src="src/to/your/image.jpg" width="1280px" height="720px" />
<!-- OR -->
<img id="my-img" src="src/to/your/image.jpg" style="width: 1280px; height: 720px;" />
Handling html tag by direct access to object image:
const myImg = document.getElementById("my-img");
// Set a new width and height
myImg.style.width = "800px";
myImg.style.height = "450px";
// Or set a new width and height by attribute
// This option is not advisable because the attribute has a
// low priority over the style property.
myImg.setAttribute("width", 800);
myImg.setAttribute("height", 450);
Functions for manipulation
Using the updateImageSizeWithWidth or updateImageSizeWithHeight method below, you can increase or decrease any image without having to explicitly specify the exact width and height, you only need one value out of these two to update the image size.
/**
* Update image size using width
*
* param {HTMLImageElement} img
* param {number} newWidth
*/function updateImageSizeWithWidth(img, newWidth) {
// Getting the width and height of the current image
const oldWidth = Number.parseFloat(getComputedStyle(img).width || img.getAttribute("width"));
const oldHeight = Number.parseFloat(getComputedStyle(img).height || img.getAttribute("height"));
// Getting proportional height with new width
const newHeight = (newWidth * oldHeight)/oldWidth;
// Setting dimensions in the image
img.style.width = `${newWidth}px`;
img.style.height = `${newHeight}px`;
}
/**
* Update image size using height
*
* param {HTMLImageElement} img
* param {number} newHeight
*/
function updateImageSizeWithHeight(img, newHeight) {
// Getting the width and height of the current image
const oldWidth = Number.parseFloat(getComputedStyle(img).width || img.getAttribute("width"));
const oldHeight = Number.parseFloat(getComputedStyle(img).height || img.getAttribute("height"));
// Getting proportional height with new width
const newWidth = (newHeight * oldWidth)/oldHeight;
// Setting dimensions in the image
img.style.width = `${newWidth}px`;
img.style.height = `${newHeight}px`;
}
updateImageSizeWithWidth(myImg, 800);
// Or
updateImageSizeWithHeight(myImg, 450);
// This one has print statement so you can see the result at every stage if you would like. They are not needed
function crop(image, width, height)
{
image.width = width;
image.height = height;
//print ("in function", image, image.getWidth(), image.getHeight());
return image;
}
var image = new SimpleImage("name of your image here");
//print ("original", image, image.getWidth(), image.getHeight());
//crop(image,200,300);
print ("final", image, image.getWidth(), image.getHeight());
You can do this:
.html file:
<img src="src/to/your/img.jpg" id="yourImgId"/>
.js file:
document.getElementById("yourImgId").style.height = "heightpx";
The same you can do with the width.
I'm working on an app that is dynamically generating images with Javascript's image() object. Code below, where object is the URL I am passing in -
resizeImage: function(object) {
var img = new Image();
img.src = object;
console.log(img);
console.log(img.width);
console.log(img.height);
var ratio;
if(img.width > img.height) {
ratio = 82/img.width;
} else {
ratio = 82/img.height;
}
img.height *= ratio;
img.width *= ratio;
return img;
},
The output of my console log shows the image object is created with source set to URL -
<img src="https://z3nburmaglot.zendesk.com/attachments/token/F0Y7C9UfUcOaA7nCMJfE5T1yB/?name=Show+Support+Tickets+on+Customer+View.png"> and height and width of 0.
Some of the images load fine - they set height and widgth appropriately and if I refresh the JS (run the function again), the images that had 0 height and width suddenly change to the correct height and width.
Any thoughts on why constructing an image this way would fail sometimes?
Sounds like your image hasn't loaded yet when you get its width or height. Then it will be 0.
When you refresh, the image is in your browser cache and will load immediately so its width and height are available straight up.
Use the onload() event of the Image object to execute code once the image has been loaded properly
resizeImage: function(object) {
var img = new Image();
// first set onload event
img.onload = function() {
console.log(img);
console.log(img.width);
console.log(img.height);
var ratio;
if(img.width > img.height) {
ratio = 82/img.width;
} else {
ratio = 82/img.height;
}
img.height *= ratio;
img.width *= ratio;
}
// then set the src
img.src = object;
return img;
},
I have a app that shows coloured dots moving across the screen, following set routes. There is a save button the saves the current screen to a .png format.
The problem I am having is that if I click the save image button several times the images don't just show the current position of that click, they show all previous positions from when the save button was clicked.
E.g. if at click 1 the dot is as position 1 and click 2 it is at position 2. Image two will show positions 1 and 2. A third image would show positions 1,2 and 3.
Obviously there is an issue with layering or not clearing the canvas but I can't see the problem.
the save code (wrapped in an AngularJS app) is :
$scope.saveImage = function() {
var stageWidth = jQuery("#mainStage").width();
var stageHeight = jQuery("#mainStage").height();
var html = d3.select("#mainStage")
.attr("version", 1.1)
.attr("xmlns", "http://www.w3.org/2000/svg")
.attr("width",stageWidth)
.attr("height",stageHeight)
.node().parentNode.innerHTML;
var imgsrc = 'data:image/svg+xml;base64,' + btoa(html);
jQuery("#canvas").height(stageHeight);
jQuery("#canvas").width(stageWidth);
var canvas = document.getElementById("canvas");
var context = document.querySelector('canvas').getContext("2d");
var image = new Image;
image.src = imgsrc;
image.onload = function() {
context.drawImage(image,0,0);
var canvasdata = canvas.toDataURL("image/png");
var pngimg = '<img src="' + canvasdata + '">';
var a = document.createElement("a");
console.log(a);
a.download = "sample.png";
a.href = canvasdata;
a.click();
};
}
Thanks in advance.
This would mean that it has not been through the digest loop. A common problem with mixing jQuery and AngularJs. Add a watcher.
if (yardss > 0.1 && yardss < 0.3) {
var img = document.createElement("img");
img.src = "images/wrench1.jpg";
img.align = "center";
document.body.appendChild(img);
} else if (yardss > 0.3) {
var img = document.createElement("img");
img.src = "images/wrench.jpg";
img.width = 500;
img.height = 300;
document.body.appendChild(img);
}
This script is activated by the user clicking on a button, and it prompts the user to enter a certain number of yards. If the yards are above a certain number, it displays a certain sized wrench. If it is below a certain number, it displays a different sized wrench.
My problem is that because the script can be run over and over again by clicking on the button, every time that the script is run, a new image of a wrench is produced below the previous image, creating a really long web page with a lot of images.
How do I make the newly created image replace the image created from the previous running of the script, instead of having the page fill with images from the script being run multiple times?
Use replaceChild instead of appendChild.
You can just change the .src property on the current image. There is no need to create a whole new image:
// get the current image object
// assumes you set id="wrenchImg" on it
var img = document.getElementById("wrenchImg");
if (yardss > 0.1 && yardss < 0.3) {
img.src = "images/wrench1.jpg";
img.height = ... // set this to whatever you need it to be for this image
img.width = ... // set this to whatever you need it to be for this image
img.align = "center";
} else if (yardss > 0.3) {
img.src = "images/wrench.jpg";
img.height = 300;
img.width = 500;
img.align = "left";
}
If you have any other properties of the image that must also be changed (height or width or alignment, for example), then you can add those to each branch of the if/else, but doing it this way, you have to fully initialize the image object because it may have been set a different way based on the previous image.
Don't create the img element again and again. Just create once and set some id on it. Then just change the src and width, height etc..
In HTML:
<img id= "wrench_img"/> // Setting id as wrench_img
In JavaScript:
function changer(yardss) {
var img1 = document.getElementById("wrench_img"); // Get the img
if (yardss > 0.1 && yardss < 0.3) {
img1.src = "images/wrench1.jpg"; // Change the src
img1.align = "center";
} else if (yardss > 0.3) {
img1.src = "images/wrench.jpg"; // Change the src
img1.width = 500; // Change width
img1.height = 300;
}
}
In your code, you were appending new image elements to the document.body. That is why you were getting multiple image elements. But if you look at this code, we don't create the image elements multiple times. We just change the one created.
Online Demo
I'm building a jQuery plugin which watermarks images (and yes, i'm well aware of the multitudinal drawbacks of a javascript/html5 watermarking system but just ignore that for now.) The basic method for each image is:
paste the image to the background of a canvas
add the data for a watermark image over that,
replace the src of the original image with that of the canvas (which now contains the watermark.)
Now it appears to work fine if I replace the image element with the canvas itself.. all of the elements appear on the canvas. But when I get the dataURL of the canvas, everything but the last image drawn onto it appears. I wouldn't even mind except this plugin also needs to replace the links to images as well, and so replace the hrefs with data urls (with the watermark.)
This is the current code:
(function($){
$.fn.extend({
cmark: function(options) {
var defaults = {
type: 'image',
content: 'watermark.png',
filter: 'darker',
scale:300,
box: {
top : 0.5,
left : 0.5,
width : 0.75,
height : 0.75,
bgcolor : '#000000',
bgopacity : 0.5,
fgopacity : 1
},
callback_unsupported: function(obj){
return obj;
}
}
var getScale = function(w, h, scale){
ratio = Math.min(scale/w, scale/h);
scalew = Math.round(ratio*w);
scaleh = Math.round(ratio*h);
return [scalew,scaleh];
}
var options = $.extend(defaults, options);
return this.each(function() {
obj = $(this);
canvas = document.createElement('canvas');
if(!window.HTMLCanvasElement){
return options.callback_unsupported(obj);
}
/* if selecting for images, reset the images. Otherwise,
we're replacing link hrefs with data urls. */
if(obj.attr('src')){
target_img = obj.attr('src');
}
else if (obj.attr('href')){
target_img = obj.attr('href');
}
// get the filetype, make sure it's an image. If it is, get a mimetype. If not, return.
ftype = target_img.substring(target_img.lastIndexOf(".")+1).toLowerCase();
canvasbg = new Image();
canvasbg.onload = function(){
iw = canvasbg.width;
ih = canvasbg.height;
scale = getScale(iw, ih, options.scale);
iw = scale[0];
ih = scale[1];
canvas.setAttribute('width', iw);
canvas.setAttribute('height', ih);
ctx = canvas.getContext('2d');
/* define the box as a set of dimensions relative to the size of the image (percentages) */
bw = Math.round(iw * options.box.width);
bh = Math.round(ih * options.box.height);
// for now the box will only ever be centered.
bx = Math.round((iw * options.box.top) - (bw/2));
by = Math.round(ih * options.box.left - (bh/2));
/* draw the box unless the opacity is 0 */
if(options.box.bgopacity > 0){
ctx.fillStyle = options.box.bgcolor;
ctx.globalAlpha = options.box.bgopacity;
ctx.fillRect(bx, by, bw, bh);
}
wm = new Image();
wm.onload = function(){
ww = wm.width;
wh = wm.height;
scalar = Math.max(bw, bh); // scale to within the box dimensions
scale = getScale(ww, wh, scalar);
ww = scale[0];
wh = scale[1];
ctx.globalCompositeOperation = options.filter;
ctx.drawImage(wm, bx, by, ww, wh);
}
wm.src = options.content;
ctx.drawImage(canvasbg, 0, 0, iw, ih);
obj.replaceWith(canvas);
$('body').append('<img src="'+canvas.toDataURL()+'">');
//obj.attr('src', canvas.toDataURL());
}
canvasbg.src = target_img;
});
}
})
})(jQuery);
I added a line which dumps an image with the data url directly onto the page for testing and this is what I see... on the left is the canvas element, on the right is the image with the data url:
So yeah, this has had me stumped for a couple of days now. I'm probably missing something horribly obvious but I can't see it.
... edited because the example is no longer online. sorry.
First of all, don't build a string buffer that big for a tag.
var img = new Image();
img.src = canvas.toDataURL();
$('body').append(img);
Or if you prefer:
$('body').append($('<img>').attr('src', canvas.toDataURL()))
Second, you are getting there dataURL of the canvas before you draw the watermark. The drawing happens in the wm.onload callback function, which happens when the watermark loads. That may not fire until way after canvasbg.onload fires off, which is where you get the dataURL.
So move the image append into code at the end of the wm.onload callback and you should be good.