Solved

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

Posted on 2014-03-08
15
798 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Webinar: Aligning, Automating, Winning

Join Dan Russo, Senior Manager of Operations Intelligence, for an in-depth discussion on how Dealertrack, leading provider of integrated digital solutions for the automotive industry, transformed their DevOps processes to increase collaboration and move with greater velocity.

 

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
 

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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article describes how to create custom column layout styles for Bootstrap. The article uses 5 columns to illustrate the concept, but the principle can be extended to any number of columns.
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

733 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