basant307/AI_Governance_Project
048
1import * as util from '../../../util/index.mjs';2import * as math from '../../../math.mjs';3 4var CRp = {};5 6var motionBlurDelay = 100;7 8// var isFirefox = typeof InstallTrigger !== 'undefined';9 10CRp.getPixelRatio = function(){11 var context = this.data.contexts[0];12 13 if( this.forcedPixelRatio != null ){14 return this.forcedPixelRatio;15 }16 17 var containerWindow = this.cy.window();18 19 var backingStore = context.backingStorePixelRatio ||20 context.webkitBackingStorePixelRatio ||21 context.mozBackingStorePixelRatio ||22 context.msBackingStorePixelRatio ||23 context.oBackingStorePixelRatio ||24 context.backingStorePixelRatio || 1;25 26 return (containerWindow.devicePixelRatio || 1) / backingStore; // eslint-disable-line no-undef27};28 29CRp.paintCache = function( context ){30 var caches = this.paintCaches = this.paintCaches || [];31 var needToCreateCache = true;32 var cache;33 34 for( var i = 0; i < caches.length; i++ ){35 cache = caches[ i ];36 37 if( cache.context === context ){38 needToCreateCache = false;39 break;40 }41 }42 43 if( needToCreateCache ){44 cache = {45 context: context46 };47 caches.push( cache );48 }49 50 return cache;51};52 53CRp.createGradientStyleFor = function( context, shapeStyleName, ele, fill, opacity ){54 let gradientStyle;55 let usePaths = this.usePaths();56 57 let colors = ele.pstyle(shapeStyleName + '-gradient-stop-colors').value,58 positions = ele.pstyle(shapeStyleName + '-gradient-stop-positions').pfValue;59 60 if (fill === 'radial-gradient') {61 if (ele.isEdge()) {62 let start = ele.sourceEndpoint(), end = ele.targetEndpoint(), mid = ele.midpoint();63 64 let d1 = math.dist( start, mid );65 let d2 = math.dist( end, mid );66 67 gradientStyle = context.createRadialGradient(mid.x, mid.y, 0, mid.x, mid.y, Math.max(d1, d2));68 } else {69 let pos = usePaths ? {x: 0, y: 0 } : ele.position(),70 width = ele.paddedWidth(), height = ele.paddedHeight();71 gradientStyle = context.createRadialGradient(pos.x, pos.y, 0, pos.x, pos.y, Math.max(width, height));72 }73 } else {74 if (ele.isEdge()) {75 let start = ele.sourceEndpoint(), end = ele.targetEndpoint();76 77 gradientStyle = context.createLinearGradient(start.x, start.y, end.x, end.y);78 } else {79 let pos = usePaths ? { x: 0, y: 0 } : ele.position(),80 width = ele.paddedWidth(), height = ele.paddedHeight(),81 halfWidth = width / 2, halfHeight = height / 2;82 let direction = ele.pstyle('background-gradient-direction').value;83 84 switch (direction) {85 case 'to-bottom':86 gradientStyle = context.createLinearGradient(pos.x, pos.y - halfHeight, pos.x, pos.y + halfHeight);87 break;88 case 'to-top':89 gradientStyle = context.createLinearGradient(pos.x, pos.y + halfHeight, pos.x, pos.y - halfHeight);90 break;91 case 'to-left':92 gradientStyle = context.createLinearGradient(pos.x + halfWidth, pos.y, pos.x - halfWidth, pos.y);93 break;94 case 'to-right':95 gradientStyle = context.createLinearGradient(pos.x - halfWidth, pos.y, pos.x + halfWidth, pos.y);96 break;97 case 'to-bottom-right':98 case 'to-right-bottom':99 gradientStyle = context.createLinearGradient(pos.x - halfWidth, pos.y - halfHeight, pos.x + halfWidth, pos.y + halfHeight);100 break;101 case 'to-top-right':102 case 'to-right-top':103 gradientStyle = context.createLinearGradient(pos.x - halfWidth, pos.y + halfHeight, pos.x + halfWidth, pos.y - halfHeight);104 break;105 case 'to-bottom-left':106 case 'to-left-bottom':107 gradientStyle = context.createLinearGradient(pos.x + halfWidth, pos.y - halfHeight, pos.x - halfWidth, pos.y + halfHeight);108 break;109 case 'to-top-left':110 case 'to-left-top':111 gradientStyle = context.createLinearGradient(pos.x + halfWidth, pos.y + halfHeight, pos.x - halfWidth, pos.y - halfHeight);112 break;113 }114 }115 }116 if (!gradientStyle) return null; // invalid gradient style117 118 let hasPositions = positions.length === colors.length;119 120 let length = colors.length;121 for (let i = 0; i < length; i++) {122 gradientStyle.addColorStop(hasPositions ? positions[i] : i / (length - 1), 'rgba(' + colors[i][0] + ',' + colors[i][1] + ',' + colors[i][2] + ',' + opacity + ')');123 }124 125 return gradientStyle;126};127 128CRp.gradientFillStyle = function( context, ele, fill, opacity ){129 const gradientStyle = this.createGradientStyleFor(context, 'background', ele, fill, opacity);130 if (!gradientStyle) return null; // error131 context.fillStyle = gradientStyle;132};133 134CRp.colorFillStyle = function( context, r, g, b, a ){135 context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';136 // turn off for now, seems context does its own caching137 138 // var cache = this.paintCache(context);139 140 // var fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';141 142 // if( cache.fillStyle !== fillStyle ){143 // context.fillStyle = cache.fillStyle = fillStyle;144 // }145};146 147CRp.eleFillStyle = function( context, ele, opacity ){148 let backgroundFill = ele.pstyle('background-fill').value;149 150 if (backgroundFill === 'linear-gradient' || backgroundFill === 'radial-gradient') {151 this.gradientFillStyle(context, ele, backgroundFill, opacity);152 } else {153 let backgroundColor = ele.pstyle('background-color').value;154 this.colorFillStyle( context, backgroundColor[0], backgroundColor[1], backgroundColor[2], opacity );155 }156};157 158CRp.gradientStrokeStyle = function( context, ele, fill, opacity ){159 const gradientStyle = this.createGradientStyleFor(context, 'line', ele, fill ,opacity);160 if (!gradientStyle) return null; // error161 context.strokeStyle = gradientStyle;162};163 164CRp.colorStrokeStyle = function( context, r, g, b, a ){165 context.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';166 // turn off for now, seems context does its own caching167 168 // var cache = this.paintCache(context);169 170 // var strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';171 172 // if( cache.strokeStyle !== strokeStyle ){173 // context.strokeStyle = cache.strokeStyle = strokeStyle;174 // }175};176 177CRp.eleStrokeStyle = function( context, ele, opacity ){178 let lineFill = ele.pstyle('line-fill').value;179 180 if (lineFill === 'linear-gradient' || lineFill === 'radial-gradient') {181 this.gradientStrokeStyle(context, ele, lineFill, opacity);182 } else {183 let lineColor = ele.pstyle('line-color').value;184 this.colorStrokeStyle( context, lineColor[0], lineColor[1], lineColor[2], opacity );185 }186};187 188// Resize canvas189CRp.matchCanvasSize = function( container ){190 var r = this;191 var data = r.data;192 var bb = r.findContainerClientCoords();193 var width = bb[2];194 var height = bb[3];195 var pixelRatio = r.getPixelRatio();196 var mbPxRatio = r.motionBlurPxRatio;197 198 if(199 container === r.data.bufferCanvases[ r.MOTIONBLUR_BUFFER_NODE ] ||200 container === r.data.bufferCanvases[ r.MOTIONBLUR_BUFFER_DRAG ]201 ){202 pixelRatio = mbPxRatio;203 }204 205 var canvasWidth = width * pixelRatio;206 var canvasHeight = height * pixelRatio;207 var canvas;208 209 if( canvasWidth === r.canvasWidth && canvasHeight === r.canvasHeight ){210 return; // save cycles if same211 }212 213 r.fontCaches = null; // resizing resets the style214 215 var canvasContainer = data.canvasContainer;216 canvasContainer.style.width = width + 'px';217 canvasContainer.style.height = height + 'px';218 219 for( var i = 0; i < r.CANVAS_LAYERS; i++ ){220 canvas = data.canvases[ i ];221 222 canvas.width = canvasWidth;223 canvas.height = canvasHeight;224 225 canvas.style.width = width + 'px';226 canvas.style.height = height + 'px';227 }228 229 for( var i = 0; i < r.BUFFER_COUNT; i++ ){230 canvas = data.bufferCanvases[ i ];231 232 canvas.width = canvasWidth;233 canvas.height = canvasHeight;234 235 canvas.style.width = width + 'px';236 canvas.style.height = height + 'px';237 }238 239 r.textureMult = 1;240 if( pixelRatio <= 1 ){241 canvas = data.bufferCanvases[ r.TEXTURE_BUFFER ];242 243 r.textureMult = 2;244 canvas.width = canvasWidth * r.textureMult;245 canvas.height = canvasHeight * r.textureMult;246 }247 248 r.canvasWidth = canvasWidth;249 r.canvasHeight = canvasHeight;250 r.pixelRatio = pixelRatio;251};252 253CRp.renderTo = function( cxt, zoom, pan, pxRatio ){254 this.render( {255 forcedContext: cxt,256 forcedZoom: zoom,257 forcedPan: pan,258 drawAllLayers: true,259 forcedPxRatio: pxRatio260 } );261};262 263CRp.clearCanvas = function(){264 var r = this;265 var data = r.data;266 function clear(context) {267 context.clearRect(0, 0, r.canvasWidth, r.canvasHeight);268 }269 clear(data.contexts[ r.NODE ]);270 clear(data.contexts[ r.DRAG ]);271};272 273 274CRp.render = function( options ){275 var r = this;276 options = options || util.staticEmptyObject();277 278 var cy = r.cy; 279 280 var forcedContext = options.forcedContext;281 var drawAllLayers = options.drawAllLayers;282 var drawOnlyNodeLayer = options.drawOnlyNodeLayer;283 var forcedZoom = options.forcedZoom;284 var forcedPan = options.forcedPan;285 var pixelRatio = options.forcedPxRatio === undefined ? this.getPixelRatio() : options.forcedPxRatio;286 var data = r.data;287 var needDraw = data.canvasNeedsRedraw;288 var textureDraw = r.textureOnViewport && !forcedContext && (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming);289 var motionBlur = options.motionBlur !== undefined ? options.motionBlur : r.motionBlur;290 var mbPxRatio = r.motionBlurPxRatio;291 var hasCompoundNodes = cy.hasCompoundNodes();292 var inNodeDragGesture = r.hoverData.draggingEles;293 var inBoxSelection = r.hoverData.selecting || r.touchData.selecting ? true : false;294 motionBlur = motionBlur && !forcedContext && r.motionBlurEnabled && !inBoxSelection;295 var motionBlurFadeEffect = motionBlur;296 297 if( !forcedContext ){298 if( r.prevPxRatio !== pixelRatio ){299 r.invalidateContainerClientCoordsCache();300 r.matchCanvasSize( r.container );301 302 r.redrawHint('eles', true);303 r.redrawHint('drag', true);304 }305 306 r.prevPxRatio = pixelRatio;307 }308 309 if( !forcedContext && r.motionBlurTimeout ){310 clearTimeout( r.motionBlurTimeout );311 }312 313 if( motionBlur ){314 if( r.mbFrames == null ){315 r.mbFrames = 0;316 }317 318 r.mbFrames++;319 320 if( r.mbFrames < 3 ){ // need several frames before even high quality motionblur321 motionBlurFadeEffect = false;322 }323 324 // go to lower quality blurry frames when several m/b frames have been rendered (avoids flashing)325 if( r.mbFrames > r.minMbLowQualFrames ){326 //r.fullQualityMb = false;327 r.motionBlurPxRatio = r.mbPxRBlurry;328 }329 }330 331 if( r.clearingMotionBlur ){332 r.motionBlurPxRatio = 1;333 }334 335 // b/c drawToContext() may be async w.r.t. redraw(), keep track of last texture frame336 // because a rogue async texture frame would clear needDraw337 if( r.textureDrawLastFrame && !textureDraw ){338 needDraw[ r.NODE ] = true;339 needDraw[ r.SELECT_BOX ] = true;340 }341 342 var style = cy.style();343 344 var zoom = cy.zoom();345 var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom;346 var pan = cy.pan();347 var effectivePan = {348 x: pan.x,349 y: pan.y350 };351 352 var vp = {353 zoom: zoom,354 pan: {355 x: pan.x,356 y: pan.y357 }358 };359 var prevVp = r.prevViewport;360 var viewportIsDiff = prevVp === undefined || vp.zoom !== prevVp.zoom || vp.pan.x !== prevVp.pan.x || vp.pan.y !== prevVp.pan.y;361 362 // we want the low quality motionblur only when the viewport is being manipulated etc (where it's not noticed)363 if( !viewportIsDiff && !(inNodeDragGesture && !hasCompoundNodes) ){364 r.motionBlurPxRatio = 1;365 }366 367 if( forcedPan ){368 effectivePan = forcedPan;369 }370 371 // apply pixel ratio372 373 effectiveZoom *= pixelRatio;374 effectivePan.x *= pixelRatio;375 effectivePan.y *= pixelRatio;376 377 var eles = r.getCachedZSortedEles();378 379 function mbclear( context, x, y, w, h ){380 var gco = context.globalCompositeOperation;381 382 context.globalCompositeOperation = 'destination-out';383 r.colorFillStyle( context, 255, 255, 255, r.motionBlurTransparency );384 context.fillRect( x, y, w, h );385 386 context.globalCompositeOperation = gco;387 }388 389 function setContextTransform( context, clear ){390 var ePan, eZoom, w, h;391 392 if( !r.clearingMotionBlur && (context === data.bufferContexts[ r.MOTIONBLUR_BUFFER_NODE ] || context === data.bufferContexts[ r.MOTIONBLUR_BUFFER_DRAG ]) ){393 ePan = {394 x: pan.x * mbPxRatio,395 y: pan.y * mbPxRatio396 };397 398 eZoom = zoom * mbPxRatio;399 400 w = r.canvasWidth * mbPxRatio;401 h = r.canvasHeight * mbPxRatio;402 } else {403 ePan = effectivePan;404 eZoom = effectiveZoom;405 406 w = r.canvasWidth;407 h = r.canvasHeight;408 }409 410 context.setTransform( 1, 0, 0, 1, 0, 0 );411 412 if( clear === 'motionBlur' ){413 mbclear( context, 0, 0, w, h );414 } else if( !forcedContext && (clear === undefined || clear) ){415 context.clearRect( 0, 0, w, h );416 }417 418 if( !drawAllLayers ){419 context.translate( ePan.x, ePan.y );420 context.scale( eZoom, eZoom );421 }422 if( forcedPan ){423 context.translate( forcedPan.x, forcedPan.y );424 }425 if( forcedZoom ){426 context.scale( forcedZoom, forcedZoom );427 }428 }429 430 if( !textureDraw ){431 r.textureDrawLastFrame = false;432 }433 434 if( textureDraw ){435 r.textureDrawLastFrame = true;436 437 if( !r.textureCache ){438 r.textureCache = {};439 440 r.textureCache.bb = cy.mutableElements().boundingBox();441 442 r.textureCache.texture = r.data.bufferCanvases[ r.TEXTURE_BUFFER ];443 444 var cxt = r.data.bufferContexts[ r.TEXTURE_BUFFER ];445 446 cxt.setTransform( 1, 0, 0, 1, 0, 0 );447 cxt.clearRect( 0, 0, r.canvasWidth * r.textureMult, r.canvasHeight * r.textureMult );448 449 r.render( {450 forcedContext: cxt,451 drawOnlyNodeLayer: true,452 forcedPxRatio: pixelRatio * r.textureMult453 } );454 455 var vp = r.textureCache.viewport = {456 zoom: cy.zoom(),457 pan: cy.pan(),458 width: r.canvasWidth,459 height: r.canvasHeight460 };461 462 vp.mpan = {463 x: (0 - vp.pan.x) / vp.zoom,464 y: (0 - vp.pan.y) / vp.zoom465 };466 }467 468 needDraw[ r.DRAG ] = false;469 needDraw[ r.NODE ] = false;470 471 var context = data.contexts[ r.NODE ];472 473 var texture = r.textureCache.texture;474 var vp = r.textureCache.viewport;475 476 context.setTransform( 1, 0, 0, 1, 0, 0 );477 478 if( motionBlur ){479 mbclear( context, 0, 0, vp.width, vp.height );480 } else {481 context.clearRect( 0, 0, vp.width, vp.height );482 }483 484 var outsideBgColor = style.core( 'outside-texture-bg-color' ).value;485 var outsideBgOpacity = style.core( 'outside-texture-bg-opacity' ).value;486 r.colorFillStyle( context, outsideBgColor[0], outsideBgColor[1], outsideBgColor[2], outsideBgOpacity );487 context.fillRect( 0, 0, vp.width, vp.height );488 489 var zoom = cy.zoom();490 491 setContextTransform( context, false );492 493 context.clearRect( vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio );494 context.drawImage( texture, vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio );495 496 } else if( r.textureOnViewport && !forcedContext ){ // clear the cache since we don't need it497 r.textureCache = null;498 }499 500 var extent = cy.extent();501 var vpManip = (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming || r.hoverData.draggingEles || r.cy.animated());502 var hideEdges = r.hideEdgesOnViewport && vpManip;503 504 var needMbClear = [];505 506 needMbClear[ r.NODE ] = !needDraw[ r.NODE ] && motionBlur && !r.clearedForMotionBlur[ r.NODE ] || r.clearingMotionBlur;507 if( needMbClear[ r.NODE ] ){ r.clearedForMotionBlur[ r.NODE ] = true; }508 509 needMbClear[ r.DRAG ] = !needDraw[ r.DRAG ] && motionBlur && !r.clearedForMotionBlur[ r.DRAG ] || r.clearingMotionBlur;510 if( needMbClear[ r.DRAG ] ){ r.clearedForMotionBlur[ r.DRAG ] = true; }511 512 if( needDraw[ r.NODE ] || drawAllLayers || drawOnlyNodeLayer || needMbClear[ r.NODE ] ){513 var useBuffer = motionBlur && !needMbClear[ r.NODE ] && mbPxRatio !== 1;514 var context = forcedContext || ( useBuffer ? r.data.bufferContexts[ r.MOTIONBLUR_BUFFER_NODE ] : data.contexts[ r.NODE ] );515 var clear = motionBlur && !useBuffer ? 'motionBlur' : undefined;516 517 setContextTransform( context, clear );518 519 if( hideEdges ){520 r.drawCachedNodes( context, eles.nondrag, pixelRatio, extent );521 } else {522 r.drawLayeredElements( context, eles.nondrag, pixelRatio, extent );523 }524 525 if( r.debug ){526 r.drawDebugPoints( context, eles.nondrag );527 }528 529 if( !drawAllLayers && !motionBlur ){530 needDraw[ r.NODE ] = false;531 }532 }533 534 if( !drawOnlyNodeLayer && (needDraw[ r.DRAG ] || drawAllLayers || needMbClear[ r.DRAG ]) ){535 var useBuffer = motionBlur && !needMbClear[ r.DRAG ] && mbPxRatio !== 1;536 var context = forcedContext || ( useBuffer ? r.data.bufferContexts[ r.MOTIONBLUR_BUFFER_DRAG ] : data.contexts[ r.DRAG ] );537 538 setContextTransform( context, motionBlur && !useBuffer ? 'motionBlur' : undefined );539 540 if( hideEdges ){541 r.drawCachedNodes( context, eles.drag, pixelRatio, extent );542 } else {543 r.drawCachedElements( context, eles.drag, pixelRatio, extent );544 }545 546 if( r.debug ){547 r.drawDebugPoints( context, eles.drag );548 }549 550 if( !drawAllLayers && !motionBlur ){551 needDraw[ r.DRAG ] = false;552 }553 }554 555 this.drawSelectionRectangle(options, setContextTransform);556 557 // motionblur: blit rendered blurry frames558 if( motionBlur && mbPxRatio !== 1 ){559 var cxtNode = data.contexts[ r.NODE ];560 var txtNode = r.data.bufferCanvases[ r.MOTIONBLUR_BUFFER_NODE ];561 562 var cxtDrag = data.contexts[ r.DRAG ];563 var txtDrag = r.data.bufferCanvases[ r.MOTIONBLUR_BUFFER_DRAG ];564 565 var drawMotionBlur = function( cxt, txt, needClear ){566 cxt.setTransform( 1, 0, 0, 1, 0, 0 );567 568 if( needClear || !motionBlurFadeEffect ){569 cxt.clearRect( 0, 0, r.canvasWidth, r.canvasHeight );570 } else {571 mbclear( cxt, 0, 0, r.canvasWidth, r.canvasHeight );572 }573 574 var pxr = mbPxRatio;575 576 cxt.drawImage(577 txt, // img578 0, 0, // sx, sy579 r.canvasWidth * pxr, r.canvasHeight * pxr, // sw, sh580 0, 0, // x, y581 r.canvasWidth, r.canvasHeight // w, h582 );583 };584 585 if( needDraw[ r.NODE ] || needMbClear[ r.NODE ] ){586 drawMotionBlur( cxtNode, txtNode, needMbClear[ r.NODE ] );587 needDraw[ r.NODE ] = false;588 }589 590 if( needDraw[ r.DRAG ] || needMbClear[ r.DRAG ] ){591 drawMotionBlur( cxtDrag, txtDrag, needMbClear[ r.DRAG ] );592 needDraw[ r.DRAG ] = false;593 }594 }595 596 r.prevViewport = vp;597 598 if( r.clearingMotionBlur ){599 r.clearingMotionBlur = false;600 r.motionBlurCleared = true;601 r.motionBlur = true;602 }603 604 if( motionBlur ){605 r.motionBlurTimeout = setTimeout( function(){606 r.motionBlurTimeout = null;607 608 r.clearedForMotionBlur[ r.NODE ] = false;609 r.clearedForMotionBlur[ r.DRAG ] = false;610 r.motionBlur = false;611 r.clearingMotionBlur = !textureDraw;612 r.mbFrames = 0;613 614 needDraw[ r.NODE ] = true;615 needDraw[ r.DRAG ] = true;616 617 r.redraw();618 }, motionBlurDelay );619 }620 621 if( !forcedContext ){622 cy.emit('render');623 }624 625};626 627let fpsHeight;628 629CRp.drawSelectionRectangle = function(options, setContextTransform) {630 const r = this;631 const cy = r.cy; 632 const data = r.data;633 const style = cy.style();634 635 const drawOnlyNodeLayer = options.drawOnlyNodeLayer;636 const drawAllLayers = options.drawAllLayers;637 const needDraw = data.canvasNeedsRedraw;638 const forcedContext = options.forcedContext;639 640 if( r.showFps || (!drawOnlyNodeLayer && (needDraw[ r.SELECT_BOX ] && !drawAllLayers)) ){641 var context = forcedContext || data.contexts[ r.SELECT_BOX ];642 643 setContextTransform( context );644 645 if( r.selection[4] == 1 && ( r.hoverData.selecting || r.touchData.selecting ) ){646 var zoom = r.cy.zoom();647 var borderWidth = style.core( 'selection-box-border-width' ).value / zoom;648 649 context.lineWidth = borderWidth;650 context.fillStyle = 'rgba('651 + style.core( 'selection-box-color' ).value[0] + ','652 + style.core( 'selection-box-color' ).value[1] + ','653 + style.core( 'selection-box-color' ).value[2] + ','654 + style.core( 'selection-box-opacity' ).value + ')';655 656 context.fillRect(657 r.selection[0],658 r.selection[1],659 r.selection[2] - r.selection[0],660 r.selection[3] - r.selection[1] );661 662 if( borderWidth > 0 ){663 context.strokeStyle = 'rgba('664 + style.core( 'selection-box-border-color' ).value[0] + ','665 + style.core( 'selection-box-border-color' ).value[1] + ','666 + style.core( 'selection-box-border-color' ).value[2] + ','667 + style.core( 'selection-box-opacity' ).value + ')';668 669 context.strokeRect(670 r.selection[0],671 r.selection[1],672 r.selection[2] - r.selection[0],673 r.selection[3] - r.selection[1] );674 }675 }676 677 if( data.bgActivePosistion && !r.hoverData.selecting ){678 var zoom = r.cy.zoom();679 var pos = data.bgActivePosistion;680 681 context.fillStyle = 'rgba('682 + style.core( 'active-bg-color' ).value[0] + ','683 + style.core( 'active-bg-color' ).value[1] + ','684 + style.core( 'active-bg-color' ).value[2] + ','685 + style.core( 'active-bg-opacity' ).value + ')';686 687 context.beginPath();688 context.arc( pos.x, pos.y, style.core( 'active-bg-size' ).pfValue / zoom, 0, 2 * Math.PI );689 context.fill();690 }691 692 var timeToRender = r.lastRedrawTime;693 if( r.showFps && timeToRender ){694 timeToRender = Math.round( timeToRender );695 var fps = Math.round( 1000 / timeToRender );696 const text = '1 frame = ' + timeToRender + ' ms = ' + fps + ' fps';697 698 context.setTransform( 1, 0, 0, 1, 0, 0 );699 700 context.fillStyle = 'rgba(255, 0, 0, 0.75)';701 context.strokeStyle = 'rgba(255, 0, 0, 0.75)';702 // context.lineWidth = 1;703 context.font = '30px Arial';704 if(!fpsHeight) {705 const dims = context.measureText(text);706 fpsHeight = dims.actualBoundingBoxAscent;707 }708 context.fillText( text, 0, fpsHeight );709 710 var maxFps = 60;711 context.strokeRect( 0, fpsHeight + 10, 250, 20 );712 context.fillRect( 0, fpsHeight + 10, 250 * Math.min( fps / maxFps, 1 ), 20 );713 }714 715 if( !drawAllLayers ){716 needDraw[ r.SELECT_BOX ] = false;717 }718 }719};720 721export default CRp;722 