Put Raphael (SVG) canvas behind other divisions to make them clickable? - javascript

I am using Raphael to create lines between divisions in an organization chart (or flow chart), but I need to be able to actually click on the divisions and content behind it.
If I could make the canvas be behind the other elements, kind of like a background image, that would be idea. Is this possible?

I found a solution. Raphael makes an SVG canvas that is absolutely positioned in my case. Absolute positions act as layers, and so to be on top of that layer, my content had to be absolutely positioned as well.
If someone else has a better solution, I would be happy to hear it, though this is working fine.

What I do is create a layer of invisible (but clickable) shapes on top of the informational lines being rendered, which will act as the target area for the content below.
If your lower layers being target are being created in Raphael you can easily clone them, set the opacity to 0, and position that layer to the top. (See Sets Reference for a way to easily group the layers together.)
Example:
#el = #parent.paper.rect(x,y,w,h); //your existing lower layer shape definition
#elTrigger = #el.clone(); //clone your existing shape
#elTrigger.attr
fill: '#fff'
opacity: 0
cursor: 'pointer'
#elTrigger.click(someAction); //assign the function
If you're lower layer isn't being rendered by Raphael (just HTML) you could still do something similar, but it would require just creating new (transparent) shapes to sit on top of the approximate coordinate of the targets below.

Related

Using SVG.JS to overlap two SVG Elements - one responsive, one fixed

So I am building a website using an SVG element to cover the entire viewport. I then have a responsive polygon which stretches the entire width of the viewport with some text on it. The issue I am having is such that I don't want the text to stretch, which when you use SVG.JS, the text is simply another child of the SVG canvas and in turn stretches with the viewport. I also want the text to be parallel to part of the polygon, which you can see in the diagram I have provided.
So, in a way, I need the text to respond to the SVG Polygon, but also not respond to it.
I was able to get the non-scaling text to work by creating another SVG element overlapping the original one with a preserved aspect ratio... however, as in diagram 3 of the image, I want to click the polygon for an animation, and by having another SVG canvas over the top this is not possible. Your canvas on top would appear to block the one below for onClick events, plus it's difficult to make the text parallel.
Diagram of polygon / text
I am using SVG.JS, but if you can offer help using SVG,HTML,CSS that is also useful.
HTML:
<div id="maindiv">
</div>
JS (SVG.JS) with text created on a new canvas:
var draw = SVG('maindiv').viewbox('0 0 500 500').attr({ 'preserveAspectRatio': 'none' })
var polyg = draw.polygon('0,100 500,200 500,500 0,500').fill('black')
polyg.click(function() {
this.animate().attr({'points':'0,200 500,300 500,500 0,500'})
})
var txtcanv = SVG('maindiv').style({'position':'fixed'})
var title = txtcanv.text('Tim Iland Design').font({
family: 'Arial'
, weight: 'bold'
, size: 30
,fill: '#f06'
})
Any ideas are greatly appreciated! Thanks.

Can I access Mask>Mask Path>Shape>BoundingBox properties via Extenscript?

I am wondering if there's a way to access the Bounding Box Gui properties of mask shapes so that I can see how to create perfect circle shape masks in After Effects?
My code is below:
maskpath = app.project.item(1).layer("Orange Solid 2").property("ADBE Mask Parade").property("ADBE Mask Atom").property("ADBE Mask Shape");
Not sure what you mean by "access the Bounding Box Gui properties of mask shapes", but I do think I know what you mean by "how to create perfect circle shape masks in After Effects".
See D. Ebberts' script code posted here: http://aenhancers.com/viewtopic.php?f=11&t=2084
I believe it does (or will lead you to do) what you want.
I found the answer from After-Effects-CS6-Scripting-Guide.pdf page 48
AVLayer sourceRectAtTime() method
Retrieves the rectangle bounds of the layer at the specified time index, corrected for text or shape layer content.
Use, for example, to write text that is properly aligned to the baseline.
app.project.item(index).layer(index).sourceRectAtTime(timeT, extents)
Returns
A JavaScript object with four attributes: [top, left, width, height].
I think you are talking about how to access Left Top Right Bottom values of this window.
This window appears when you click on shape of mask path
(position where pointing hand drown blue color arrow)
please any one can tell me how to access those values via Script

Partial border/stroke using SVG

I'm using svg/d3 for creating a chart made of 'rect' elements.
What is the best way for adding a partical border/stroke for each rectangle (only on top of the rectangle)?
Thanks
I don't think SVG supports stroking only portions of a rectangle or path - stroke isn't like a CSS border. You're left with a few other options, all of which take some extra work:
Stroke the entire rect and apply a clipPath to remove the other three edges - probably works best if you make the rectangles bigger than necessary.
Apply a linear gradient fill to each rect, using the gradient definition to show a "border" at the top of the shape.
Add a separate line element to act as the border for each rect.
Use the stroke-dasharray property (docs) to set a dash definition where the "dash" only covers the top of the rect. This might be tricky to get right, but I suspect it wouldn't be too hard, as the stroke probably begins at the top left of the shape.

cleaning rectangular

I have a function in script that draws a rectangular on canvas.I want to clean the rectangular drew in the "if" condition.
I also have text on the canvas(its coordinates are 0,80) and it shouldn't be cleaned. Only the rectangular must be cleaned.
function red_stroke_2(yy)
{
//Red color edges
context.strokeStyle = "#f00";
context.strokeRect(0,yy,800,40);
}
if (Option1==answers[qnumber])
{
red_stroke_2(80);
}
Canvas is "stateless" in the sense that it does not know about the primitives that have been drawn or the calls that have been made. As such it is impossible to undo only a certain drawing call. If you need to modify the drawing, you need to redraw all of the items that you don't want to change. Of course you have the option to change single pixels, so if your text is black and the rectangle is red, you can replace all red pixels, but this won't work so good if antialiasing is enabled and is utterly complicated.
So either redraw the whole area (omit the rectangle drawing but render the text). Or consider using 2 Canvases on top of each other (one with the text, one with the background), then of course you can rerender the background without having to worry about the text.
Last but not least using SVG might be also an alternative, since this is stateful and consists of DOM elements that you can modify/insert/remove and the browser will do the compositing. In that case you would have a rect element and a textelement and you could simply remove the former.
This will put transparent pixels instead of your rectangle:
function clean_red_stroke(yy)
{
context.clearRect(0,yy,800,40);
}
//Call it with the same 'yy' you used in the drawing method
clean_red_stroke(80);
However I think you code could be improved, by using more variables (and consequently a most generic function) for exemple.

I would like to reposition a circle created through Raphael js, and to use it as a letter in a title

I have created a vector graphic using Raphael JS - specifically a circle.
I would now like to use this circle as the letter "O" in a title. It is also a circle that will animate upon click. I would like to know if this is at all possible.
Here is a fiddle to explain better what I'm trying to say.
The html is very simple:
<h2>N<span id="canvas_cont"></span>OTRE APPROCHE :</h2>
Here is the jsfiddle
Basically the circle will act as the second letter in "Notre", and when clicked will move to the right of the screen. Other things will happen after, but this effect is what I'm trying to get....
Placing the Raphael canvas in a span is clever, but at the end of the day I suspect you'll regret mixing native HTML with Raphael in this way. Doing so would probably require a lot of absolute positioning and z-indexes that are better handled and supported in Raphael.
I recommend you simple draw the text in Raphael:
var text = r.set();
text.push(
r.text(10,20,"N"),
r.text(70,20,"TRE APPROCHE :")
);
text.attr({
'text-anchor': 'start',
'font-size':'36px'
});
If the SVG/VML styling is inadequate, you could also just use an image. Again, I would recommend placing that image on the canvas using Raphael (paper.image());
Note that, in the updated fiddle, I made the canvas a div the width of the logo.
Updated fiddle.

Categories