CoolFace
Datasetpublic

basant307/AI_Governance_Project

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes48downloads
drawing-redraw.mjs722 linesDownload Raw Back to canvas
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 
basant307/AI_Governance_Project · CoolFace