jQuery/CSS to show merge style relationship between two columns like FileMerge
I'd like to show the end user two documents side by side in separate columns. The document on the left makes a reference to the document on the right. I'd like to show this relationship by highlighting the text in the left column that makes the reference, and the referenced text on the right. This is easy enough with basic CSS. I'd like to take it a step further however and actually draw a connection between the two columns.
I suppose a screen shot is the easiest way to explain what I'd like to accomplish.
It's important that both columns scroll independently of each other, yet the lines connecting the two highlighted sections should remain accurate and update as the columns are scrolled.
Is there a way to accomplish this without using Flash or HTML 5 canvas? Are there any ready made jQuer开发者_Go百科y plugins to accomplish this?
As far as I know, the only one that does something similar to this is the jsdifflib. If I were you, I'd scour the source of that library and turn it into a jQuery plugin. Then, I'd figure out where it's drawing the side-by-side data and insert your own rendering logic. The sort of thing you want to happen can be done using only CSS, but it will take some serious tinkering around with the border-radius property (which has a little bit more browser-wide implementation than the <canvas>
element (though the 2d context of <canvas>
is getting pretty wide-spread).
For example, you can make a circle out of a regular div by doing this:
HTML
<div id="test"></div>
CSS
#test {
width:50px;
height:50px;
border-radius:25px;
background-color:#333;
}
Yields:
The unfortunate thing about the border-radius property is that you can't do a negative radius that flips the convexity (or whatever you want to call it) of the corner. In order to start getting effects like this, you need to combine elements that have border-radius set on them. So let's take a look at something like this:
HTML
<div id="container">
<div id="test"></div>
<div id="covertest"></div>
</div>
CSS
#container {
position:relative;
}
#test {
position:absolute;
width:200px;
height:200px;
background-color:#333;
}
#covertest {
position:absolute;
width:200px;
height:100px;
top:100px;
background-color:#eee;
border-top-right-radius:200px 100px;
}
Yields:
Now, the really annoying bit is that this is as stretched as I can get it using just two divs (and a container to position them properly absolutely). Still..this is pretty good even if it doesn't give you the exact shape you were looking for.
Naturally, you can come up with any combination of divs you can think of, so use your brain with me for a moment and see what you can't come up with. I'm going to tinker with this some more and see what I can do.
Edit: Alright, I've thought a little more about how to do this, and I've come up with a working solution. Consider this:
HTML
<div id="container">
<div id="covertestleft"></div>
<div id="covertestmiddle"></div>
<div id="coverbottomright"></div>
<div id="covertestright"></div>
</div>
CSS
#container {
position:relative;
width:200px;
height:200px;
background-color:#333;
overflow:hidden;
}
#covertestleft {
position:absolute;
width:40px;
top:100px;
bottom:0px;
background-color:#eee;
border-top-right-radius:40px 40px;
}
#covertestmiddle {
position:absolute;
top:109px;
bottom:-50px;
left:25px;
border-left:160px solid #eee;
border-right:50px solid transparent;
border-top:85px solid transparent;
}
#covertestright {
position:absolute;
right:0px;
bottom:8px;
width:30px;
height:100px;
background-color:#333;
border-bottom-left-radius:40px 10px;
}
#coverbottomright {
position:absolute;
right:0px;
bottom:0px;
width:30px;
height:100px;
background-color:#eee;
}
Yields:
This is pretty close to the effect you were trying to achieve. What you could do is create a class that produces this sort of block given a certain width and height of two blocks it's trying to link up. It'll take some learning of the nitty-gritty of these CSS properties in order to be able to transform it to different width and height values, but it's not at all impossible.
Aside from this solution, I'm fairly sure there's no way to accomplish this outside of using the <canvas>
element or a third-party plugin like Flash or Silverlight.
You can make trapezium with CSS like this, if you're willing to forgo the round bits:
http://jsfiddle.net/Eric/V9jbz/
精彩评论