Solved

how to load canvas in jquery not from image but background-image?

Posted on 2014-03-08
15
782 Views
Last Modified: 2014-03-12
Hi,

So here is my problem: I want to load canvas from the background image of a div
and not direct from an image and I fail.
Does some one know how to do that?

I show the method I use for canvas from an image and that is OK:

	
<img class="bigimage" id = "IMG1a"  alt="" src="img/ET1_448.jpg" width="100">
		<img class="bigimage" id = "IMG2a"  alt=""  src="img/ET2_448.jpg" width="100">
		<img class="bigimage" id = "IMG3a"  alt=""  src="img/ET3_448.jpg" width="100">


         	<div class="autocenter"><canvas id="myCanvas_OUT0" width="303" height="539"></canvas></div>

Open in new window


and the JQUERY

$(".bigimage").click( function() {

	img_srcout0="";
	img_srcout0 = $(this).attr("id");
	
	 elemout0 = document.getElementById("myCanvas_OUT0");
	if (elemout0 && elemout0.getContext) 
		{
		   contextout0 = elemout0.getContext("2d");
		  
		  if (contextout0) 
			{
			 imgout0=document.getElementById(img_srcout0);
			contextout0.drawImage(imgout0,0,0);
			}
			
		}
	
	 imgdout0 = contextout0.getImageData(0, 0, 303,539);
	 pixout0 = imgdout0.data;
	
	
});

Open in new window


and that is fine.

But  for responsive reason I want to use backgroundimages  and here I fail to find a solution:


I try with backgound image in a sprite

	<div id="id-menu" class="c-menu">
		SPRITE<br/>
		<ul class="icone">
			<a href="#" id = "IMG1" ><li class="icone-1" id = "IMG1child" ></li></a>
			<a href="#" id = "IMG2" ><li class="icone-2" id = "IMG2child" ></li></a>
			<a href="#" id = "IMG3" ><li class="icone-3" id = "IMG3child" ></li></a>
			<a href="#" id = "IMG4" ><li class="icone-4" id = "IMG4child" ></li></a>
			</ul>
		</ul>
		</div>

Open in new window



with the JQUERY

$("a").click( function() {
img_srcout0="";
	img_srcout0= $(this).children(":first").attr("id"); //.css('background-image'); BAD
	alert(img_srcout0);

	 elemout0 = document.getElementById("myCanvas_OUT0");
	if (elemout0 && elemout0.getContext) 
		{
		   contextout0 = elemout0.getContext("2d");
		  
		  if (contextout0) 
			{
			 imgout0=document.getElementById(img_srcout0);
			contextout0.drawImage(imgout0,0,0);
			}
			
		}
	
	 imgdout0 = contextout0.getImageData(0, 0, 303,539);
	 pixout0 = imgdout0.data;
	
	
});

Open in new window


and the CSS


.icone
{
margin-left:0px;
}


.icone-1 { background-position: left top }
.icone-2 { background-position: 14.2857% top }
.icone-3 { background-position: 28.5714% top }
.icone-4 { background-position: 42.8571% top }
.icone-5 { background-position: 57.1428% top }
.icone-6 { background-position: 71.4285% top }
.icone-7 { background-position: 85.7142% top }
.icone-8 { background-position: right top }





ul
{
padding:0px;
border:3px solid blue;
display: inline-block;
}

.icone li {
	margin:auto;
	text-align:center; /* non*/	
	vertical-align:bottom;
	padding:0px;
	width: 75px;
	height: 100px;
	border-radius:16px;
	border: solid white 5px;
	opacity: 1;
	background-image: url("http://www.davidinlove.com/img/sprite_menu_DT.jpg");
	background-repeat: no-repeat;
	display: inline-block;
	list-style-type:none;
}

Open in new window



Thanks if Some One knows how to do that.

For me it is important to use in a responsive way and for loading times of sprite
faster.

Loading a lot of images is long for tablet.


Thanks in advance DAVID
0
Comment
Question by:DavidInLove
  • 8
  • 4
  • 3
15 Comments
 
LVL 58

Expert Comment

by:Gary
ID: 39915319
What is it you want to happen when you click the images - confused.
0
 

Author Comment

by:DavidInLove
ID: 39915549
Hi,

It is a tool in my website.
When I click on the image it duplicates the image in a canvas.

My problem is I can only do it from an image and I fail to do that from a background image.

You can click on this page where I show the problem:

build canvas from image src or background-image
0
 
LVL 58

Expert Comment

by:Gary
ID: 39915900
So you want to take that sprite image, show the part of it that was clicked in the canvas and you want it to be responsive as well.
0
 

Author Comment

by:DavidInLove
ID: 39917443
"So you want to take that sprite image, show the part of it that was clicked in the canvas and you want it to be responsive as well. "

Yes  I want to use sprite background-image because that enables being responsive using mediaquery in CSS and that I know how to do it.

My question is: how to duplicate a background-image in a canvas, and that I fail I can just do it from a real image.

Thanks for your time.

David
0
 
LVL 58

Expert Comment

by:Gary
ID: 39917860
Background images are not fully responsive, you can easily set one dimension responsive the the other dimension must be static.
Else you have to write up a lot of js to calculate the width, get the ratio, and then work out what the height needs to be.
So if you are happy with just the width being responsive I'll have a go at something
0
 

Author Comment

by:DavidInLove
ID: 39920392
Yes Gary,

I use the MQ in CSS with the device width and I set the width of the background-image.
Of course the image I load is not so much heavy for mobile than desktop.

But here is not exactly my problem.

What I cannot do is to click on a div with a background image and to construct the canvas with that.

Thanks for your answers and maybe you can help even if I believe to think that there is no solution because I've post this question in some places forum in the internet but nobody seems to understand or give a solution for this part of the problem.

I may be not clear engough.

Happy to hear from you.


David
0
 
LVL 35

Accepted Solution

by:
Robert Schutt earned 500 total points
ID: 39920474
Hi David,

I may have a solution for you. However, it works "stand-alone" but then I saw you posted a link to your website and I tried implementing it in a local copy and it didn't work quite as well regarding the next functionality: copying from left to right canvas (although the image is shown ok).

In short, what the code does is get the url to the image, make a new Image() from it (because the background-image from CSS doesn't appear in the DOM as far as I can tell so can't be used but it should be loaded from cache). Then, from the background-position it is determined which part of the sprite image needs to be drawn on the canvas. That part works (with your current CSS) but as I said, I think something goes wrong in the rest of the functionality because of the changes I made.

Here is a link to the stand-alone version where I worked on a canvas that has the same size as the source pictures: http://schutt.nl/ee/Q_28383720/

And here is the (slightly different) code I tried in your page (replacing your current "a".click() function):
function custompos(p, isY, cnv, img) {
  var ti, tc;
  if (isY) {
    ti = img.height;
    tc = 100; // cnv.height;
    p = p.replace('top', '0').replace('bottom', '100%'); // ti - tc
  } else {
    ti = img.width;
    tc = 75; // cnv.width;
    p = p.replace('left', '0').replace('right', '100%'); // ti - tc
  }
  if (p.substr(-1) == '%') {
    p = Number(p.substr(0, p.length - 1)) * (ti - tc) / 100;
  }
  return p;
}

$("a").click( function(e) {
  e.preventDefault();
  img_srcout0="";
  img_srcout0 = $(this).children(":first").css('background-image').replace(/^url\((['"]?)(.*?)\1\).*$/i, "$2");
  var bpos = $(this).children(":first").css('background-position'); // remember for later
  elemout0 = document.getElementById("myCanvas_OUT0");
  if (elemout0 && elemout0.getContext) 
  {
    contextout0 = elemout0.getContext("2d");
    if (contextout0) 
    {
      imgout0=new Image();
      imgout0.onload=function(){ // run the rest of the code after image has loaded (only after setting the src below)

        // some extra code to get position, this is not completely generic!
        var bposa = bpos.split(' ');
        var bposx = custompos(bposa[0], false, elemout0, imgout0);
        var bposy = custompos(bposa[1], true, elemout0, imgout0);

        //contextout0.drawImage(imgout0,0,0);
        contextout0.drawImage(imgout0,bposx,bposy,75,100,0,0,300,400);

        imgdout0 = contextout0.getImageData(0, 0, 303,539);
        pixout0 = imgdout0.data;
      };
      imgout0.src = img_srcout0; // set to same image as used in CSS url
    }
  }
});

Open in new window

0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Closing Comment

by:DavidInLove
ID: 39920872
Hi Robert,

This code you have included in your site http://schutt.nl/ee/Q_28383720/ is excellent.

I am really impressed!

I will work with canvas size the same as images in sprites and set value with Media Queries
to be responsive.

Your explainations are also very clear and I understood that I had to load the background-image in the DOM to build the Canvas.

I will test loading speed but I believe that loading the sprite in the cache is faster than working with 8 different images to load in the DOM.

Afterward when the user click on the sprite it needs only load the image from the cache.

I believe that here I have something very important for my website.


Great thanks!!!!
0
 

Author Comment

by:DavidInLove
ID: 39922137
Robert,
in case you look in here, I have finalyzed the code.
Thanks a lot!!

<!DOCTYPE html>
<html>
<head>
<title> EE Q_28383720 </title>
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>

.icone
{
margin-left:0px;
}
.icone-1 { background-position: left top }
.icone-2 { background-position: 14.2857% top }
.icone-3 { background-position: 28.5714% top }
.icone-4 { background-position: 42.8571% top }
.icone-5 { background-position: 57.1428% top }
.icone-6 { background-position: 71.4285% top }
.icone-7 { background-position: 85.7142% top }
.icone-8 { background-position: right top }


@media only screen and (max-width: 600px)
{
ul
{
padding:0px;
border:3px solid blue;
display: inline-block;
}

.icone li {
  margin:auto;
  text-align:center; /* non*/	
  vertical-align:bottom;
  padding:0px;
  width: 75px;
  height: 100px;
  border-radius:16px;
  border: solid white 5px;
  opacity: 1;
  background-image: url("http://www.davidinlove.com/img/sprite_menu_DT.jpg");
  background-repeat: no-repeat;
  display: inline-block;
  list-style-type:none;
}
}


@media only screen and (min-width: 601px)
{
ul
{
padding:0px;
border:3px solid blue;
display: inline-block;
}

.icone li {
  margin:auto;
  text-align:center; /* non*/	
  vertical-align:bottom;
  padding:0px;
  width: 150px;
  height: 200px;
  border-radius:16px;
  border: solid white 5px;
  opacity: 1;
  background-image: url("http://www.davidinlove.com/img/sprite_menu_DT2.jpg");
  background-repeat: no-repeat;
  display: inline-block;
  list-style-type:none;
}
}

</style>
</head>
<body>
  <div id="id-menu" class="c-menu">
    SPRITE<br/>
    <ul class="icone">
      <a href="#" id = "IMG1" ><li class="icone-1" id = "IMG1child" ></li></a>
      <a href="#" id = "IMG2" ><li class="icone-2" id = "IMG2child" ></li></a>
      <a href="#" id = "IMG3" ><li class="icone-3" id = "IMG3child" ></li></a>
      <a href="#" id = "IMG4" ><li class="icone-4" id = "IMG4child" ></li></a>
      <a href="#" id = "IMG5" ><li class="icone-5" id = "IMG5child" ></li></a>
      <a href="#" id = "IMG6" ><li class="icone-6" id = "IMG6child" ></li></a>
      <a href="#" id = "IMG7" ><li class="icone-7" id = "IMG7child" ></li></a>
      <a href="#" id = "IMG8" ><li class="icone-8" id = "IMG8child" ></li></a>
      </ul>
    </ul>
    </div>

<hr>

<span id="mycanvas" ><canvas id="myCanvas_OUT0" width="150" height="200"></canvas> </span>


<script>

function custompos(p, isY, cnv, img) {
  var ti, tc;
  if (isY) {
    ti = img.height;
    tc = cnv.height;
    p = p.replace('top', '0').replace('bottom', '100%'); // ti - tc
  } else {
    ti = img.width;
    tc = cnv.width;
    p = p.replace('left', '0').replace('right', '100%'); // ti - tc
  }
  if (p.substr(-1) == '%') {
    p = Number(p.substr(0, p.length - 1)) * (ti - tc) / 100;
  }
  return p;
}

$("a").click( function(e) {

if (($(window).width())<600)
	$("#mycanvas").html('<canvas id="myCanvas_OUT0" width="75" height="100"></canvas>');
else
	$("#mycanvas").html('<canvas id="myCanvas_OUT0" width="150" height="200"></canvas>');

  e.preventDefault();
  img_srcout0="";
  img_srcout0= $(this).children(":first").css('background-image').replace(/^url\((['"]?)(.*?)\1\).*$/i, "$2");
  var bpos = $(this).children(":first").css('background-position');
  elemout0 = document.getElementById("myCanvas_OUT0");
  if (elemout0 && elemout0.getContext) 
  {
    contextout0 = elemout0.getContext("2d");
    if (contextout0) 
    {
      imgout0=new Image();
      imgout0.onload=function(){

        // some extra code to get position, this is not completely generic!
        var bposa = bpos.split(' ');
        var bposx = custompos(bposa[0], false, elemout0, imgout0);
        var bposy = custompos(bposa[1], true, elemout0, imgout0);
        contextout0.drawImage(imgout0,-bposx,-bposy);

        //imgdout0 = contextout0.getImageData(0, 0, 303,539);
        //pixout0 = imgdout0.data;
      };
      imgout0.src=img_srcout0;
    }
  }
});

</script>



</body>
</html>

Open in new window

0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 39922375
Yes, I do monitor closed questions, if only because I can ;-)

I will definitely have a look because I'm curious what I did wrong and glad you were able to solve it for yourself. Also I was intrigued by what you did with the 2 canvases, drawing the selected color from the first onto the second one, seemed real artsy!
0
 

Author Comment

by:DavidInLove
ID: 39922825
Hi Robert,

Maybe you have been in my website 'painting online Paris'

For instance I enjoy drawing architecture and work in IT.

I found that it was a great help to use photo to have something to help drawing and paint online.

My website is new and looking at my log I saw some people use it slightly mostly from US.

I am working on algorythm now to improve the way to draw.
Until now I find the RGB where you click on canvas and copy it  averaging 5% on the other canvas.

You can also mix different elements of different photos.

That's it!
but also I invest time in seo  webdesign social marketing.

It takes time.

Thanks to you I can make it responsive for what concerns images.

I had a great problem with android tablet for loading image.


Happy to hear from you!
David
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 39922913
Yes, I had a look on your website and tried some painting, it's big fun! My own creativity level is low, but I do like to play around with 'art' on HTML canvas for example: http://schutt.nl/prj/html5/demo_drawrecur2.html
0
 

Author Comment

by:DavidInLove
ID: 39922944
It seems you enjoy mathematics too!
It looks like Mandelbrot fractal.

Do you believe that a dynamic canvas like yours could be doing a background of a website?

It can be very interesting.

If yes I can open a new ticket around this subject.

David
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 39923018
Yes I guess you could put this in the background of a page but it could get very distracting.

If you want my opinion on more questions I'm ok to answer them here or if they are completely unrelated to this you can find my contact details on my profile page. But if you want more opinions, using the strength of the EE community, posting a new question would be the way to go.
0
 

Author Comment

by:DavidInLove
ID: 39923686
Hi Robert,
I've posted it on EE
question on body background canvas


the question is how to have a dynamic canvas as a background.
I would like to create something like you did as canvas in the background of my website body for example.

Thanks David
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

How to build a simple, quick and effective accordion menu using just 15 lines of jQuery and 2 css classes
Not sure what the best email signature size is? Are you worried about email signature image size? Follow this best practice guide.
In this tutorial viewers will learn how to embed custom externally-hosted Google Fonts using the Google Font API in CSS Go to the Google Fonts website at google.com/fonts: Browse or search based on font properties or name to find a suitable font for…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now