• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 908
  • Last Modified:

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

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
DavidInLove
Asked:
DavidInLove
  • 8
  • 4
  • 3
1 Solution
 
GaryCommented:
What is it you want to happen when you click the images - confused.
0
 
DavidInLoveAuthor Commented:
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
 
GaryCommented:
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
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
DavidInLoveAuthor Commented:
"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
 
GaryCommented:
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
 
DavidInLoveAuthor Commented:
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
 
Robert SchuttSoftware EngineerCommented:
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
 
DavidInLoveAuthor Commented:
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
 
DavidInLoveAuthor Commented:
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
 
Robert SchuttSoftware EngineerCommented:
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
 
DavidInLoveAuthor Commented:
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
 
Robert SchuttSoftware EngineerCommented:
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
 
DavidInLoveAuthor Commented:
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
 
Robert SchuttSoftware EngineerCommented:
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
 
DavidInLoveAuthor Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

  • 8
  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now