Overlay button over all images - javascript

Basically i want to loop through the html and get all the pictures and overlay a small button on them on hover, so when the user is clicking on that button, a bunch of info about that picture will appear. Right now i can overlay a small icon over a photo that will generate a popup when it's clicked, but i don't know how to dynamically add a icon on all photos on hover. This is what i've done so far http://jsfiddle.net/s5sp1h6e/1/
//Getting all the images
function getAllImages()
{
var images = document.getElementsByTagName('img');
var srcList = [];
for(var i = 0; i < images.length; i++)
{
srcList.push(images[i].src);
}
}
I've found a script that overlays a image over all images but every time i'm changing the size of the image i'm overlaying, the script stops working and i can't understand why.
If i want to change in this line the width and the height to be given hardcoded, the script stops working.
var overlay = $('<img class="protectionOverlay" src="' + overlayImg + '" width="' + img.width() + '" height="' + img.height() + '"/>') bla bla..
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
$(function()
{
var overlayImg = 'http://www.privdog.com/PrivDog/logo-medium.png';
var useOnAllImages = true;
// Preload the pixel
var preload = new Image();
preload.src = overlayImg;
$('img').on('mouseenter touchstart', function(e)
{
// Only execute if this is not an overlay or skipped
var img = $(this);
if (img.hasClass('protectionOverlay')) return;
if (!useOnAllImages && !img.hasClass('protectMe')) return; // The script will be applied to all images. IF u don't want this -> useOnAllImages = false and class="protectMe"
// Get the real image's position, add an overlay
var pos = img.offset();
//var xx = overlayImg.offset();
//alert(xx.top);
var overlay = $('<img class="protectionOverlay" src="' + overlayImg + '" width="' + img.width() + '" height="' + img.height() + '"/>').css({position: 'absolute', zIndex: 9999999, left: pos.left, top: pos.top}).appendTo('body').bind('mouseleave', function()
{
setTimeout(function(){ overlay.remove(); }, 0, $(this));
});
if ('ontouchstart' in window) $(document).one('touchend', function(){ setTimeout(function(){ overlay.remove(); }, 0, overlay); });
});
}

Basically you need to add a an event handler for mouseover and mouseout. In the handler apply the necessary changes to the image.
$("img").on("mouseover", function () {
$(this).addClass("overlay-class");
var icon = $("<span class='icon' />").appendTo(document.body);
// logic to position the icon
}).on("mouseout", function () {
$(this).removeClass("overlay-class");
$(".icon").remove();
});

Related

Javascript: Why svg gets converted into a png with dark background?

I have svg images in my page:
And I use to convert to png images (and download them):
https://github.com/CogComp/apelles/blob/master/public/index.html#L370-L390
var mySVG = $("#" + id + " svg")[0];
var imgId = id + "-img";
$(document.body).append('<img height="' + mySVG.getBBox().height + '" width="' + mySVG.getBBox().width + '" id="' + imgId + '" style="visibility: hidden; "/>');
var tgtImage = document.getElementById(imgId); // Where to draw the result
var can = document.createElement('canvas'); // Not shown on page
var ctx = can.getContext('2d');
var loader = new Image;
loader.width = can.width = tgtImage.width;
loader.height = can.height = tgtImage.height;
loader.onload = function () {
ctx.drawImage(loader, 0, 0, loader.width, loader.height);
tgtImage.src = can.toDataURL();
};
var svgAsXML = (new XMLSerializer).serializeToString(mySVG);
loader.src = 'data:image/svg+xml,' + encodeURIComponent(svgAsXML);
sleep(500).then(() => {
var url = tgtImage.src.replace(/^data:image\/[^;]/, 'data:application/octet-stream');
window.open(url);
});
Here is the output. Why is the output turned dark?
I tried changing the background color but didn't help.
Here is the link to the page btw: http://nlp.cogcomp.org/
Update: Checking the SVG code I think I have a background:
Despite having a background, I tried adding a background to the picture, but doesn't seem to help. Here are a couple of variations I have tried:
var svgQ = $("#" + id + " svg");
var mySVG = svgQ[0];
var rect = document.createElementNS(svgQ,'rect');
rect.setAttribute('x',10);
rect.setAttribute('y',10);
rect.setAttribute('width',50);
rect.setAttribute('height',50);
rect.setAttribute('fill','#EFEFEF');
mySVG.appendChild(rect);
// or mySVG.append(rect);
$("svg").each(function(){
$(this).css({ fill: '#000' });
// or $(this).attr("fill", '#000');
// or $(this).attr("fill", '#000000');
});
svgQ.css({ fill: '#000' });
// or svgQ.attr("fill", '#000');
// or svgQ.attr("fill", '#000000');

select image from a series of image and place it to canvas in 1 function

I am Alex and this is my first stack overflow question.
I have the below script.
-This script gets images from an api.
-For each image received from the api, an element is created
-for each image, a class attribute is created
-for each image, an id attribute is created.
-for each image, a element is created. For each of the , I dynamically append an onclick event. each onclick is associated with its own function.
the anchor1,2,3,4 and 5 function are made so each time a user clicks a selected image, that image is then place into a canvas. When that is done, the color thief js kicks in and displays the color palette of the image selected.
All of that works perfectly.
What I would like to do is instead of having a function for each image, is to have 1 function that would place the image clicked into the canvas.
Basically i think my code can be made less redundant.
// search the collection using a JSON call
function search(query) {
return $.getJSON("https://www.rijksmuseum.nl/api/en/collection?q=Q&key=r4nzV2tL&imgonly=True&ps=5&format=json".replace("Q", query));
}
var searchBtn = document.getElementById("search");
searchBtn.addEventListener("click", doSearch);
var resultD = document.getElementById("result");
var searchField = document.getElementById("query");
//search function starts here
function doSearch() {
$("#result").show(); // result div to show when making new search
resultD.innerHTML = "";
var searchString = searchField.value;
if (searchString !== "") {
search(searchString).done(function(data) {
for (var artObj in data.artObjects) {
var rImg = document.createElement("img"); // create the image
rImg.setAttribute("crossOrigin", "Anonymous"); //needed so I can actually copy the image for later use
rImg.setAttribute("class", "imageClass"); //needed so I can actually copy the image for later use
var link = document.createElement("a"); // create the link
link.setAttribute('href', '#'); // set link path
// link.href = "www.example.com"; //can be done this way too
rImg.src = data.artObjects[artObj].webImage.url; // the source of the image element is the url from rijks api
link.appendChild(rImg); // append image to link
resultD.appendChild(link); // append link with image to div
resultD.innerHTML += data.artObjects[artObj].title; // this is the title from rijks api
$("#result img").each(function (i, image){ //for each image create a different id
image.id = "image" + (i + 1);
});
$("#result a").each(function (i, anchor){ //for each anchor create a different id
anchor.id = "anchor" + (i + 1);
anchor.setAttribute('onclick', "anchor" + (i + 1)+'();return false;'); // set link path
//return false needed so to avoid page jump
});
resultD.innerHTML += "<br> <br> <br> <br>";
}
});
}
}//search function ends here
//for each image create size matching canvas
function anchor1(){
var c=document.getElementById("drawing1");
var ctx=c.getContext("2d");
var img=document.getElementById("image1");
c.height = img.height ;
c.width = img.width ;
ctx.drawImage(img,0,0,c.width, c.height);
$("#result").hide();
setTimeout(function() { //timeout for image load to canvas - start
var colorThief = new ColorThief();
var color = colorThief.getPalette(img, 18);
var newHTML = $.map(color, function(value) {
return('<div style="background-color:rgb(' + value.join(', ') + ')"> </div>'+'<br>');
});
$("#colors").html(newHTML.join(''));
}, 500); //timeout for image load to canvas - ends
}
function anchor2(){
var c=document.getElementById("drawing1");
var ctx=c.getContext("2d");
var img=document.getElementById("image2");
c.height = img.height ;
c.width = img.width ;
ctx.drawImage(img,0,0,c.width, c.height);
$("#result").hide();
setTimeout(function() { //timeout for image load to canvas - start
var colorThief = new ColorThief();
var color = colorThief.getPalette(img, 18);
var newHTML = $.map(color, function(value) {
return('<div style="background-color:rgb(' + value.join(', ') + ')"> </div>'+'<br>');
});
$("#colors").html(newHTML.join(''));
}, 500); //timeout for image load to canvas - ends
}
function anchor3(){
var c=document.getElementById("drawing1");
var ctx=c.getContext("2d");
var img=document.getElementById("image3");
c.height = img.height ;
c.width = img.width ;
ctx.drawImage(img,0,0,c.width, c.height);
$("#result").hide();
setTimeout(function() { //timeout for image load to canvas - start
var colorThief = new ColorThief();
var color = colorThief.getPalette(img, 18);
var newHTML = $.map(color, function(value) {
return('<div style="background-color:rgb(' + value.join(', ') + ')"> </div>'+'<br>');
});
$("#colors").html(newHTML.join(''));
}, 500); //timeout for image load to canvas - ends
}
function anchor4(){
var c=document.getElementById("drawing1");
var ctx=c.getContext("2d");
var img=document.getElementById("image4");
c.height = img.height ;
c.width = img.width ;
ctx.drawImage(img,0,0,c.width, c.height);
$("#result").hide();
setTimeout(function() { //timeout for image load to canvas - start
var colorThief = new ColorThief();
var color = colorThief.getPalette(img, 18);
var newHTML = $.map(color, function(value) {
return('<div style="background-color:rgb(' + value.join(', ') + ')"> </div>'+'<br>');
});
$("#colors").html(newHTML.join(''));
}, 500); //timeout for image load to canvas - ends
}
function anchor5(){
var c=document.getElementById("drawing1");
var ctx=c.getContext("2d");
var img=document.getElementById("image5");
c.height = img.height ;
c.width = img.width ;
ctx.drawImage(img,0,0,c.width, c.height);
$("#result").hide();
setTimeout(function() { //timeout for image load to canvas - start
var colorThief = new ColorThief();
var color = colorThief.getPalette(img, 18);
var newHTML = $.map(color, function(value) {
return('<div style="background-color:rgb(' + value.join(', ') + ')"> </div>'+'<br>');
});
$("#colors").html(newHTML.join(''));
}, 500); //timeout for image load to canvas - ends
}
You want to utilize the .on event with jquery which allows you to deal with dynamic data which is basically what you are dealing with.
You are generating different <a> links with an individual id to call your different functions like (anchor1, anchor2...) with $("#result a").each(function (i, anchor){ //for each anchor create a different id anchor.id = "anchor" + (i + 1);
Instead of generating a different id for each <a> just give them the same value, but make it a class and not a id. Id's should always be unique and never repeat, classes can be repeated. For instance <a class="anchor"><...</a>
Then when you want to deal with the data from that particular record/image you would call it as such.
$(document).on('click','.anchor', function () {
});
So here is a working example you can start with.
<a class="anchor" data-id="1">...</a>
$(document).on('click','.anchor', function () {
var anchor_id = $(this).attr('data-id').val();
var c=document.getElementById("drawing1");
var ctx=c.getContext("2d");
var img=document.getElementById("image"+anchor_id); //this will attach the id for that image here
c.height = img.height ;
c.width = img.width ;
ctx.drawImage(img,0,0,c.width, c.height);
$("#result").hide();
setTimeout(function() { //timeout for image load to canvas - start
var colorThief = new ColorThief();
var color = colorThief.getPalette(img, 18);
var newHTML = $.map(color, function(value) {
return('<div style="background-color:rgb(' + value.join(', ') + ')"> </div>'+'<br>');
});
$("#colors").html(newHTML.join(''));
}, 500); //timeout for image load to canvas - ends
});
http://api.jquery.com/on/
https://learn.jquery.com/events/handling-events/
http://html-tuts.com/jquery-this-selector/

Image Preloading for animation

I have a banner at the top of some of my webpages. The banner is static until the user clicks on the play button which kick starts the animation.
The animation is one long horizontal image that just rolls around and iv got it overlapping perfectly.
But what I want to happen is to have a smaller alternative image to load first, while the large image loads behind then once it is loaded to replace the original small image so there is no delay on the page...
How do I go about this?
This is my js to get the banner to play on click.
$(document).ready(function()
{
var mwbannerfull = $( '#mwbannerfull' );
var playing = false;
var playarrow = $( '.playarrow' );
var speed = 0.145;
var totalDistance = 4350;
playarrow.click(function()
{
if (playing)
pause();
else
play();
playing = !playing
playarrow.toggleClass('playing');
});
function play()
{
var distance = parseInt(mwbannerfull.css('left'), 10) * -1;
if (isNaN(distance)) distance = 0;
distance = totalDistance - distance;
var time = distance / speed;
mwbannerfull.animate({left: '-' + totalDistance + 'px'}, time, 'linear', function()
{
$(this).css(
{
left: 0
});
play();
});
}
function pause()
{
mwbannerfull.stop();
}
});
HTML:
<div id="mwprobanner">
<a href="#!" class="playarrow">
<i class="icon-play"></i>
<i class="icon-pause"></i>
</a>
<div id="mwbannerfull"></div>
</div>
data-l will store your large image
<img data-l='https://www.google.com.hk/images/srpr/logo11w.png' src='http://www.microsoft.com/global/learning/en-us/PublishingImages/ms-logo-site-share.png' />
 
function startLoading() {
$("img").each(function () {
var _this = $(this);
var src = $(this).attr('data-l');
if (src != "") {
var tmp = $(new Image());
//When loaded
tmp.one('load', function () {
_this.replaceWith(tmp);
});
tmp.attr('src', src);
}
});
}
Image will start loading after 2 seconds.
setTimeout(function(){
startLoading();
},2000);
http://jsfiddle.net/netorz04/

Detect When the Canvas is Done Drawing - onload - onchange - Javascript

Here is HTML and Code that draws an image into a canvas, after a user has used a file picker.
HTML
<form class='frmUpload'>
<input name="picOneUpload" type="file" accept="image/*" onchange="picUpload(this.files[0])" >
</form>
<button onclick='fncSaveAsJPG()'>Convert Img To JPEG</button>
<canvas id="cnvsForFormat" width="400" height="266"></canvas>
<img id='imgTwoForJPG' src="">
Script
<script>
window.picUpload = function(frmData) {
console.log("picUpload ran: " + frmData);
var cnvs=document.getElementById("cnvsForFormat");
console.log("cnvs: " + cnvs);
var ctx=cnvs.getContext("2d");
cnvs.style.border="1px solid #c3c3c3";
var img = new Image;
img.src = URL.createObjectURL(frmData);
console.log('img: ' + img);
img.onload = function() {
var picWidth = this.width;
var picHeight = this.height;
var wdthHghtRatio = picHeight/picWidth;
console.log('picWidth: ' + Number(picWidth));
console.log('picHeight: ' + Number(picHeight));
console.log('wdthHghtRatio: ' + wdthHghtRatio);
if (Number(picWidth) > 400) {
var newHeight = Math.round(Number(400) * wdthHghtRatio);
} else {
return false;
};
document.getElementById('cnvsForFormat').height = newHeight;
console.log('width: ' + picWidth + " h: " + picHeight);
console.log('width: 400 h: ' + newHeight);
//You must change the width and height settings in order to decrease the image size, but
//it needs to be proportional to the original dimensions.
ctx.drawImage(img,0,0, 400, newHeight);
};
cnvs.onload = function () {
console.log('Onload Canvas 2 Ran');
};
};
cnvsForFormat.onload = function () {
console.log('Onload Canvas Ran');
};
</script>
I've tried attaching the .onload() method to various elements and put the code in various places without any luck. How to I get some code to run with the <canvas> element is done with the drawImage event?

canvas html tag

i have a JavaScript project (using jquery), inside it i draw a canvas by code and then i insert array of images on it. it represents fine without any error.
problem: later on, i try to get these images inside from canvas to compare if they have the same src or the same id to don't replace it with the new image
my functions are:
var inter;
var screen;
function onClick(id){
getScreen(id, function(data){
screen=window.open('',id,'width=' + data.maxX + ',height=' + data.maxY , true);
if (screen.document.getElementById("screen") != null ){
screen.document.getElementById("screen").innerHTML = "";
}
screen.document.write('<div id="screen"><canvas id="screenCanvas" width=' +
data.maxX + ' height=' + data.maxY +
' style="border:2px solid #000000;color:#000000;" ></canvas></div>');
draw(data);
inter = setInterval(function(){screen(id); }, 5000);
});
}
function screen(id){
getScreen(id, function(data){
if (screen.closed == true){
clearInterval(inter);
return;
}
if((screen.document.getElementById('screenCanvas').width != data.maxX) ||
(data.maxY != screen.document.getElementById('screenCanvas').height)){
screen.close();
screen=window.open('',id,'width=' + data.maxX + ',height=' + data.maxY , true);
screen=window.open('',id,'width=' + data.maxX + ',height=' + data.maxY , true);
if (screen.document.getElementById("screen") != null ){
screen.document.getElementById("screen").innerHTML = "";
}
screen.document.write('<div id="screen"><canvas id="screenCanvas" width=' +
data.maxX + ' height=' + data.maxY +
' style="border:2px solid #000000;color:#000000;" ></canvas></div>');
draw(data);
});
}
function draw(data) {
var canvas = screen.document.getElementById('screenCanvas');
var context = canvas.getContext('2d');
var tileY = 0;
var tileX = 0;
var counter = 0;
var tileWidth = data.tileWidth;
var tileHeight = data.tileHeight;
for (var i=0;i<(data.maxX/data.tileWidth);i++){
for (var j=0;j<(data.maxY/data.tileHeight);j++){
var img = new Image();
img.onload = (function(img, tileX, tileY, tileWidth, tileHeight){
return function() {
context.drawImage(img,tileX, tileY, tileWidth, tileHeight);
}
})(img, tileX, tileY, tileWidth, tileHeight);
img.src = "http://myserver:8080/images/screen/tile/" +
data.tiles[counter].imageId;
tileX = tileX + parseInt(data.tileWidth);
counter ++;
}
tileY = tileY + parseInt(data.tileHeight);
tileX = 0;
}
}
</script>
this code gets an array (data) that contains list of (id, maxX, maxY, tileWidth, tileHeight, tiles[x, y, imageId]) and open new window, then write in this window the canvas code and draw images then calls a timer to work each 5 seconds. after each 5 seconds, screen method calls to re-get the data again and check if screen open then it remove all inner html to rewrite new canvas, and it tests if sizes changes.
this code works fine without any error, but i need to edit these code to get images inside canvas and test it they has the same imageId, don't download it again.(i don't save image id, to get images by, we can store it in img.id, or get images by src since, imageId is a part of image path that makes it unique).
Note:
id[unique](is the id of the user),
maxX(maximum width of the screen),
maxY(maximum height of the screen),
tileWidth(width of each image),
tileHeight(height of each image),
tiles(list of images)
x(left position of the image)
y(top postion of the image)
imageId[unique](id of each image)
example: data[id:1,maxX:1920,maxY:1080,tileWidth:480,tileHeight:270,tiles:(x:2,y:1,imageId:1a)]
any help?
as Ravi Jain said you can't get the image drawn to canvas object, and as robertc said you can use img element.
try these functions that specify the usage of img element not canvas:
function onClick(id){
getScreen(id, function(data){
var inter;
var screen;
var width = parseInt(data.maxX) + parseInt(data.tileWidth);
var height = parseInt(data.maxY) + parseInt(data.tileHeight);
screen=window.open('',id,'width=' + width + ',height=' + height , true);
draw(screen, data);
inter = setInterval(function(){screen(screen, inter, id); }, 5000);
});
}
function screen(screen, inter, id){
getScreen(id, function(data){
if (screen.closed == true){
clearInterval(inter);
return;
}
if((screen.document.getElementById("screen").style.width != data.maxX + "px") ||
(screen.document.getElementById("screen").style.height != data.maxY + "px")){
screen.close();
var width = parseInt(data.maxX) + parseInt(data.tileWidth);
var height = parseInt(data.maxY) + parseInt(data.tileHeight);
screen=window.open('',id,'width=' + width + ',height=' + height , true);
}
draw(screen, data);
});
}
function draw(screen, data) {
var screenDiv = screen.document.getElementById("screen");
if (screenDiv == null) screen.document.write('<div id="screen" style="width:' +
data.maxX + '; height:' + data.maxY + '; " style="margin: 0 auto;" >');
var tileY = 0;
var tileX = 0;
var counter = 0;
for (var i=0;i<(data.maxX/data.tileWidth);i++){
for (var j=0;j<(data.maxY/data.tileHeight);j++){
var imageSource = screen.document.getElementById("id_" + counter);
var path = "http://myserver:8080/images/screen/tile/" +
data.tiles[counter].imageId;
if (imageSource == null){
screen.document.write('<img id="id_' + counter + '" src="' + path +
'" height="' + data.tileHeight + '" width="' + data.tileWidth + '" />');
}else if(imageSource.src != path){
imageSource.src = path;
}
tileX = tileX + parseInt(data.tileWidth);
counter ++;
}
tileY = tileY + parseInt(data.tileHeight);
tileX = 0;
}
if (screenDiv == null) screen.document.write('</div>');
}
</script>
your code are working fine that's true, but for one instance only, you declare var screen and var inter at the top of the script not in the function, this means that if you click on the first user to get it's screen (as what i understood of your code, what your project did), the timer of the first user stops and of the second user starts. this code that i wrote solve this problem and your problem to replace the source of the image if it changes.
hope this help you man,
GOOD LUCK;
Once you've drawn something on canvas it's pixels. It doesn't retain the object that was used to create those pixels. If you want this sort of information then you either need to maintain it yourself outside of canvas, or use something which retains objects for you like SVG.

Categories