There's a way to attach a event like mouse over into a mask?
This example shows my problem: http://goo.gl/DRhsH
When you pass the mouse NEXT to the blue box, it changes the color from the mask, what i would like to do is to just call that event WHEN the mouse pass over blue box (Not near - This happen beucause the blue and red boxes are masked with another rect, and when you pass the mouse near them)
, because i need to work with only the displayed image, and binding a event like that should solve my problem.
i tried to bind the click/mouseover into a group but it keeps the same result, the whole image is acessible, and not just the part viewed.
I also tried to clip it, but it keep tracking the content clipped
Edit: Replaced the previous answer as did things improperly and bonsaijs apparently won't allow clipping.
I'd suggest using the mask path as a clip path as well, but bonsiajs doesn't seem to support that. Anyway, here's an SVG structure that triggers events as you intended. If this can't be generated using bonsaijs, maybe you can do it in another way.
<svg width="596" height="596" viewBox="-0.5 -0.5 596 596"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<mask id="mask">
<path d="M 0 0 l 50 0 l 0 150 l -50 0 Z" fill="rgba(255,255,0,1)"
transform="matrix(1,0,0,1,80,0)" id="maskPath"/>
</mask>
<clipPath id="clipPath">
<use xlink:href="#maskPath"/>
</clipPath>
</defs>
<g>
<g mask="url(#mask)" clip-path="url(#clipPath)" onmouseover="alert('in')">
<path d="M 0 0 l 100 0 l 0 100 l -100 0 Z" fill="rgba(255,0,0,1)"/>
<path d="M 0 0 l 100 0 l 0 100 l -100 0 Z" fill="rgba(0,0,255,1)"
transform="matrix(1,0,0,1,50,50)"/>
</g>
</g>
</svg>
Related
I'm working with an inline SVG.
Example:
<svg viewBox="0 0 8 8">
<path d="m0 0 h8 v4 l-4 4 l-4-4 z"/>
</svg>
I would like to change the l-4 4 command to l-4 0 inside the d attribute using JavaScript. I don't want to edit the entire path, just the l command. Maybe somehow getting the l command with coordinates -4 4 and setting them to -4 0.
How can I achieve this?
Javascript doesn't have a very rich api for interacting with svg. There are probably libraries that fill in this gap, but I haven't looked. If this is all you want to do, you could try something like this:
const svg = document.querySelector("svg");
svg.innerHTML = svg.innerHTML.replace("l-4 4", "l-4 0");
<svg viewBox="0 0 8 8">
<path d="m0 0 h8 v4 l-4 4 l-4-4 z"/>
</svg>
When I create a SVG Path in Illustrator and change the position of the points for a morphing animation the points are totally different!
For example:
<path d="M 355.077,300c-31.017,0-31.017-200-62.034-200 s-31.017,200-62.034,200c-31.015,0-31.015-200-62.031-200c-31.014,0-31.014,200-62.029,200c-31.013,0-31.013-200-62.026-200"/>
and
<path d="M355.077,217.635 c-31.017,0-31.017-64.507-62.034-64.507s-31.017,185.701-62.034,185.701c-31.015,0-31.015-274.316-62.031-274.316 c-31.014,0-31.014,175.276-62.029,175.276c-31.013,0-31.013-97.737-62.026-97.737"/>
are the same path (with moved points obviously). However, the order in which they occur is totally different and therefore the animation pushes the points all around the SVG element.
I have tried all export scripts Illustrator offers.
Is there a trick for getting a consistent result when exporting? So that the points are at the right place? Perhaps a plug-in I can use?
Thanks!
This is not an answer. This is just to say that the paths can be used for morphing since the commands and the number of the commands is the same. However if the paths you have are different a solution would be to change all the commands to C
<svg viewBox="0 0 400 400" width="300">
<path fill="gold" d="M 355.077,300
c-31.017,0-31.017-200-62.034-200
s-31.017,200-62.034,200
c-31.015,0-31.015-200-62.031-200
c-31.014,0-31.014,200-62.029,200
c-31.013,0-31.013-200-62.026-200">
<animate
attributeName="d"
attributeType="XML"
values="M 355.077,300
c-31.017,0-31.017-200-62.034-200
s-31.017,200-62.034,200
c-31.015,0-31.015-200-62.031-200
c-31.014,0-31.014,200-62.029,200
c-31.013,0-31.013-200-62.026-200;
M355.077,217.635
c-31.017,0-31.017-64.507-62.034-64.507
s-31.017,185.701-62.034,185.701
c-31.015,0-31.015-274.316-62.031-274.316
c-31.014,0-31.014,175.276-62.029,175.276
c-31.013,0-31.013-97.737-62.026-97.737;
M 355.077,300
c-31.017,0-31.017-200-62.034-200
s-31.017,200-62.034,200
c-31.015,0-31.015-200-62.031-200
c-31.014,0-31.014,200-62.029,200
c-31.013,0-31.013-200-62.026-200"
dur="5s"
repeatCount="indefinite"/>
</path>
</svg>
There is a cubic bezier with arrow marker:
<defs>
<marker id="arrow" orient="auto" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" refX="10" refY="6">
<path d="M0,0 L0,12 L12,6 z"></path>
</marker>
</defs>
<path marker-end="url(#arrow)" d="M 220 104 C 220 144 400 184 400 224" stroke-width="2"></path>
I want to shift arrow head to the center of curve, but when I mutating refX attr of marker arrow shifts not across the curve but straight to top (http://prntscr.com/ikzuol). It works perfectly with quadratic bezier curves but not with cubic.
Is there a way to display an arrow head at the center of cubic bezier curve with correct orientation using marker?
I know there is an option to get coordinates at length, calculate angle to rotate and do positioning and rotation by myself but I would like to avoid such calculations.
UPD: I've created a codepen to demonstrate the issue: https://codepen.io/onatolich/pen/LQqYvr
UPD2: one more codepen to demonstrate that it's working with quadratic bezier curves: https://codepen.io/onatolich/pen/NyoxQv
refX and refY are points in the coordinate system the marker is defined in and have no relation to the direction of the path. They simply define the point that is considered the origin of the marker and wich will be placed on the end of the path.
There is no way to define a marker along a computed path. Markers can only be placed at the vertices of a path. So the seemingly straight-forward way would be to find a mid-point, place a vertex there with appropriate cubic bezier control points...
<svg width="500" height="500">
<defs>
<marker id="arrow" orient="auto" markerUnits="userSpaceOnUse"
markerWidth="12" markerHeight="12" refX="3" refY="6">
<path d="M0,0 L0,12 L12,6 z"></path>
</marker>
</defs>
<path marker-mid="url(#arrow)"
d="M 220,104 C 220,124 265,143 310,162.5 355,182 400,202 400,224"
stroke-width="2" stroke="black" fill="transparent"></path>
</svg>
...but that is obviously a lot of computation, also.
Here is a hack that uses the <animateMotion> element, not to animate anything, but because it can move an object to every point along a path. The movement just starts, ends, and freezes in the middle of the path.
The "marker" does not have its own viewport, which means there is no way to define a refX/refY. The point to be placed on the path is always at (0,0) of its userspace coordinates. That is the reason the marker has to be moved in the opposite direction of these values.
<svg width="500" height="500" >
<path id="path1" d="M 220 104 C 220 144 400 180 400 224"
fill="none" stroke-width="2" stroke="black" />
<path d="M0,0 L0,12 L12,6 z" transform="translate(-3,-6)">
<animateMotion dur="0s" rotate="auto" fill="freeze"
keyTimes="0;1" keyPoints="0.5;0.5" calcMode="linear" >
<mpath xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#path1"/>
</animateMotion>
</path>
</svg>
The hack will not work with Edge/IE, which do not implement SMIL animations.
How can I create an arc shape like this:
With CSS or jquery or javascript
You don't even need CSS/JS to draw this. Just use an <svg> element.
<svg width="270" height="120">
<path
d="M 49.155517,102.32765 C 127.54837,40.541934 209.51266,103.2205 209.51266,103.2205 l 0,0 C 259.33409,50.363364 259.15552,50.363364 259.15552,50.363364 126.68749,-56.114356 2.1861831,50.204194 2.1861831,50.204194 z"
stroke-width="3"
stroke="#A5423A"
fill="none"
/>
</svg>
You could use SVG for this. There is an arc path command which you could use.
As your comment states, you want to place content inside the arc and you want them to rotate.
Content like text or image could be placed inside the svg.
Rotation can be achieved with transform=rotate(..).
If you want to do more animations with SVG you could have a look at D3.js. If you just want to create some arcs, you possibly can do the math on your own for computing the SVG path string.
#AlliterativeAlice is correct.
But for this shape I would use two arcs instead of a lot of C paths.
I also prefer to use relative paths instead of absolute one.
So my solution used arcs and lines instead of only Bezier Curves.
<svg width="300px" height="300px" viewBox="0 0 100 100">
<path d="m 10,60
a 50 50 0 0 1 80,0
l -10,10
a 40 40 0 0 0 -60 0Z" stroke-width="1" stroke="#A5423A" fill="none" />
</svg>
Is there a way to restrict rotated child elements from skewing when parent element is scaled?
This is my code
<svg viewbox="0 0 500 500">
<g class="parent" transform="matrix(1.71341 0 0 1 -42.302 0)">
<path d="M59.295623779296875,59.295623779296875 L470,59.295623779296875 L470,470 L59.295623779296875,470Z"></path>
<g class="shape1" transform="matrix(-0.774634 0.63241 -0.63241 -0.774634 481.409 228.445)">
<ellipse rx="100" ry="100" cx="200" cy="200"></ellipse>
</g>
<g class="shape2" transform="matrix(1 0 0 1 0 0)">
<ellipse rx="70" ry="70" cx="400" cy="400"></ellipse>
</g>
</g>
</svg>
I created a JsFiddle http://jsfiddle.net/tYqdk/30/
. In the fiddle shape1 (Ellipse with color green) is rotated. When apply scale to the parent element shape1 become skewed.
When the rotation of child element is 90,180,270, or 360 there is no issues.
Is there any way to fix this issue?.
If you want a child element to appear unaffected by the parent's transform, then you will need to apply an inverse transform to the child.
Why is the child even inside the group if it isn't meant to be affected by changes to the group properties? Move it outside the group or move the transform down to the children you want it to affect.