canvas连线

本文通过HTML5的Canvas API展示了如何实现图形之间的动态连线功能,主要利用JavaScript进行交互控制。结合提供的源代码,读者可以了解到Canvas绘图的基础及动态效果的实现技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图



源代码

<!DOCTYPE html>
<html lang="zh-CN">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <meta charset="UTF-8">
    <head></head>
    <style>
		*{
			margin: 0;
			padding: 0;
		}
		div{
			display: inline-block;
			width: 50px;
			margin-right: 100px;
			height: 300px;
		}
		a{
			width: 50px;
			height: 50px;
			display: block;
			border:1px solid #000;
			cursor: pointer;
		}
		a.active{
			border:1px solid #f00;
		}
		canvas{
			/*border:1px solid #000;*/
			position: absolute;
			top: 0;
			left: 56px
		}
    </style>
    <body>
        <input name="question1" type="hidden">
        <input name="question2" type="hidden">
        <input name="question3" type="hidden">
        <input name="question4" type="hidden">
		<div class="J_div1">
			<a data-conkey="question1"></a>
			<a data-conkey="question2"></a>
			<a data-conkey="question3"></a>
			<a data-conkey="question4"></a>
		</div>
		<div class="J_div2">
			<a data-convalue="1"></a>
			<a data-convalue="2"></a>
			<a data-convalue="3"></a>
			<a data-convalue="4"></a>
		</div>
		<canvas id="canvas" width="96" height="200"></canvas>
		<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
		<script>
			$.connect=function(o){
				if (!o||!o.qesele||!o.ansele||!o.canvas) {return false;};

				o.type=o.type||'click';
				o.className=o.className||'active';
				var _can=document.querySelector(o.canvas);
				var $qes=$(o.qesele).addClass('qes');
				var $ans=$(o.ansele).addClass('ans');
				var $as=$qes.add($ans);

				if (!_can||$qes.length==0||$ans.length==0) {return false;};

				var ll={};
				$cl.result=ll;
				var _wid=_can.width||300,_hei=_can.height||300,ctx=_can.getContext('2d');
				var item=$qes.length;
				var j=_hei/item,k=j/2;
				var _arr3=[];
				var count=0;
				for (var i = 0; i < item; i++) {
					_arr3.push(i*j+k);
				};

				if (o.type=="click") {
					_click();
				}else{
					_drag();
				}
				
				$(document).click(function(){
					removeCN($as);
				});
				function setLine(){
					var cn=o.className;
					var a1=$qes.filter('.'+cn),
						a2=$ans.filter('.'+cn);
					var index1,index2;
					var question,answer;
					if (a1.length==1&&a2.length==1) {
						index1=$qes.index(a1);
						index2=$ans.index(a2);
						question=a1.attr('data-conkey');
						answer=a2.attr('data-convalue');
						setUnion(index1,index2,question,answer);
						makeLine();
					};
				}
				function makeLine(){
					ctx.clearRect(0,0,_wid,_hei);
					for(var pro in ll){
						ctx.beginPath();
						var i=ll[pro][0];
						var j=ll[pro][1];
						ctx.moveTo(0,_arr3[i]);
						ctx.lineTo(_wid,_arr3[j]);
						ctx.stroke();
					}
					if (typeof o.success ==='function') {
						o.success($cl);
					};
					removeCN($as);
				}
				function setUnion(index1,index2,question,answer){
					var i=0;
					var p1,p2,temp=[];
					for(var p in ll){
						var pro=ll[p];
						if (pro[0]==index1) {
							p1=pro;
							i++;
						}
						if(pro[1]==index2){
							p2=pro;
							i++;
						}
					}
					if (i!=0) {
						if (p1&&p2) {
							temp=[p1[0],p1[1],p1[2],p1[3]];
							p1[1]=p2[1];
							p1[3]=p2[3];
							p2[1]=temp[1];
							p2[3]=temp[3];
							$cl.a1=p1[2];
							$cl.q1=p1[3];
							$cl.a2=p2[2];
							$cl.q2=p2[3];
						}else if (p1) {
							p1[1]=index2;
							p1[3]=answer;
							$cl.a1=p1[2];
							$cl.q1=p1[3];
							$cl.a2='';
							$cl.q2='';
						}else if (p2) {
							$cl.a2=p2[2];
							$cl.q2='';

							p2[0]=index1;
							p2[2]=question;
							$cl.a1=p2[2];
							$cl.q1=p2[3];
							
						};
					}else{
						ll['index'+count]=[index1,index2,question,answer];
						$cl.a1=question;
						$cl.q1=answer;
						$cl.a2='';
						$cl.q2='';
						if (count!=_arr3.length-1) {
							count++;
							$cl.count=count;
						};
					};
				}
				function _click(){
					$as.parent().on('click','.qes,.ans', function(event) {
						event.stopPropagation();
						var $this=$(this);
						var $a=$this.hasClass('qes')?$qes:$ans;
						removeCN($a);
						$this.addClass(o.className);
						setLine();
					});
				}
				function _drag(){
					$as.attr('draggable','true');
					$as.each(function(index,ele){
						ele.ondragstart=function(){
							var $this=$(this);
							var cn=o.className;
							var $a=$this.hasClass('qes')?$qes:$ans;
							removeCN($a);
							$this.addClass(cn);
						};
						ele.ondragover=function(){
							var $this=$(this);
							var cn=o.className;
							var $a=$this.hasClass('qes')?$qes:$ans;
							removeCN($a);
							$this.addClass(cn);
						};
						ele.ondragend=function(event){
							event.preventDefault();
							setLine();
						};
					});
				}
				function removeCN($ele){
					$ele.removeClass(o.className);
				}
				return $cl;
			};
			var $cl=$.connect({//返回一个对象,包括count、result、a1、q1、a2、q2属性
				qesele:'.J_div1 a',  //连线目标元素1
				ansele:'.J_div2 a',  //连线目标元素2
				canvas:'#canvas',    //需要画线的canvas
				className:'active',  //设置选中类名,默认为“active”
				type:'drag',   //drag拖动连线,click单击连线,默认click
				success:function(result){  //绘图回调函数,result
					//result.count;连了多少条线
					//result.a1、result.q1当前画的第一条线
					//result.a2、result.q2当前画的第二条线
					var a1=result.a1,q1=result.q1;
					var a2=result.a2,q2=result.q2;
					var inp1=$('input[name="'+a1+'"]');
					inp1.val(q1);
					if (a2) {
						$('input[name="'+a2+'"]').val(q2);
					}
				}
			});

		</script>
    </body>
</html>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值