Change image of an object - html

I want to make so that when I run a function it changes the image of objects in a function and I thought this would work
for(var i = 0; i < heads.length; i++){heads[i].src = ram_head;}
with ram_head equaling a string with the url but when I run the code the image does not change at all when I run the function.
Example of the code: http://jsfiddle.net/themagicalcake/URvA7

Here's code that:
creates an array of image objects (heads)
assigns the same image URL to all of those image objects (rams_head)
and when each image has fully loaded draws that image to the canvas.
Example code and a Demo: http://jsfiddle.net/m1erickson/5DXe7/
var ram_head="https://dl.dropboxusercontent.com/u/139992952/multple/RAMDISEGNO.jpg";
var heads=[];
heads.push(new Image());
heads.push(new Image());
for(var i=0;i<heads.length;i++){
heads[i].onload=function(){
ctx.drawImage(this,this.x,10);
}
heads[i].x=i*100;
heads[i].src=ram_head;
}

I see three issues with the code you've now linked to:
When you set the .src of an Image object, you can't use that image to draw with until the new .src URL image has loaded. If you want to change the .src and then draw, you have to handle the onload event and draw when that fires.
In your onkeydown handler, you are setting heads[i].src, but the image object is heads[i].img so the .src of the image would be heads[i].img.src.
Since you aren't displaying native <img> tags in the DOM, but are instead drawing the image yourself, after you change the .src of the image and then wait for that new image to load, if you want the image to display in your drawing context, you have to redraw it yourself. I won't just redraw just because you changed the .src.

Related

Weird Image with SVG in src attribute in Edge browser

I'm rendering image and I'm passing svg file as source attribute to image. It works perfect on all browsers, except Edge. I cant find an reason why it renders this weird black box with cross:
Html code of is like: <img width="3029" height="3920" id="id_of_image" src="data:image/svg+xml;charset=utf-8,<svg xmlns=....................CONTENT OF SVG............></svg>"/>
How can I show this kind of image also on edge? I'm filling src attribute from JS where I have element as string. I need to put it into image attribute, but question is how is that possible?
Problem solved. Issue was that in Edge it had problem with rendering svg when you are using tags directly in attributes. So solution was to replace and convert string in JS. I created function to generate SVG attribute for image from ajax request, when you have your SVG string:
function fixSVGDiagram(svgString) {
svgString = svgString.replace("<![CDATA[", "").replace("]]>", ""); //If styles occured, Edge crashes on that
svgString = svgString.replace(/#/g,"temporaryhash") //Because of hasthag issues (in styles)
svgString = encodeURI(svgString) //Magic happens
svgString = svgString.replace(/temporaryhash/g, "%23") //Get back hashtag
return "data:image/svg+xml;charset=utf-8," + svgString
}
If you are loading SVG as attribute in ajax request then you can store it as string:
svgData = (new XMLSerializer).serializeToString(responseData);
and then
var img = new Image
img.src = fixSVGDiagram(svgData)
and you can put image where you want.
svg code doesn't work like this for svg image.
Without the use of image tag you can directly use the svg tag in the html code.
OR.
You can create an svg file with *.svg extension and set the filename as the src in the image attribute.

FloodFill in AS3

I have been making a basic painting application similar to MS-Paint with basic paint, eraser and fill tools. It's this last one that's giving me some trouble.
I'm pretty new to using BitmapData but the idea is that when the user clicks the board, it triggers the startFloodFill method. This is shown below:
public static function startFloodFill(e:MouseEvent):void
{
trace("FLOODFILL");
var boardRef:MovieClip = e.currentTarget.parent.board; //Creates a reference to the board
var boardData:BitmapData = new BitmapData(boardRef.width, boardRef.height); //Creates a new BitmapData with the same size as boardRef
boardData.floodFill(e.localX, e.localY, 0x00CCCCCC); //Applies the FloodFill
boardData.draw(boardRef); //Saves the boardRef as bitmapData
boardRef.bitmapData = boardData; //Updates the board
boardRef.parent.addChild(boardRef);
}
Can anybody tell me what I've done wrong here? When I click, the board does not change. I expected the FloodFill to fill the entire bitmap with the chosen colour as the board is blank when I click.
I also tried replacing the last two lines with:
boardRef.addChild(new Bitmap(boardData) ); //Updates the board
Thanks
The problem is that you first use the floodFill, and then use the draw method, which actually fills the BitmapData with whatever param you give it - in your case it's the boardRef.
You should first draw the boardRef into the boardData, and then use floodFill. At the end, you need to create new Bitmap and display it.
Now you are setting the bitmapData of a MovieClip?! Don't know what you wanted, but you just need to add new child (new Bitmap)

How to Get Image From <img src=""> Tag?

When I want to render a picture, I send a request to the server with the associated picture to render. What's odd is how it's returned:
<img src="https://blargh.com/displayTemplate?templateid=template1">
Where that link is supposed to be the image data.
Using this, how can I transform that into an image that I can display to the user? This is for a facebook app, I can't just embed the HTML. It needs to be displayed inside my AS App as a Bitmap or Sprite or anything, really. Trying to convert it to a Bitmap or BitmapData have failed...
The only other information I can give is that my templateLoader is a Loaderand its .data is supposed to carry the HTML.
Something like this:
var data:String = '<img src="https://blargh.com/displayTemplate?templateid=template1">';
// grab the src attribute
var url:Array = data.match(/<img src=\"(.*?)\">/);
if (url.length > 1){
var loader:Loader = new Loader();
loader.load(new URLRequest(url[1]));
addChild(loader);
}
Use e4x. I'm not sure if you're getting a string or the result format on your service call is already XML, but if it's a string, you'd do something like this:
var imgXML:XML = XML(yourString);//yourString contains <img src="https://blargh.com/displayTemplate?templateid=template1">
link = imgXML.#src;
Then, look at the code Zevan posted for how to use a Loader if you're using just AS, or use it as the source for an Image control in Flex.
Looks like the server is providing you with a link that dynamically looks up the image based on the GET data you're passing to the server (the ?templateid=template1). Too bad you didn't paste in the real link so that this theory could be proven. Take the real link and copy out the http:// portion, enter it into your browser and if the image appears then this is indeed the case.
If this is true, then you want to extract the link from the tag. You could do this with a regular expression, like so:
/\?)"(.?)"(.*)/
If you ran that regex against the full tag like you've provided above, then capture group 2 will contain just the HTTP link. You can then use a Loader object to fetch the image so you're actually downloading and presenting the binary image data instead of embedding HTML.
If you're going to be using Regex in AS3, then you absolutely must have the RegExr tool by grantskinner.com: http://gskinner.com/RegExr/desktop/.
Also, to get the data from capture group 2 we do this:
var imageTag:String = '<img src="https://blargh.com/displayTemplate?templateid=template1">'
var myHttpRegex:Regex = /\<img(.*?)"(.*?)"(.*)/;
var result:Object;
result = myHttpRegex.exec(imageTag);
if(result != null) {
var imgUrl:String = result[1];
}
Code is untested, but the concept is there.

Frame labels & function parameters

Is it possible to change a frame label within a gotoAndStop('label') with the parameters in a function?
I'm playing around with updating code as I learn more and more techniques, and at the moment the code is a basic click-a-button to select the object shape, and on press the button disappears:
// Change the object into a circle.
circle_btn.addEventListener(MouseEvent.CLICK,function(){changeShape_fun(circle_btn,circle);});
// Change the object into a square.
square_btn.addEventListener(MouseEvent.CLICK,function(){changeShape_fun(square_btn,square);});
// Change the object into a star.
star_btn.addEventListener(MouseEvent.CLICK,function(){changeShape_fun(star_btn,star);});
function changeShape_fun(shape_btn,frame){
shape_btn.visible = false;
main_mc.gotoAndStop('frame');
}
However I can't/don't seem to know how to change a frame label through function parameters, or if what I'm trying to do is even possible.
Also to note, while I'm all ears for any more efficient ways of doing what I'm trying to do, I would still like to know how/if you can change frame labels through function parmeters.
Thanks! :)
You're very close, but you're trying to go to a frame called 'frame' and not the string contained within the frame variable. Try this instead:
// Change the object into a circle.
circle_btn.addEventListener(MouseEvent.CLICK,function(event:MouseEvent){changeShape_fun(circle_btn, 'circle');});
// Change the object into a square.
square_btn.addEventListener(MouseEvent.CLICK,function(event:MouseEvent){changeShape_fun(square_btn, 'square');});
// Change the object into a star.
star_btn.addEventListener(MouseEvent.CLICK,function(event:MouseEvent){changeShape_fun(star_btn, 'star');});
function changeShape_fun(shape_btn,frame){
shape_btn.visible = false;
main_mc.gotoAndStop(frame);
}
This will go to a frame within main_mc called 'circle' when you click the circle or 'square' if you click the square, etc.

Controlling image load order in HTML

Is there a way to control the load order of images on a web page? I was thinking of trying to simulate a preloader by first loading a light-weight 'LOADING' graphic. Any ideas?
Thanks
Use Javascript, and populate the image src properties later. The # tells the browser to link to a URL on the page, so no request will be sent to the server. (If the src property was empty, a request is still made to the server - not great.)
Assemble an array of image addresses, and recurse through it, loading your images and calling a recursive function when the onload or onerror method for each image returns a value.
HTML:
<img src='#' id='img0' alt='[]' />
<img src='#' id='img1' alt='[]' />
<img src='#' id='img2' alt='[]' />
JS:
var imgAddresses = ['img1.png','img2.jpg','img3.gif'];
function loadImage(counter) {
// Break out if no more images
if (counter==imgAddresses.length) { return; }
// Grab an image obj
var I = document.getElementById("img"+counter);
// Monitor load or error events, moving on to next image in either case
I.onload = I.onerror = function() { loadImage(counter+1); }
//Change source (then wait for event)
I.src = imgAddresses[counter];
}
loadImage(0);
You could even play around with a document.getElementsByTagName("IMG").
By the way, if you need a loading image, this is a good place to start.
EDIT
To avoid multiple requests to the server, you could use almost the same method, only don't insert image elements until you're ready to load them. Have a <span> container waiting for each image. Then, loop through, get the span object, and dynamically insert the image tag:
var img = document.createElement("IMG");
document.getElementById('mySpan').appendChild(img);
img.src = ...
Then the image request is made only once, when the element is created.
I think this article https://varvy.com/pagespeed/defer-images.html gives a very good and simple solution. Notice the part which explains how to create "empty" <img> tags with:
<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="your-image-here">
to avoid <img src="">
To display a loading image, just put it in the HTML and change it later at the appropriate moment/event.
Just include the 'loading' image before any other images. usually they are included at the very top of the page and then when the page loading completes, they are hidden by a JS.
Here's a small jQuery plugin that does this for you: https://github.com/AlexandreKilian/imageorder