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
Related
I have two canvases. I have made them circular using border-radius. The 2nd is positioned inside the first one (using absolute position).
I have click events on both circles. If you click on inside canvas, the color at the point of the click is loaded in the outside canvas with opacity varying from white to the picked color and finally to black. If you click on outer canvas the exact color value at that point is loaded in the text-box at the bottom
I am unable to click in red zones (as shown in figure below) of the outer canvas when using chrome. I tried z-idex, arcs but nothing is helping me. But In Firefox everything is working fine.
Note: You can drag the picker object in the outer circle. But if you leave it in red zones, you would not be able to click it again in Chrome. Clicking in green zone will get you its control again
Code in this JSFiddle
Edit
I excluded all irrelevant code to make it easy. Now there is only a container having two canvas.
Filled simply with two distinct colors. Open following fiddle link in both chrome and firefox. Click on both cirles in different zones and see difference in chrome and firefox. I want them to behave in chrome as they do in firefox
Note I will ultimately draw an image in inner canvas.
Updated Fiddle Link
-
Your problem is because canvases currently are always rectangular, even if they don't look rectangular. Border radius makes the edges except the circle transparent, but it still doesn't stop events in Chrome on the corner areas. This is why you cannot click the bottom circle in those areas
I even tried putting it inside of a container that had a border-radius instead but the click event still goes through
With that being said, you have two options. You could either change your code to only use one canvas with the same type of layout, just drawing the background circle before the other each time. Essentially you'd draw a circle, draw your black to color to white gradient, use the xor operation to combine the two into one circle, then do the same with the rainbox gradient. You must draw the background circle first because canvas paints over the old layers every time
or
You could use javascript to only detect clicks in the circular area which takes just a little bit of math (: This solution is featured in edit below
In the future, CSS Shapes may allow canvases to be non-rectangular elements to be used, I'm actually not sure, but we don't have that capability yet at least
Edit
Alright, so after going through your code a bit it seems there are some things I should cover before I offer a solution
Setup all your finite variables outside of the functions that run every time. This means you don't put them (like radiuses, offsets, etc.) in the click function or something that runs often since they don't change
Your "radius"es are actually "diameter"s. The format of .rect goes .rect(x, y, width (diameter of circle), height (diameter of circle))
Almost always when overlaying canvases like you are you want to make them equal dimensions and starting position to prevent calculation error. In the end it makes it easier, doing all relative positioning with javascript instead of mixing it with CSS. In this case, however, since you're using border-radius instead of arc to make a circle, keep it like it is but position it using javascript ....
jQuery isn't needed for something this simple. If you're worried about any load speed I'd recommend doing it in vanilla javascript, essentially just changing the .click() functions into .onclick functions, but I left jQuery for now
You can declare multiple variables in a row without declaring var each time by using the following format:
var name1 = value1,
name2 = value2;
Variables with the same value you can declare like so:
var name1 = name2 = sameValue;
When children have position:absolute and you want it to be positioned relative to the parent, the parent can have position:relative, position:fixed, or position:absolute. I would think you'd want position:relative in this case
When you don't declare var for a variable it becomes global (unlessed chained with a comma like above). For more on that read this question
Now, onto the solution.
After talking with a friend I realized I could sort do the math calculation a lot easier than I originally thought. We can just calculate the center of the circles and use their radiuses and some if statements to make sure the clicks are in the bounds.
Here's the demo
After everything is set up correctly, you can use the following to detect whether or not it's in the bounds of each
function clickHandler(e, r) {
var ex = e.pageX,
ey = e.pageY,
// Distance from click to center
l = Math.sqrt(Math.pow(cx - ex, 2) + Math.pow(cy - ey, 2));
if(l > r) { // If the distance is greater than the radius
if(r === LARGE_RADIUS) { // Outside of the large
// Do nothing
} else { // The corner area you were having a problem with
clickHandler(e, LARGE_RADIUS);
}
} else {
if(r === LARGE_RADIUS) { // Inside the large cirle
alert('Outer canvas clicked x:' + ex + ',y:' + ey);
} else { // Inside the small circle
alert('Inner canvas clicked x:' + ex + ',y:' + ey);
}
}
}
// Just call the function with the appropriate radius on click
$(img_canvas).click(function(e) { clickHandler(e, SMALL_RADIUS); });
$(wheel_canvas).click(function(e) { clickHandler(e, LARGE_RADIUS); });
Hopefully the comments above and code make enough sense, I tried to clean it up as best as I could. If you have any questions don't hesitate to ask!
I have problem with canvas createPattern. I have two boxes, both will move after pressing a keyarrow:
Example:
http://jsfiddle.net/wA73R/1/
The problem is that the box background filled by createPattern also is moving. How to avoid that? Is there any solution? The big box is only an example (drawImage is not the good solution for me, I need something that will repeat background image).
Thank you for help
The problem is that the box background filled by createPattern also is moving.
Actually your problem is that the background is not moving - it is static, while you are drawing your rectangle to different positions.
How to avoid that?
The pattern will always be drawn at the coordinate origin, whose actual position is defined by the current transformation. In future you will be able to transform the pattern itself with the setTransform method, but since that currently is not implemented anywhere you instead will have to change the global transformation matrix.
In your case it means, that instead of drawing your rectangle at x/y, you translate the whole context to x/y and draw your rectangle at 0/0 then:
ctx.fillStyle=pattern;
ctx.save();
ctx.translate(boxes[i].x - left , boxes[i].y);
ctx.fillRect(0, 0, boxes[i].width, boxes[i].height);
ctx.restore();
(updated demo)
What I need to do is to understand if mouse leaves SVG object (path, i.e it is not a rectangular - can't use just offset, not a circular - can't use radius and center position, etc. ). I can not use mouse leave/enter events because I have a pointer for mouse that is always above all elements. Obviously I also can't just use elementFromPoint - because it gives the top layer element.
So the question:
Is there a way to understand if coordinates (X,Y) are in the specific element $("#element").
UPD:
I uploaded my current code to my website http://pekap.co/example/
I didn't create jsfiddle because I have SVG object to ebmed.
There you can find my JS, svg object I use, etc.
If you go to the svg object it changes its color and pointer appears (orange circle). The goal is to change color of the SVG area whenever we leave it/ enter it and display orange circle under mouse only inside SVG area.
Whereas currently I can accomplish on one of goals (either one with different code)
UPD 2.
Erik Dahlström gave almost perfect solution for me: set pointer-events to none in CSS. I will go for this now, however to make my day perfect it would be great if there was a way to detect when any part of circle is out of the SVG area.
I'm not sure I follow what you mean, the pointer is the little circle that follows the mouse?
If so, then just make that circle have pointer-events: none and it will be "transparent" to mouse events. Note that webkit/safari/chrome/blink doesn't yet support mouseenter and mouseleave so you'll likely need some scriptbased workaround (not sure if D3 does this already).
It should also be possible to do a solution based on using a CSS :hover rule on the path element. Set some property to some value on hover, and then check with getComputedStyle what the property is currently set to on the path element.
My suggestion would be to to create a image map of the area, its a lot of work but this seems to be what you need: http://jsfiddle.net/sb9j7/
<area shape="poly" name="dip" coords="253,102, 277,100, 280,105, 290,107, 295,111, 304,130, 290,140, 287,147, 240,157, 238,159, 227,153, 203,146, 198,125, 200,116, 214,102, 231,102" href="#">
this fiddle is from image mapster
I am drawing lines using Canvas (HTML 5), since lines/shapes are not stored as objects in Canvas, I cannot attach unique events to it (eg onmouseclick)
I wish to attach a onmouseover event to a line, is it possible by getting to know if the mouse if over a particular line (using its 2 X and 2 Y co-ordinates) in Canvas using Javascript. Would this work for different line widths (eg: 2,5 pixels)
Want to avoid using SVG as the entire project is built on Canvas
Please advise.
You would need to use math formulas to calculate the area of the line and whether a certain point intersects with it.
Here's a basic example:
Find mouse coordinates relative to position of the canvas (How to find mouse pos on element)
Calculate whether mouse x/y is inside some rectangle (Point in rectangle formula)
Done.
There is a function isPointInPath(x,y). It will return true if a point is on the current path.
You will have to call that for every line you want to check and the best way to do that is at the same time as you draw.
The best way is using some canvas frameworks. Look at "LibCanvas :: Creating Lines" (dont forget to dblClick at canvas)
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.