Raphael.js - image with it's original width and height size?
Asked Answered
M

4

14

Hi RaphaelJS users =) ,

I have maybe a dumb-ish question, but I can't seem to find the answer, the thing is, I'm trying to load/create an image with Raphael, that's fine, like this:

var image_1 = paper.image('/img/img1.jpg', 0, 0, 100, 100);

But as you can see, it always seems like you have to give the "width" and "height" properties, I already checked the documentation, but it's always short and not that's detailed, and I tried giving null parameters or empty parameters, but it doesn't work...

So I'm wondering if there is actually a direct way in raphael to do this, or....do I have to always get those values before???

I mean, something like this?:

var imgURL = "../img/img1.jpg"

var myImg = new Image();
myImg.src = imgURL;

var width = myImg.width;
var height = myImg.height;

   //create the image with the obtained width and height:
    var image_1 = paper.image('/img/img1.jpg', 0, 0, width, height);

And so that way I load with the original size of the image and that kinda solves my problem, but....isn't there way inside Raphael to do this???

Maye answered 29/5, 2012 at 16:1 Comment(4)
what's stopping you from implementing it like you suggested? be more clear - what are you trying to achieve?Cockadoodledoo
@EliranMalka , umm, nothing is stopping me, I implemented it the way I said, but, my question was... if instead of doing all that code...Raphael does have an argument/parameter/property to create an image with the original dimensions??? ,do I make myself clear? or what am I missing? =PMaye
so have you found a solution? i'm also looking for itFlavor
@oyatek Hi, I'm sorry, but nop, no direct solution, the one I used is the one I already posted(the one using JS to find the width and height and use those variables in the parameters), but for now my thought is that there is no actual parameter to get with and height automatically in the paper.image creation =PMaye
M
15

For now...I guess I'll have to answer my own question with my own answer, cause there seems to be no other way that I've found or that someone has told me =P

var imgURL = "../img/img1.jpg"

var myImg = new Image();
myImg.src = imgURL;

var width = myImg.width;
var height = myImg.height;

   //create the image with the obtained width and height:
    var image_1 = paper.image('/img/img1.jpg', 0, 0, width, height);
Maye answered 22/6, 2012 at 1:18 Comment(1)
Thank you for the answer.. i was also looking along the same lines and found myself using your way aswell and now you kinda confirmed that its not to bad =)Kisung
B
9

Building off of @drzaus's awesome answer, I had some issues where if the image I was loading into Raphael was not already in the cache, the height and width would be set to 0. To fix this:

(function(Raphael){
/// Plugin - replaces original RaphaelJS .image constructor
/// with one that respects original dimensions.
/// Optional overrides for each dimension.
/// @drzaus @zaus
/// based on https://mcmap.net/q/803685/-raphael-js-image-with-it-39-s-original-width-and-height-size
/// modified 13/08/2013 by @Huniku to support asynchronous loads

var originalRaphaelImageFn = Raphael.fn.image;

Raphael.fn.imageAsync = function(url, x, y, w, h) {
    var dfd = new jQuery.Deferred();
    var done = false;
    var paper = this;
    // fix the image dimensions to match original scale unless otherwise provided
    if( !w || !h ) {
        //Create the new image and set the onload event to call
        //the original paper.image function with the desired dimensions
        var img = new Image();
        img.onload = function() {
            if(done)
                return;
            if( !w ) w = img.width;
            if( !h ) h = img.height;
            dfd.resolve(originalRaphaelImageFn.call(paper, url, x, y, w, h));
        };
        //Begin loading of the image
        img.src = url;

        //If the images is already loaded (i.e. it was in the local cache)
        //img.onload will not fire, so call paper.image here.
        //Set done to ensure img.onload does not fire.
        if(img.width != 0) {
            if( !w ) w = img.width;
            if( !h ) h = img.height;
            done = true;
            dfd.resolve(originalRaphaelImageFn.call(paper, url, x, y, w, h));
        }
    }
    else
        dfd.resolve(originalRaphaelImageFn.call(paper, url, x, y, w, h));
    return dfd.promise();
};
})(Raphael);

This allows the image to load before before querying it for width/height, and also supports the instance where the image is already in the cache and the onload event is not fired. To use this, simply:

var dfd = paper.imageAsync("images/hello.png",0,0,false,false);
dfd.done(function( result ) {  //result is a Raphael element
    console.log('done');
    //do something with result
});
Benefield answered 14/8, 2013 at 0:11 Comment(0)
A
3

Had same problem, thanks for the tip -- here's a plugin to replace the existing image function with one that respects dimensions: http://jsfiddle.net/drzaus/dhkh7/

To be safer, should probably not overwrite the original image function just in case it ever changes, but you get the idea.

;(function(Raphael){
/// Plugin - replaces original RaphaelJS .image constructor
/// with one that respects original dimensions.
/// Optional overrides for each dimension.
/// @drzaus @zaus
/// based on https://mcmap.net/q/803685/-raphael-js-image-with-it-39-s-original-width-and-height-size

var originalRaphaelImageFn = Raphael.fn.image;
Raphael.fn.image = function(url, x, y, w, h) {
    // fix the image dimensions to match original scale unless otherwise provided
    if( !w || !h ) {
        var img = new Image();
        img.src = url;
        if( !w ) w = img.width;
        if( !h ) h = img.height;
    }
    return originalRaphaelImageFn.call(this, url, x, y, w, h);
};
})(Raphael);

And usage:

window.onload = function() {
  var paper = new Raphael('canvas', '100%', '100%');

  // specify dimensions as before
  paper.image('http://www.stockfreeimages.com/Swiss-panorama-thumb6499792.jpg', 10, 10, 100, 50).attr('stroke', '#000');

  // original ratio
  paper.image('http://www.stockfreeimages.com/Swiss-panorama-thumb6499792.jpg', 10, 100).attr('stroke', '#f00');

  // specify width, height taken from original
  paper.image('http://www.stockfreeimages.com/Swiss-panorama-thumb6499792.jpg', 10, 200, 100).attr('stroke', '#0f0');

  // specify height, width taken from original
  paper.image('http://www.stockfreeimages.com/Swiss-panorama-thumb6499792.jpg', 10, 300, false, 100).attr('stroke', '#00f');
};
Assai answered 12/1, 2013 at 15:42 Comment(0)
K
0

Edward's comment worked for me but I had to place it in an interval function and wait until the width and height are defined before adding the image (otherwise I got a 0x0 image). Here is the code I used:

var imgURL = "/img/img1.jpg"
var myImg = new Image();
myImg.src = imgURL;

function loadImagAfterWidthAndHeightAreDefined(){
  width = myImg.width;
  height = myImg.height;

  if(myImg.width > 0 && myImg.height > 0){
    image_1 = paper.image(imgURL, 0, 0, width, height);
  }
  else{
    setTimeout(function(){
      loadImagAfterWidthAndHeightAreDefined();
    },250);
  }
}
loadImagAfterWidthAndHeightAreDefined()
Kast answered 18/12, 2014 at 9:49 Comment(1)
Wouldn't this be better with the $(document).ready(function(){}); from jQuery? You should not then need the setTimeout() function.Howsoever

© 2022 - 2024 — McMap. All rights reserved.