蛙蛙推荐:用VML做思维管理工具

蛙蛙推荐:用VML做思维管理工具
摘要:应该大多数人用过MindManger和OneNote等软件,他们用来描述你的想法,做会议记录,工作笔记等,在界面的任何地方都可以写上文字,并可以拖动,而且文字之间还可以用线连接起来,甚至还有手绘涂鸦功能。

思路:IE很早就支持VML了,可以在网页上画矢量图形,而且和javascript能很好的交互,然后捕获用户的鼠标键盘等事件做相应的处理就可以了。
关于VML的入门及提高,大家可以搜索美洲豹的《Thinking in VML》及沐缘华的《VML极道编程》
 

先截图看看

使用介绍如下:
1、在网页的任何空白处用鼠标左键拖动可以涂鸦,便于临时记录一些文字;
2、在网页的任何空白处双击鼠标左键,会显示一个可编辑框,编辑框的浅黄色部分可以输入文字(鼠标会变成可输入形状),点击左上角的+/-图标可以展开和收缩文字,用鼠标拖动编辑框上部淡蓝色的部分(鼠标会变成可拖动形状)可以把文字框拖动到别的地方。
3、用鼠标左键点击某一个编辑框的淡蓝色部分,按住Shift键不放,拖拽到另一个编辑框,会在两个编辑框之间画一条线,然后再移动编辑框,这条线会跟着动。用来表示两条关联的信息。
4、点击铅笔笔记、连接曲线、编辑框,会变成选中状态,其边框会编程虚线,然后按delete键可以删除
5、两个编辑框之间的连接曲线可以选中后用鼠标拖动以改变曲度,按住alt键拖动是变化第2个控制点,不按alt键是变化贝塞尔曲线的第1个控制点。

[bug]
!解决了不能拖动滚动条的bug
!物体超出浏览器后,整个坐标系不准确了,而且画布不能超出浏览器区域。

罗列了一些需要增加的功能点,周末实现一下,大家还有什么新需求,觉得很有必要的,也提一下。
我在IE6,IE7下测试通过,有同学反映IE8下不能运行,大家也帮忙测试一下,我没有IE8环境,我的2003安装不上。

todo:
1、删除连接线、编辑框、手绘线==ok
2、改变画笔粗度和颜色
3、编辑框的格式化功能,加粗,字体大小、颜色等
4、两个编辑框之间的连线应该显示箭头,要不知道两个编辑框的关系
5、改变编辑框的图标和颜色,以表示不同的重要性和类别
6、按tab键自动添加兄弟节点,按回车自动添加子节点
完整代码如下

 

<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< html  xmlns:v ="urn:schemas-microsoft-com:vml"  xmlns ="http://www.w3.org/1999/xhtml"   >
< head >
 
< title > WawaMind beta v1.0 </ title >
</ head >
< style  type ="text/css" >
 v/:* 
{  BEHAVIOR :  url(#default#VML)  }
 body 
{
 margin-left
:  0px ;
 margin-top
:  0px ;
 margin-right
:  0px ;
 margin-bottom
:  0px ;
 cursor
: default ;
 width
: 1000px ;
}
 .wen
{
   padding-top
: 3px ;
   padding-left
: 3px ;
   padding-bottom
: 3px ;
   padding-right
: 3px ;
   FONT-SIZE
:  9.2pt ;  LINE-HEIGHT :  20px ;
   BACKGROUND-COLOR
:  #99ccff ;
   BORDER-BOTTOM
:  #330099 1px solid ;  
   BORDER-LEFT
:  #330099 1px solid ;  
   BORDER-RIGHT
:  #330099 1px solid ;  
   BORDER-TOP
:  #330099 1px solid ;   
   
/* filter:Alpha(Opacity="80",FinishOpacity="90",Style="0"); */
   cursor
: move ;
   z-index
: 100 ;
   
}
.editdiv
{
    OVERFLOW
:  auto ;  background-color : #fff999 ;  cursor : default ;
    height
: 50px ;
}
.editdiv p
{
 margin
: 0 ;
}
.expanbutton
{
cursor
: hand ;  font-weight : bold ;  font-size : 20px ;
}
</ style >
< script  type ="text/javascript" >
var  xx = 0 ,yy = 0 ,oldvalue = "" ,poly1,zz = 1  
// 有关移动的过程和函数
var  dragapproved = false
var  eventsource,x,y
var  popeventsource = ""
var  Pencil  =   true ;
var  selectObj,selectObjBorder  =   null ;

// 页面双击创建编辑框
function  dbClick() {
    
if  (event.srcElement.className != " body " return ;
    
var  markhtml  = " <div class='wen' style='position:absolute;left: " + window.event.offsetX + " ;top: " + window.event.offsetY + " ;width:150px;z-index:9'></div> " ;
    
var  newMark = document.createElement(markhtml);
    document.body.appendChild (newMark);
    newMark.innerHTML 
=   " <span class=/ " expanbutton/ "  onclick=/ " expandMemo( this )/ " >-</span><span></span><div class=/ " editdiv/ "  contentEditable=true onselectstart=/ " event.cancelBubble = true / " ></div> " ;
    newMark.fromline 
=   new  Array();
    newMark.toline 
=   new  Array();
}

// 鼠标按下
function  msDown() {
    
if (event.button == 1 ){
        
var  isclickScroll =  (event.y  <   0   ||  event.y  >  document.body.clientHeight 
            
||  event.x  <   0   ||  event.x  >  document.body.clientWidth)
        
if (selectObj){  // 清空选择
                selectObj.style.borderStyle  =  selectObjBorder;
                selectObj 
=   null ;
        }
        
if (event.srcElement.className == " wen "   ||
           event.srcElement.tagName 
==   " curve "   ||
           event.srcElement.tagName 
==   " shape "
           ) 
// 选择要删除的对象
        {
            selectObj 
=  event.srcElement;
            selectObjBorder 
=  selectObj.style.borderStyle;
            selectObj.style.borderStyle 
=   " dotted " ;
            selectObj.style.borderWidth  
=   " 1px " ;
            
        }
        
if  (event.srcElement.className == " wen " )
        {
            
if (event.shiftKey)  // 画两个物体间的线
            {
                eventsource
= event.srcElement;
                
return ;
            }
            dragapproved
= true   // 拖动物体
            eventsource = event.srcElement
            temp1
= eventsource.style.pixelLeft
            temp2
= eventsource.style.pixelTop
            x
= event.clientX
            y
= event.clientY
        }
else // 铅笔
             dragapproved = false ;
             
if  (event.srcElement.className != " body "   ||  isclickScroll)   // 防止在物体上画线
             {

                 Pencil 
=   false ;
                 
return ;
             } 
             Pencil 
=   true ;
            document.body.setCapture(); 
            color1
= " red "
            size1
= 1  
            xx
= event.offsetX;yy = event.offsetY;zz += 1
            poly1
= document.body.appendChild(document.createElement( " <v:shape filled=false path='m0,0 l0,0' style='position:absolute;z-index: " + zz + " ;left: " + xx + " ;top: " + yy + " ;width:100;height:100' strokecolor=' " + color1 + " ' strokeweight=' " + size1 + " ' coordsize='100,100'/> " )) 
            oldvalue
= poly1.path.value.replace( " e " , ""
        }
    }
}
// 鼠标移动
function  msMove() {
    
if (event.button == 1 )
    {
        
if (event.shiftKey)  // 画两个物体件的线
        {
            
return ;
        }
        
if (dragapproved){  // 拖动物体
             var  newleft = temp1 + event.clientX - x
            
var  newtop = temp2 + event.clientY - y
            eventsource.style.pixelLeft
= newleft
            eventsource.style.pixelTop
= newtop
            
            
// 移动线
             for ( var  i  =   0 ; i <  eventsource.fromline.length;i ++ )
            {
                eventsource.fromline[i].from 
=  newleft  + " , " +  newtop;
            }   
            
for ( var  i  =   0 ; i <  eventsource.toline.length;i ++ )
            {
                eventsource.toline[i].to 
=  newleft  + " , " +  newtop;
            }        
        }
        
else   if (selectObj  &&  selectObj.tagName  ==   " curve " )
        { 
// 调整曲线
             if ( ! event.altKey)
                selectObj.control1 
=  event.x + " , " + event.y;
            
else
                selectObj.control2 
=  event.x + " , " + event.y;
        }
        
else { // 铅笔功能
             if  (event.srcElement.className != " body " return // 防止在物体上画线
             if (Pencil)
            {
                oldvalue
+= " , " + (event.offsetX - xx) + " , " + (event.offsetY - yy);
                poly1.path.value
= oldvalue 
                poly1.path.value
= poly1.path.value.replace( " ,0, " , " , " ).replace( " ,0 e " , " e " )     
            }
        }        
    }
}
// 鼠标弹起
function  msUp() {
 document.body.releaseCapture(); 
    
if  (event.shiftKey  &&  event.srcElement.className == " wen " // 画两个物体见的连线。
    {
        
var  target  =  event.srcElement;
        
var  newline = document.createElement( " <v:curve filled=/ " false / "  from= " + eventsource.style.pixelLeft + " , " + eventsource.style.pixelTop + " / "  to = / "" + target.style.pixelLeft + " , " + target.style.pixelTop + " / " >< / v:curve>");
        document.body.insertBefore(newline);
        eventsource.fromline[eventsource.fromline.length] 
=  newline;
        target.toline[target.toline.length] 
=  newline;
    }
}
// 控制编辑框的展开和收缩
function  expandMemo(o)
{
    
var  expand  =  o.innerText  ==   " + " ;
    
var  text  =  o.parentNode.childNodes[ 2 ].innerText;
    o.parentNode.childNodes[
1 ].innerText  =  expand  ?   "" :text.substring( 0 , 10 );
    o.parentNode.childNodes[
2 ].style.display  =  expand  ?   ' block ' : ' none ' ;    
    o.innerText 
=  expand   ?   " - "  : " + " ;
}
function  keyDown() {
  
if (event.keyCode  ==   46 // 删除
  {
      
if (selectObj)
      {
         document.body.removeChild(selectObj);
         selectObj 
=   null ;
      }
  }
}
document.onkeydown 
=  keyDown 
</ script >
< body  class ="body"   ondblclick ="dbClick()"  onmousedown ="msDown()"  onmousemove ="msMove()"  onmouseup ="msUp()"  onselectstart ="return false;" >
</ body >
</ html >

在地址栏里输入如下文本可以查看运行时生成的html
javascript:document.body.innerHTML%20=%20"<textarea%20style='height:300;%20width:300'>"+document.body.innerHTML+"</textarea>"
或者大家可以用这些代码做一个在线创作脑图的网站,我觉得这东西不一定做的功能多么强大,尽量在简单易用和满足需求之间找到平衡就可以了,我觉得现在的功能能满足我的需求。

winform的工具做好了,欢迎大家下载适应,并反馈信息,周末比较忙,新增功能暂时不做了,另外就是c#的WebBrowser控件为什么只显示竖滚动条,不显示横向滚动条呀,不解决这个问题,画的东西超过画布宽度的话就画不出去了显示不了了。
以下是下载地址。

WawaMind.zip
  

[参考链接]
记录鼠标轨迹生成vml曲线图程序(可模拟签名)
http://blog.csdn.net/manyou/archive/2005/09/28/491036.aspx

VML打造动态曲线[建议加精]
http://bbs.51js.com/viewthread.php?tid=21639&extra=page%3D1%26amp%3Bfilter%3Ddigest

VML实现铅笔功能?
http://bbs.51js.com/viewthread.php?tid=80191&extra=page%3D1

Javascript技术之详尽解析event对象
http://javascript.chinahtml.com/2007/Javascriptjavascript-118033875213857_3.shtml

How the Javascript Vector Engine Works
http://www.xmlpitstop.com/ArticleManagement/DisplayArticle.aspx?ResourceID=24

[翻译] 6个优秀的思维导图网站
http://bbs.kafan.cn/thread-312112-1-6.html

 

JavaScript键盘事件侦听
http://www.blogjava.net/zhangrenquan/articles/60110.html

在BODY用onSelectStart=return false 不让选择,但是页面上的文字输入框怎样可以设置到可选择.
http://topic.csdn.net/t/20030112/17/1351341.html

JavaScript高级测试题-你真的了解JavaScript?
http://www.ad0.cn/netfetch/read.php/1173.htm

用 Javascript 获取滚动条位置等信息
http://www.codebit.cn/pub/html/javascript/tip/get_scroll_position/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值