UNPKG

veheeavis

Version:

Vehicle Electrical/Electronic Architecture Visualizer

2 lines (1 loc) 8.55 kB
!function(t){"function"==typeof define&&define.amd?define(t):t()}((function(){"use strict";var t,i;t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0,i=function(){class Ploteeavis{constructor(t){this.container=document.querySelector(t.container),this.data=t.data,this.styles=t.styles,this.scale=1,this.draggingModule=null,this.dragOffsetX=0,this.dragOffsetY=0,this.startPort=null,this.endPort=null,this.canvas=document.createElement("canvas"),this.container.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.dpr=window.devicePixelRatio||1,this.canvas.style.width=this.container.clientWidth+"px",this.canvas.style.height=this.container.clientHeight+"px",this.canvas.width=this.container.clientWidth*this.dpr,this.canvas.height=this.container.clientHeight*this.dpr,this.ctx.scale(this.dpr,this.dpr),this.view={x:0,y:0,zoom:1},this.validateData(this.data),this.addEventListeners(),this.render()}render(){this.ctx.save(),this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.portRects=[],this.ctx.translate(this.view.x*this.dpr,this.view.y*this.dpr),this.ctx.scale(this.view.zoom,this.view.zoom),this.data.modules.forEach((t=>{this.drawModule(t),this.drawPorts(t)})),this.data.modules.every((t=>t.leftArray&&t.rightArray&&t.topArray&&t.bottomArray))&&this.data.connections.forEach((t=>{this.drawConnection(t)})),this.startPort&&this.endPort?this.drawTempConnection(this.startPort,this.endPort):this.startPort&&this.drawTempConnectionToMouse(this.startPort,this.mouseX,this.mouseY),this.ctx.restore()}drawPorts(t){const{x:i,y:o,width:s,height:e}=t.position,h=t.leftArray,n=e/(h.length+2),r=6,a=i-3;h.forEach(((s,e)=>{const h=o+(e+1)*n;this.ctx.fillStyle=`rgb(${100*s.portcolor}, 0, 0)`,this.ctx.fillRect(a,h,6,10),s.offsetX=a-i,s.offsetY=h-o,s.width=6,s.height=10;const r=new Rectangle(a,h,6,10);r.port=s,r.module=t,this.portRects.push(r)}));const c=t.rightArray,d=e/(c.length+2),l=6,f=i+s-3;c.forEach(((s,e)=>{const h=o+(e+1)*d;this.ctx.fillStyle=`rgb(${100*s.portcolor}, 0, 0)`,this.ctx.fillRect(f,h,6,10),s.offsetX=f-i,s.offsetY=h-o,s.width=6,s.height=10;const n=new Rectangle(f,h,6,10);n.port=s,n.module=t,this.portRects.push(n)}));const p=t.topArray,u=s/(p.length+2),g=6,y=o-3;p.forEach(((s,e)=>{const h=i+(e+1)*u;this.ctx.fillStyle=`rgb(${100*s.portcolor}, 0, 0)`,this.ctx.fillRect(h,y,10,6),s.offsetX=h-i,s.offsetY=y-o,s.width=10,s.height=6;const n=new Rectangle(h,y,10,6);n.port=s,n.module=t,this.portRects.push(n)}));const x=t.bottomArray,m=s/(x.length+2),w=6,v=o+e-3;x.forEach(((s,e)=>{const h=i+(e+1)*m;this.ctx.fillStyle=`rgb(${100*s.portcolor}, 0, 0)`,this.ctx.fillRect(h,v,10,6),s.offsetX=h-i,s.offsetY=v-o,s.width=10,s.height=6;const n=new Rectangle(h,v,10,6);n.port=s,n.module=t,this.portRects.push(n)}))}validateData(t){const i=t.modules.map((t=>t.name));t.connections.forEach((t=>{if(!i.includes(t.from)||!i.includes(t.to))throw new Error(`Invalid connection: ${t.from} -> ${t.to}`)}))}addEventListeners(){this.portRects=[],this.canvas.addEventListener("mousedown",(t=>{const i=this.getCanvasCoords(t.clientX,t.clientY),o=this.portRects.find((t=>t.contains(i.x,i.y)));o?(this.startPortRect=o,this.startPort=o.port,this.startPort.module=o.module):this.data.modules.forEach((t=>{const{x:o,y:s,width:e,height:h}=t.position;i.x>=o&&i.x<=o+e&&i.y>=s&&i.y<=s+h&&(this.draggingModule=t,this.dragOffsetX=i.x-o,this.dragOffsetY=i.y-s)}))})),this.canvas.addEventListener("mousemove",(t=>{const i=this.getCanvasCoords(t.clientX,t.clientY);this.mouseX=i.x,this.mouseY=i.y;const o=this.portRects.find((t=>t.contains(i.x,i.y)));this.canvas.style.cursor=o?"pointer":"",this.startPort?this.render():this.draggingModule&&(this.draggingModule.position.x=i.x-this.dragOffsetX,this.draggingModule.position.y=i.y-this.dragOffsetY,this.updatePorts(this.draggingModule),this.render())})),this.canvas.addEventListener("mouseup",(t=>{if(this.startPort){const i=this.getCanvasCoords(t.clientX,t.clientY),o=this.portRects.find((t=>t.contains(i.x,i.y)));if(o&&(this.endPort=o.port),this.startPort&&this.endPort){const t={from:this.startPortRect.module.name,to:o.module.name,fromPort:this.startPort.portid,toPort:this.endPort.portid};this.data.connections.push(t),this.drawConnection(t),this.startPort=null,this.endPort=null,this.render()}else this.draggingModule=null}else this.draggingModule&&(this.draggingModule=null)})),this.canvas.addEventListener("wheel",(t=>{if(t.ctrlKey){t.preventDefault();const i=this.canvas.getBoundingClientRect(),o=(t.clientX-i.left)/this.dpr,s=(t.clientY-i.top)/this.dpr,e=this.view.zoom;this.view.zoom*=t.deltaY>0?.9:1.1,this.view.zoom=Math.max(.1,Math.min(this.view.zoom,5)),this.view.x-=(o-this.view.x)*(this.view.zoom/e-1),this.view.y-=(s-this.view.y)*(this.view.zoom/e-1),this.render()}}))}updatePorts(t){const{x:i,y:o,width:s,height:e}=t.position,h=t.leftArray,n=e/(h.length+2),r=6,a=i-3;h.forEach(((t,s)=>{const e=o+(s+1)*n;t.offsetX=a-i,t.offsetY=e-o}));const c=t.rightArray,d=e/(c.length+2),l=6,f=i+s-3;c.forEach(((t,s)=>{const e=o+(s+1)*d;t.offsetX=f-i,t.offsetY=e-o}));const p=t.topArray,u=s/(p.length+2),g=6,y=o-3;p.forEach(((t,s)=>{const e=i+(s+1)*u;t.offsetX=e-i,t.offsetY=y-o}));const x=t.bottomArray,m=s/(x.length+2),w=6,v=o+e-3;x.forEach(((t,s)=>{const e=i+(s+1)*m;t.offsetX=e-i,t.offsetY=v-o}))}getCanvasCoords(t,i){const o=this.canvas.getBoundingClientRect();return{x:(t-o.left-this.view.x)/this.view.zoom,y:(i-o.top-this.view.y)/this.view.zoom}}drawModule(t){const{x:i,y:o,width:s,height:e,color:h}=t.position;this.ctx.fillStyle=h,this.ctx.fillRect(i,o,s,e),this.ctx.strokeStyle="#000",this.ctx.lineWidth=2,this.ctx.strokeRect(i,o,s,e),this.ctx.shadowColor="rgba(0, 0, 0, 0.1)",this.ctx.shadowBlur=10,this.ctx.shadowOffsetX=5,this.ctx.shadowOffsetY=5,this.ctx.fillStyle="#000",this.ctx.font="12px Microsoft YaHei",this.ctx.fillText(t.name,i+10,o+20)}drawPolylineLink(t,i,o,s,e){t.beginPath(),t.moveTo(i,o),t.lineTo(i,o),t.lineTo(s,e),t.lineTo(s,e),t.strokeStyle="black",t.lineWidth=1,t.stroke()}drawPolylineLink_new(t,i,o,s,e,h,n){t.beginPath(),t.moveTo(i,o);const r=void 0;this.calculatePathPoints(i,o,s,e,h,n).forEach((i=>t.lineTo(i.x,i.y))),t.strokeStyle="black",t.lineWidth=1,t.stroke()}calculatePathPoints(t,i,o,s,e,h){const n=[{x:t,y:i}],r=20;switch(e){case"right":n.push({x:t+r,y:i});break;case"left":n.push({x:t-r,y:i});break;case"bottom":n.push({x:t,y:i+r});break;case"top":n.push({x:t,y:i-r})}const a=n[1];let c;switch(h){case"left":c={x:o-r,y:s};break;case"right":c={x:o+r,y:s};break;case"top":c={x:o,y:s-r};break;case"bottom":c={x:o,y:s+r}}return"left"===e||"right"===e?(n.push({x:a.x,y:c.y}),n.push(c)):(n.push({x:c.x,y:a.y}),n.push(c)),n.push({x:o,y:s}),n}drawConnection(t){const i=this.data.modules.find((i=>i.name===t.from)),o=this.data.modules.find((i=>i.name===t.to));if(!i||!o)return;const s=(t,i)=>t.leftArray.includes(i)?"left":t.rightArray.includes(i)?"right":t.topArray.includes(i)?"top":t.bottomArray.includes(i)?"bottom":void 0,e=i.leftArray.find((i=>i.portid===t.fromPort))||i.rightArray.find((i=>i.portid===t.fromPort))||i.topArray.find((i=>i.portid===t.fromPort))||i.bottomArray.find((i=>i.portid===t.fromPort)),h=o.leftArray.find((i=>i.portid===t.toPort))||o.rightArray.find((i=>i.portid===t.toPort))||o.topArray.find((i=>i.portid===t.toPort))||o.bottomArray.find((i=>i.portid===t.toPort));if(!e||!h)return;const n=s(i,e),r=s(o,h),a=i.position.x+e.offsetX+e.width/2,c=i.position.y+e.offsetY+e.height/2,d=o.position.x+h.offsetX+h.width/2,l=o.position.y+h.offsetY+h.height/2;this.drawPolylineLink_new(this.ctx,a,c,d,l,n,r)}drawTempConnection(t,i){const o=t.module.position.x+t.port.offsetX+t.port.width/2,s=t.module.position.y+t.port.offsetY+t.port.height/2,e=i.module.position.x+i.port.offsetX+i.port.width/2,h=i.module.position.y+i.port.offsetY+i.port.height/2;this.ctx.strokeStyle="green",this.ctx.lineWidth=2,this.ctx.beginPath(),this.ctx.moveTo(o,s),this.ctx.lineTo(e,h),this.ctx.stroke()}drawTempConnectionToMouse(t,i,o){if(!t||!t.module||!t.module.position)return;const s=t.module.position.x+t.offsetX+t.width/2,e=t.module.position.y+t.offsetY+t.height/2;this.ctx.strokeStyle="red",this.ctx.lineWidth=5,this.ctx.beginPath(),this.ctx.moveTo(s,e),this.ctx.lineTo(i,o),this.ctx.stroke()}}class Rectangle{constructor(t,i,o,s){this.x=t,this.y=i,this.width=o,this.height=s}contains(t,i){return t>=this.x&&t<=this.x+this.width&&i>=this.y&&i<=this.y+this.height}}return{Ploteeavis:Ploteeavis}},"function"==typeof define&&define.amd?define([],i):"object"==typeof module&&module.exports?module.exports=i():t.veheeavis=i()}));