I am able to fill the image inside the circle. But the problem is image getting zoomed inside the circle, i want image to be less zoomed or fit into circle.
<div class="disp"></div>
JavaScript
var r = Raphael("disp");
var cir=r.circle(100, 100,33).attr({fill:"url(image.jpg)"});
// image get zoomed, how to make image fit into circle or less zoomed
Please help me! Thanks
You will need to do some mathematics. Don't use attr(fill) - create an image-object and fit it in your circle.
Here is a great example of such behaviour.
BTW, you wrote class="disp" and var r = Raphael("disp"); won't work - this function waits for id.
Here's a solution you can put directly into your code, assuming you're using jQuery as well as Raphael
Related
I need to apply zoom to the javascript canvas which I have badly accomplished by using the following line of code:
ctx.scale(2,2) //doubles everything's size
Instead of zooming, its obviously doubling the size of the canvas and all of its elements. I'd be okay with this if I got it working like the image below shows:
Any ideas on how I could accomplish what is depicted in the picture above? I'm not using any external libraries hence making this so difficult. Thanks.
You can translate the context by half the canvas size using ctx.translate()
EDIT :
var zoomfactor = 2; //set whatever you want as zoom factor
ctx.transform(zoomfactor,0,0,zoomfactor,-(zoomfactor-1)*canvas.width/2,-(zoomfactor-1)*canvas.height/2)
I have a group of elements that are masked by a rect in SnapSVG and I want to translate the elements, bringing new ones into view (and hiding ones that are currently in view). The code is really simple - here's a codepen: http://codepen.io/austinclemens/pen/ZbpVmX
As you can see from the pen, box1, which starts outside the mask element (clip) should cross through it when animated, but it never appears. Moreover, box2, which should move out of the clipping area, remains visible.
This example seems to do a similar thing and has no problems: http://svg.dabbles.info/snaptut-masks2
Here's the code from codepen:
var t = Snap('#target')
var clip=t.rect(200,200,200,200).attr({fill:'#fff'})
var box1=t.rect(300,100,50,50).attr({fill:'#000'})
var box2=t.rect(300,300,50,50).attr({fill:'#000'})
var boxgroup=t.group(box1,box2)
boxgroup.attr({mask:clip})
boxgroup.animate({transform:'t100,300'},2000)
I notice that the svg.dabbles examples translates the clip region by 0,0 at one point, but adding something like that doesn't seem to get me anywhere.
Ok, I figured this out thanks in part to this really great article about SVG transforms: http://sarasoueidan.com/blog/svg-transformations/
The upshot is that when I translate the box group, it takes the mask with it. This is a little confusing to me still - I guess the mask attribute is causing this somehow? Anyways, the solution is to apply an opposite translation to the mask to keep it in place. Check the pen to see it in action but basically I just had to add:
clip.animate({transform:'t-100,-300'},2000)
The tricky part of this is that you now need to synchronize the movement of the mask and the movement of the box group.
edit - I now demonstrate how synchronization can be achieved using snap's set.animate method on the codepen.
I am creating a rectangle element in raphael JS as a tooltip on an SVG circle element generated by raphael JS. I am unable to access the coordinates of the center of the circle (which I need to place the rectangle tooltip) using the following code in Internet Explorer..
var c = {};
c.x = parseInt(c_element.node.attributes[0].nodeValue);
c.y = parseInt(c_element.node.attributes[1].nodeValue);
//code for the rectangle element tooltip
r = paper.rect(c.x,c.y,50,50);
Its working fine in Firefox.. But in IE, the tooltip gets created at the upper left corner of the div enclosing my raphael JS paper and not on the center o the circle as desired..
How do I solve this cross-browser issue? Please help..
I don't know for certain why IE doesn't like this, but there's a much easier way:
c.x = c_element.attr("cx");
c.y = c_element.attr("cy");
jsFiddle
If you log the Raphael object to the console, you can check out the "attrs" property to see what's in there. Different for every type of Raphael object.
While we're all here: I highly recommend using an absolutely positioned div for your tooltips. HTML handles things like wrapping text and resizing the tooltip to accomodate different amounts of text much more easily than the SVG text element. See this answer. (Whatever you use, you'll still need to access the coordinates of the circle.)
I want to create a jqPlot line chart which has the ability to change orientation between vertical and horizontal orientation. I was able to achieve this using CSS rules, by rotating the div element containing the chart.
My work up to now: http://jsfiddle.net/GayashanNA/A4V4y/14/
But the problem is I also want to track the mouse-pointer and mouse clicks on points on chart after the orientation is flipped because i want to annotate those points. I am unable to do this when the chart is in vertical orientation. Can anyone suggest a method to do this? Or am i approaching the problem in a wrong way?
(Note: I am able to do this in horizontal orientation, you can observe it if you try to click on a point on the above chart.)
Thanks and help is much appreciated.
I've never used jqPlot, but I guess your problem is trying to use css rotate(), since the cursor plugin is using the mouse position to determine where to draw the lines, and element's size doesn't change when transformed by rotate(), it still have the same width and height values.
If you take a look at the code, you will see:
if (c.showVerticalLine) {
c.shapeRenderer.draw(ctx, [[gridpos.x, 0], [gridpos.x, ctx.canvas.height]]);
}
if (c.showHorizontalLine) {
c.shapeRenderer.draw(ctx, [[0, gridpos.y], [ctx.canvas.width, gridpos.y]]);
}
So it seems like the library is always drawing the lines based on mouse position over the original element, which of course, won't match the position after being transformed by rotate(), and XY coordinates are going to be transformed to YX after rotate().
I would try to change the size of your original element, though I don't know if the library lets you specify in which sides are the labels going to be drawn.
I finally found a solution for the problem. But i had to change jqPlot library to achieve this. To help anyone else who run in to the same problem, i'll put my solution here.
First i had to insert the following code in to the jqPlot class of the jquery.jqplot.js file, which is the core library.
function jqPlot() {
//add the following code segment
var verticallyOriented = false;
this.setVertical = function(state){
verticallyOriented = state;
}
//don't change other code that isn't mentioned here
//now you have to change the logic in the getEventPosition function
//to make sure the new orientation is detected
function getEventPosition(ev) {
//change the line starting with var gridPos = ...
//to the following code segment
//depending on the orientation the event position calculating algorithm is changed
if(verticallyOriented){
var gridPos = {x:ev.pageY - go.top , y:plot.eventCanvas._elem.height() - ev.pageX + go.left};
} else {
var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top};
}
//no change to other code is needed
}
}
You can view a working example here: http://jsfiddle.net/GayashanNA/yZwxu/
Gist for the changed library file: https://gist.github.com/3755694
Please correct me if i have done something wrong.
Thanks.
Please see the code below. I am trying to draw a circle around a path (an icon made by Raphael.js founder, Dimitry) and then fill the circle with a color. This, however, paints on the top of the path. If I could first draw the filled circle and then draw the path, this would be solved. But I need to reference the path because I need to find its center, in order to draw the circle. Can anyone please suggest how to do this? My code is below.
Thanks.
<script>
var myVar = {
s: 1,
pw: 850,
ph: 450
}
</script>
<script>
var paper = new Raphael('figSellerBuyer', myVar.pw * myVar.s, myVar.ph * myVar.s);
var market = paper.path(paths.marketBoundary);
market.attr({fill: "rgb(75,245,75)", stroke: "None"});
var humanIcon = paper.path("M21.021,16.349c-0.611-1.104-1.359-1.998-2.109-2.623c-0.875,0.641-1.941,1.031-3.103,1.031c-1.164,0-2.231-0.391-3.105-1.031c-0.75,0.625-1.498,1.519-2.111,2.623c-1.422,2.563-1.578,5.192-0.35,5.874c0.55,0.307,1.127,0.078,1.723-0.496c-0.105,0.582-0.166,1.213-0.166,1.873c0,2.932,1.139,5.307,2.543,5.307c0.846,0,1.265-0.865,1.466-2.189c0.201,1.324,0.62,2.189,1.463,2.189c1.406,0,2.545-2.375,2.545-5.307c0-0.66-0.061-1.291-0.168-1.873c0.598,0.574,1.174,0.803,1.725,0.496C22.602,21.541,22.443,18.912,21.021,16.349zM15.808,13.757c2.362,0,4.278-1.916,4.278-4.279s-1.916-4.279-4.278-4.279c-2.363,0-4.28,1.916-4.28,4.279S13.445,13.757,15.808,13.757z")
humanIcon.attr({fill: "rgb(75,75,75)"}).scale(2.5,2.5);
humanIcon.translate(40,40);
var bbox = humanIcon.getBBox();
var xcenter = Math.round(bbox.x + bbox.width/2.0);
var ycenter = Math.round(bbox.y + bbox.height/2.0);
var circle = paper.circle(xcenter, ycenter, 40);
circle.attr({fill:"white"});
</script>
After doing a lot of search on Google, I found the answer here on Stackoverflow. At the time, I did not save the link to the answer and I don't remember it. If anyone does find it, please edit this answer and post it. However, I did record the solution and here it is:
One can use the insertBefore() and insertAfter() functions in Raphael. In the example code given in the question, one can do this by changing the last line to:
circle.attr({fill:"white"}).insertBefore(humanIcon);
Thanks to those who responded.
Try changing the order in which the two are drawn. That or look over the Raphael docs to see if there is a "Z-index" attribute that can be used to permanently modify the position of the path on the stack of render-able layers.
Edit: I didn't read your explanation well enough. If you could declare your object without drawing it perhaps you could grab the BBox, and then draw it later.
Edit, Edit: SVG has a "defs" tag to create objects without drawing them, so it stands to reason that Raphael can handle it too.
Try using Raphael's Element.toBack() and Element.toFront().
In your case, it sounds like you want to draw the path, then draw the circle, then call either circle.toBack() or path.toFront().