Including an svg element in my html breaks jquery ui - javascript

I am having a very weird issue that I have no idea whatsoever how to debug.
I have a html file with a div that has the jquery UI draggable enabled:
$(function() {
$(".ideanode").draggable({ containment: "parent" });
});
this is working fine and dandy until I include this in my html:
<svg id="connectors" height="100%" width="100%">
<defs>
<marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6"
orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" />
</marker>
</defs>
<line x1="0" y1="0" x2="200" y2="100" class="arrow" />
</svg>
This just completely removes the draggable functionality of my div and I can't even begin to understand why. I will link to a full example as well.
https://codepen.io/ricodon1000/pen/XWmqxeB
If any additional information is needed please ask, I'm still learning how to post really good questions here. Thank you!

add a global style
svg{
background:red;
opacity:.5;
}
and you will see the SVG is covering the whole screen, thus blocking every element underneath

Related

Possible work-around for Chrome clip-path bug with SVG

I created a minimal example to demonstrate a Chrome bug I recently ran into:
const main = document.getElementById('main');
const topHover = document.getElementById('top-hover');
topHover.addEventListener('mouseenter', function(e) {
main.setAttribute('clip-path', 'url(#top-clip)');
});
topHover.addEventListener('mouseleave', function(e) {
main.setAttribute('clip-path', 'url(#everything)');
});
const bottomHover = document.getElementById('bottom-hover');
bottomHover.addEventListener('mouseenter', function(e) {
main.setAttribute('clip-path', 'url(#bottom-clip)');
});
bottomHover.addEventListener('mouseleave', function(e) {
main.setAttribute('clip-path', 'url(#everything)');
});
//main.setAttribute('clip-path', 'url(#everything)');
#main {
fill: #51D2C3;
}
#bg {
fill: #E1F5F2;
}
#top-hover {
fill: none;
}
#bottom-hover {
fill: none;
}
<svg height="200" width="300">
<path id="bg" d='M100 50 h50 v50 h50 v50 h-50 v50 h-50 v-50 h-50 v-50 h50 z'></path>
<path id="main" clip-path='url(#everything)' d='M100 50 h50 v50 h50 v50 h-50 v50 h-50 v-50 h-50 v-50 h50 z'></path>
<g>
<clipPath id="everything"></clipPath>
<rect id="top-hover" pointer-events="all" x="50" y="50" width="150" height="75"></rect>
<clipPath id="top-clip">
<use href="#top-hover"></use>
</clipPath>
<rect id="bottom-hover" pointer-events="all" x="50" y="125" width="150" height="75"></rect>
<clipPath id="bottom-clip">
<use href="#bottom-hover"></use>
</clipPath>
</g>
</svg>
The bug seems to be in how Chrome treats clip-path that's created at the same time as SVG element creation. It seems that whatever is applied to SVG element as initial clip-path becomes a permanent implicit clip-path that can't be unset via JavaScript. I reported it already here: https://bugs.chromium.org/p/chromium/issues/detail?id=1045915
in Chrome hover states don't work.
in Firefox they work as expected.
if you remove clip-path property from object with id="main" in HTML/SVG portion, and set it programmatically via JavaScript (see commented out line), hovering works as expected in Chrome as well.
if you don't set initial clip-path at all, hovering works as expected in Chrome (aside from starting out in "on" state for all regions)
if you change initial clip-path to something else (update HTML/SVG clip-path for id="main" element to either url(#top-clip) or url(#bottom-clip)), only the initially non-clipped region will render when new clip-path is applied.
From this, I conclude that that Chrome erroneously treats clip-path that's set at the time of SVG element creation as a permanent implicit clip-path that's applied on top of current clip-path.
This is a simplified example of my actual logic. In my logic I'm creating the above definition via d3.js, adding a delay to applying clip-path (even something as low as a microsecond), seems to solve the issue but seems like a hack. Is there a cleaner workaround or an alternative way to define similar functionality that mitigates this bug?

How does "text-align: justify" works?

Hello I am writing a lib. for creating composition of texts, internal customisation. - d3-fusiontext.
I want to support
text-align: Justify
The user say provides me a long text. Mentions the height and width it would like to be rendered. The lib. wraps it up, and provides a good visual with wrapped texts. They are all svg text elements so that it can be exported too.
Now I would be to curious to know how the browser internally aligns in a justified manner? Any source/ links/ topics to start with. Any help/ guidance is highly appreciated.
This is a good example of how things might look.
codepen.io/anon/pen/zxNJKE
P.S: Sorry about no gh-pages and docs as the stuff is under dev. Will update.
Just a generalized curiosity how does the browser determines the spacings in justified alignment?
There are other answers on SO which provide information on how you can do text wrapping.
Word Wrap in Raphael JS / SVG
How to either determine SVG text box width, or force line breaks after 'x' characters?
Once you work out which characters/words fit on the line, you can use the textLength and lengthAdjust attributes to get SVG to stretch the line to fit the width.
<svg width="10cm" height="3cm" viewBox="0 0 1000 300"
xmlns="http://www.w3.org/2000/svg" version="1.1">
<line x1="200" y1="0" x2="200" y2="300" stroke="red"/>
<line x1="800" y1="0" x2="800" y2="300" stroke="red"/>
<text x="200" y="100"
font-family="Verdana" font-size="55" fill="blue" >
Hello, out there
</text>
<text x="200" y="170"
font-family="Verdana" font-size="55" fill="blue"
textLength="600" lengthAdjust="spacing">
Hello, out there
</text>
<text x="200" y="240"
font-family="Verdana" font-size="55" fill="blue"
textLength="600" lengthAdjust="spacingAndGlyphs">
Hello, out there
</text>
<!-- Show outline of canvas using 'rect' element -->
<rect x="1" y="1" width="998" height="298"
fill="none" stroke="blue" stroke-width="2" />
</svg>

Detecting when a SVG animation has ended

I have a SVG image inside my body tag that is being animated by the following code:
<clipPath id="left-to-right">
<rect x="0" y="0" width="0%" height="100%" >
<animate attributeName="width" values="0%;100%" dur="5s" fill="freeze"/>
</rect>
</clipPath>
I'm adding the .svg to the body via an image tag like so:
<body>
<div id="loading-container">
<img id="silhoutte" src="Images/Silhoutte.svg">
</div>
<div id="content">
/* Content in here */
<div>
</body>
The svg is serving as a "loading" animation while i preload/cache some high resolution images before displaying the actual content.
My difficulty is in trying to detect the end of the SVG animation in order to reveal the content div. How would i go about detecting the animation if at all possible?
I'm open to suggestions on better ways to implement a web page loading screen using the animated SVG i created.
Thank you!
The SVG animation element should fire an endEvent once the animation is finished, so something like this should work:
document.querySelector('#left-to-right animate').addEventListener('endEvent', function() {
console.log('Animation finished');
}, false);

Changing Clickable Area of an Image without Resizing Image

I am currently working on a PHP/Javascript project where an action occurs when an image is clicked. The image is small, so I would like to expand the clickable area to further around the image without enlarging the image itself. Is this possible? Below is a general idea of the structure of what I'm working on.
<g id="pictures">
<image id="marker_image" cx="145" cy="460" r="1" preserveAspectRatio="none"
x="136" y="451" width="18" height="18"
xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="//link.thislink.com/image_assets/markers/pool.png"
style="opacity: 1" fill="#000000" fill-opacity="1" stroke="#000000"
stroke-opacity="1" stroke-width="2" stroke-linecap="round" stroke-
linejoin="round"></image>
</g>
I'm new to working with SVGs, but from what I've read, I think I can use the <g> to add padding?
Wrap you image in a div, make the div as big as you want using padding, and bind your action on the div instead of the img

Draw an arrow between two divs

I'm searching for a solution of the question that I expected to be solved already.
But I saw only big projects with a lot of features but no simple solution.
Actually I need to get something like that:
So to get an arrow drawing over a div containing some squares (divs)
<div id="container">
<div class="white_field"></div>
<div id="1" class="black_field">
<br style="clear:both;">
<div id="2" class="black_field">
<div class="white_field"></div>
<br style="clear:both;">
<div id="3" class="black_field">
<div class="white_field"></div>
</div>
I looked in the canvas direction but stumbled on tha canvas was not visible behind my divs ( maybe some z-index should help )
But still strange that I couldn't find some ready-made solution of a problem that seems to me coming up often.
( to explain some thing on the site arrows are almost a must )
You might consider SVG.
In particular, you can use a line with a marker-end shaped with an arrow-path.
Be sure to set orient=auto so the arrowhead will be rotated to match the slope of the line.
Since SVG is a DOM element, you can control the start/end position of the line in javascript.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/9aCsJ/
<svg width="300" height="100">
<defs>
<marker id="arrow" markerWidth="13" markerHeight="13" refx="2" refy="6" orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" style="fill:red;" />
</marker>
</defs>
<path d="M30,150 L100,50"
style="stroke:red; stroke-width: 1.25px; fill: none;
marker-end: url(#arrow);"
/>
</svg>
I highly recommended this library: https://anseki.github.io/leader-line/
It's pretty powerful, fast, super easy to use and it worked flawlessly for me.
I have no idea whether anybody looks at this thread anymore but here's the solution i used, it differs only slightly from #markE answer in that this answer makes it much easier to specify exactly where the line needs to start and stop.
<head>
<style>
.arrow{
stroke:rgb(0,0,0);
stroke-width:2;
marker-end:url(#markerArrow)
}
</style>
</head>
<body>
<svg height="210" width="500">
<defs>
<marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6"
orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
</marker>
</defs>
<line x1="0" y1="0" x2="200" y2="100" class="arrow" />
</svg>
</body>
All you have to do is change the x and y coordinates of the line! I used this answer in my react app and it worked beautifully.
And heres the fiddle.
.arrow {
stroke: rgb(0, 0, 0);
stroke-width: 2;
marker-end: url(#markerArrow)
}
<svg height="210" width="500">
<defs>
<marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6" orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
</marker>
</defs>
<line x1="0" y1="0" x2="200" y2="100" class="arrow" />
</svg>
Use a library, like JSPlumb: https://jsplumbtoolkit.com/
Its fairly simple to create the arrow head. See this example on CSS Tricks.
Maybe using this inside a container which has the arrow line might do it.
Canvas and jCanvas
Based on your needs, you should definitely check out using Canvas and the jCanvas library. It makes things like this a breeze.
I ventured down the road of doing everything with DIVs and jQuery but it always fell short on interactivity and quality. This really kicks open the doors without adding code complexity.
Hope that helps others, like me.
JP
EDIT 2017 05 20:
I used to have an example here that linked to the jCanvas' sandbox with all the code you needed to draw an arrow between two elements and drag both of those elements around the canvas. However, that link no longer works and I don't have the code anywhere else.
So, I still think you should check out jCanvas but unfortunately I don't have any sample code to start you off.
I recommend using this:
https://www.cssscript.com/connect-elements-directional-arrow/
Very simple to use :)
You can do this then:
<connection from="#id_1" to="#id_2" color="red" tail></connection>
How to include it:
You extract the .zip file to your projects folder.
Either copy over the CSS & JavaScript to your project, or add a reference to those files in your project:
<head>
<!-- Your head-codes here -->
<link rel = "stylesheet" type = "text/css" href = "../plugins/domarrow.js-master/domarrow.css"/>
</head>
<body>
<!-- Your body-codes here -->
<script src="../plugins/domarrow.js-master/domarrow.js"></script>
</body>
In my case the file structure is:
C/MyProject/:.
│
├───css
│ start.css
│
├───html
│ start.html <--- write here
│
├───js
│ start.js
│
└───plugins
│
└───domarrow.js-master
domarrow.css
domarrow.js
That's why I need the "../" in the beginning of the relative path, it means "step out one level", so for example: "../plugins" exits the "html" folders & goes into the "plugins" folder instead.
Adjust the file-path according to your file layouts.

Categories