1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import {Graph} from "./Graph.js"; 17import {Rect} from "./Rect.js"; 18import {ns2s, TimerShaftElement} from "../TimerShaftElement.js"; 19import {ColorUtils} from "../base/ColorUtils.js"; 20import {CpuStruct} from "../../../bean/CpuStruct.js"; 21 22const markPadding = 5; 23 24export class Mark extends Graph { 25 name: string | undefined 26 inspectionFrame: Rect 27 private _isHover: boolean = false 28 29 constructor(canvas: HTMLCanvasElement | undefined | null, name: string, c: CanvasRenderingContext2D, frame: Rect) { 30 super(canvas, c, frame); 31 this.name = name; 32 this.inspectionFrame = new Rect(frame.x - markPadding, frame.y, frame.width + markPadding * 2, frame.height) 33 } 34 35 get isHover(): boolean { 36 return this._isHover; 37 } 38 39 set isHover(value: boolean) { 40 this._isHover = value; 41 if (value) { 42 document.body.style.cursor = 'ew-resize' 43 } else { 44 document.body.style.cursor = 'default' 45 } 46 } 47 48 draw(): void { 49 this.c.beginPath(); 50 this.c.lineWidth = 7 51 this.c.strokeStyle = '#999999' 52 this.c.moveTo(this.frame.x, this.frame.y); 53 this.c.lineTo(this.frame.x, this.frame.y + this.frame.height / 3) 54 this.c.stroke(); 55 this.c.lineWidth = 1 56 this.c.strokeStyle = '#999999' 57 this.c.moveTo(this.frame.x, this.frame.y); 58 this.c.lineTo(this.frame.x, this.frame.y + this.frame.height) 59 this.c.stroke(); 60 this.c.closePath(); 61 } 62} 63 64export interface TimeRange { 65 slicesTime: { 66 color: string | null | undefined; 67 startTime: number | null | undefined; 68 endTime: number | null | undefined; 69 }; 70 scale: number; 71 totalNS: number 72 startX: number 73 endX: number 74 startNS: number 75 endNS: number 76 xs: Array<number> 77 refresh: boolean 78 xsTxt: Array<string> 79} 80 81export class RangeRuler extends Graph { 82 public rangeRect: Rect 83 public markA: Mark 84 public markB: Mark 85 public range: TimeRange; 86 private pressedKeys: Array<string> = []; 87 mouseDownOffsetX = 0 88 mouseDownMovingMarkX = 0 89 movingMark: Mark | undefined | null; 90 isMouseDown: boolean = false; 91 isMovingRange: boolean = false; 92 isNewRange: boolean = false; 93 markAX: number = 0; 94 markBX: number = 0; 95 isPress: boolean = false 96 pressFrameIdW: number = -1 97 pressFrameIdS: number = -1 98 pressFrameIdA: number = -1 99 pressFrameIdD: number = -1 100 upFrameIdW: number = -1 101 upFrameIdS: number = -1 102 upFrameIdA: number = -1 103 upFrameIdD: number = -1 104 currentDuration: number = 0 105 cacheInterval: { interval: number, value: number, flag: boolean } = { 106 interval: 200, 107 value: 0, 108 flag: false 109 } 110 centerXPercentage: number = 0; 111 animaStartTime: number | undefined 112 p: number = 1000; 113 private readonly notifyHandler: (r: TimeRange) => void; 114 private scale: number = 0; 115 private delayTimer: any = null 116 //缩放级别 117 private scales: Array<number> = [50, 100, 200, 500, 1_000, 2_000, 5_000, 10_000, 20_000, 50_000, 100_000, 200_000, 500_000, 118 1_000_000, 2_000_000, 5_000_000, 10_000_000, 20_000_000, 50_000_000, 100_000_000, 200_000_000, 500_000_000, 119 1_000_000_000, 2_000_000_000, 5_000_000_000, 10_000_000_000, 20_000_000_000, 50_000_000_000, 120 100_000_000_000, 200_000_000_000, 500_000_000_000]; 121 private _cpuUsage: Array<{ cpu: number, ro: number, rate: number }> = [] 122 123 constructor(timerShaftEL: TimerShaftElement, frame: Rect, range: TimeRange, notifyHandler: (r: TimeRange) => void) { 124 super(timerShaftEL.canvas, timerShaftEL.ctx!, frame) 125 this.range = range; 126 this.notifyHandler = notifyHandler; 127 this.markA = new Mark(timerShaftEL.canvas, 'A', timerShaftEL.ctx!, new Rect(range.startX, frame.y, 1, frame.height)) 128 this.markB = new Mark(timerShaftEL.canvas, 'B', timerShaftEL.ctx!, new Rect(range.endX, frame.y, 1, frame.height)) 129 this.rangeRect = new Rect(range.startX, frame.y, range.endX - range.startX, frame.height) 130 } 131 132 set cpuUsage(value: Array<{ cpu: number, ro: number, rate: number }>) { 133 this._cpuUsage = value 134 this.draw(); 135 } 136 137 drawCpuUsage() { 138 let maxNum = Math.round(this._cpuUsage.length / 100) 139 let miniHeight = Math.round(this.frame.height / CpuStruct.cpuCount);//每格高度 140 let miniWidth = Math.ceil(this.frame.width / 100);//每格宽度 141 for (let i = 0; i < this._cpuUsage.length; i++) { 142 let it = this._cpuUsage[i] 143 this.c.fillStyle = ColorUtils.MD_PALETTE[it.cpu] 144 this.c.globalAlpha = it.rate 145 this.c.fillRect(this.frame.x + miniWidth * it.ro, this.frame.y + it.cpu * miniHeight, miniWidth, miniHeight) 146 } 147 } 148 149 draw(discardNotify: boolean = false): void { 150 this.c.clearRect(this.frame.x - markPadding, this.frame.y, this.frame.width + markPadding * 2, this.frame.height) 151 this.c.beginPath(); 152 if (this._cpuUsage.length > 0) { 153 this.drawCpuUsage() 154 this.c.globalAlpha = 0; 155 } else { 156 this.c.globalAlpha = 1; 157 } 158 //绘制选中区域 159 this.c.fillStyle = window.getComputedStyle(this.canvas!, null).getPropertyValue("background-color");//"#ffffff" 160 this.rangeRect.x = this.markA.frame.x < this.markB.frame.x ? this.markA.frame.x : this.markB.frame.x 161 this.rangeRect.width = Math.abs(this.markB.frame.x - this.markA.frame.x) 162 this.c.fillRect(this.rangeRect.x, this.rangeRect.y, this.rangeRect.width, this.rangeRect.height) 163 this.c.globalAlpha = 1; 164 this.c.globalAlpha = .5; 165 this.c.fillStyle = "#999999" 166 this.c.fillRect(this.frame.x, this.frame.y, this.rangeRect.x, this.rangeRect.height) 167 this.c.fillRect(this.rangeRect.x + this.rangeRect.width, this.frame.y, this.frame.width - this.rangeRect.width, this.rangeRect.height) 168 this.c.globalAlpha = 1; 169 this.c.closePath(); 170 this.markA.draw(); 171 this.markB.draw(); 172 if (this.notifyHandler) { 173 this.range.startX = this.rangeRect.x 174 this.range.endX = this.rangeRect.x + this.rangeRect.width 175 this.range.startNS = this.range.startX * this.range.totalNS / (this.canvas?.clientWidth || 0) 176 this.range.endNS = this.range.endX * this.range.totalNS / (this.canvas?.clientWidth || 0) 177 let l20 = (this.range.endNS - this.range.startNS) / 20; 178 let min = 0; 179 let max = 0; 180 let weight = 0; 181 for (let index = 0; index < this.scales.length; index++) { 182 if (this.scales[index] > l20) { 183 if (index > 0) { 184 min = this.scales[index - 1]; 185 } else { 186 min = 0; 187 } 188 max = this.scales[index]; 189 weight = (l20 - min) * 1.0 / (max - min); 190 if (weight > 0.243) { 191 this.scale = max; 192 } else { 193 this.scale = min; 194 } 195 break; 196 } 197 } 198 if (this.scale == 0) { 199 this.scale = this.scales[0]; 200 } 201 let tmpNs = 0; 202 let yu = this.range.startNS % this.scale; 203 let realW = (this.scale * this.frame.width) / (this.range.endNS - this.range.startNS); 204 let startX = 0; 205 if (this.range.xs) { 206 this.range.xs.length = 0 207 } else { 208 this.range.xs = [] 209 } 210 if (this.range.xsTxt) { 211 this.range.xsTxt.length = 0 212 } else { 213 this.range.xsTxt = [] 214 } 215 this.range.scale = this.scale; 216 if (yu != 0) { 217 let firstNodeWidth = ((this.scale - yu) / this.scale * realW); 218 startX += firstNodeWidth; 219 tmpNs += yu; 220 this.range.xs.push(startX) 221 this.range.xsTxt.push(ns2s(tmpNs)) 222 } 223 while (tmpNs < this.range.endNS - this.range.startNS) { 224 startX += realW; 225 tmpNs += this.scale; 226 this.range.xs.push(startX) 227 this.range.xsTxt.push(ns2s(tmpNs)) 228 } 229 230 if (!discardNotify) { 231 this.notifyHandler(this.range) 232 } 233 } 234 } 235 236 mouseDown(ev: MouseEvent) { 237 let x = ev.offsetX - (this.canvas?.offsetLeft || 0) 238 let y = ev.offsetY - (this.canvas?.offsetTop || 0) 239 this.isMouseDown = true; 240 this.mouseDownOffsetX = x; 241 if (this.markA.isHover) { 242 this.movingMark = this.markA; 243 this.mouseDownMovingMarkX = this.movingMark.frame.x || 0 244 } else if (this.markB.isHover) { 245 this.movingMark = this.markB; 246 this.mouseDownMovingMarkX = this.movingMark.frame.x || 0 247 } else { 248 this.movingMark = null; 249 } 250 if (this.rangeRect.containsWithPadding(x, y, 5, 0)) { 251 this.isMovingRange = true; 252 this.markAX = this.markA.frame.x; 253 this.markBX = this.markB.frame.x; 254 document.body.style.cursor = "move" 255 } else if (this.frame.containsWithMargin(x, y, 20, 0, 0, 0) && !this.rangeRect.containsWithMargin(x, y, 0, markPadding, 0, markPadding)) { 256 this.isNewRange = true; 257 } 258 } 259 260 mouseUp(ev: MouseEvent) { 261 this.isMouseDown = false; 262 this.isMovingRange = false; 263 this.isNewRange = false; 264 this.movingMark = null; 265 } 266 267 mouseMove(ev: MouseEvent) { 268 this.range.refresh = false; 269 let x = ev.offsetX - (this.canvas?.offsetLeft || 0); 270 let y = ev.offsetY - (this.canvas?.offsetTop || 0) 271 this.centerXPercentage = x / (this.canvas?.clientWidth || 0) 272 if (this.centerXPercentage <= 0) { 273 this.centerXPercentage = 0 274 } else if (this.centerXPercentage >= 1) { 275 this.centerXPercentage = 1 276 } 277 let maxX = this.canvas?.clientWidth || 0 278 if (this.markA.inspectionFrame.contains(x, y)) { 279 this.markA.isHover = true 280 } else if (this.markB.inspectionFrame.contains(x, y)) { 281 this.markB.isHover = true; 282 } else { 283 this.markA.isHover = false; 284 this.markB.isHover = false; 285 } 286 if (this.movingMark) { 287 let result = x - this.mouseDownOffsetX + this.mouseDownMovingMarkX; 288 if (result >= 0 && result <= maxX) { 289 this.movingMark.frame.x = result 290 } else if (result < 0) { 291 this.movingMark.frame.x = 0 292 } else { 293 this.movingMark.frame.x = maxX 294 } 295 this.movingMark.inspectionFrame.x = this.movingMark.frame.x - markPadding 296 this.recordMovingS() 297 requestAnimationFrame(() => { 298 this.draw() 299 this.range.refresh = false; 300 this.delayDraw() 301 }); 302 } else if (this.rangeRect.containsWithPadding(x, y, markPadding, 0)) { 303 document.body.style.cursor = "move" 304 } else if (this.frame.containsWithMargin(x, y, 20, 0, 0, 0) && !this.rangeRect.containsWithMargin(x, y, 0, markPadding, 0, markPadding)) { 305 document.body.style.cursor = "crosshair"; 306 } 307 if (this.isMovingRange && this.isMouseDown) { 308 let result = x - this.mouseDownOffsetX; 309 let mA = result + this.markAX 310 let mB = result + this.markBX 311 if (mA >= 0 && mA <= maxX) { 312 this.markA.frame.x = mA 313 } else if (mA < 0) { 314 this.markA.frame.x = 0 315 } else { 316 this.markA.frame.x = maxX 317 } 318 this.markA.inspectionFrame.x = this.markA.frame.x - markPadding 319 if (mB >= 0 && mB <= maxX) { 320 this.markB.frame.x = mB; 321 } else if (mB < 0) { 322 this.markB.frame.x = 0 323 } else { 324 this.markB.frame.x = maxX 325 } 326 this.markB.inspectionFrame.x = this.markB.frame.x - markPadding 327 this.recordMovingS() 328 requestAnimationFrame(() => { 329 this.draw() 330 this.range.refresh = false; 331 this.delayDraw() 332 }); 333 } else if (this.isNewRange) { 334 this.markA.frame.x = this.mouseDownOffsetX; 335 this.markA.inspectionFrame.x = this.mouseDownOffsetX - markPadding; 336 if (x >= 0 && x <= maxX) { 337 this.markB.frame.x = x; 338 } else if (x < 0) { 339 this.markB.frame.x = 0; 340 } else { 341 this.markB.frame.x = maxX; 342 } 343 this.markB.inspectionFrame.x = this.markB.frame.x - markPadding; 344 this.recordMovingS() 345 requestAnimationFrame(() => { 346 this.draw() 347 this.range.refresh = false; 348 this.delayDraw() 349 }); 350 } 351 } 352 353 recordMovingS() { 354 if (this.animaStartTime == undefined) { 355 let dat = new Date(); 356 dat.setTime(dat.getTime() - 400); 357 this.animaStartTime = dat.getTime(); 358 } 359 this.currentDuration = (new Date().getTime() - this.animaStartTime); 360 if (Math.trunc(this.currentDuration / this.cacheInterval.interval) != this.cacheInterval.value) { 361 this.cacheInterval.flag = true; 362 this.cacheInterval.value = Math.trunc(this.currentDuration / this.cacheInterval.interval) 363 } else { 364 this.cacheInterval.flag = false; 365 } 366 this.range.refresh = this.cacheInterval.flag; 367 } 368 369 delayDraw() { 370 if (this.delayTimer) { 371 clearTimeout(this.delayTimer) 372 } 373 this.delayTimer = setTimeout(() => { 374 this.range.refresh = true; 375 this.draw() 376 this.range.refresh = false; 377 this.animaStartTime = undefined 378 }, this.cacheInterval.interval + 50) 379 } 380 381 mouseOut(ev: MouseEvent) { 382 this.movingMark = null; 383 } 384 385 fillX() { 386 if (this.range.startNS < 0) this.range.startNS = 0; 387 if (this.range.endNS < 0) this.range.endNS = 0; 388 if (this.range.endNS > this.range.totalNS) this.range.endNS = this.range.totalNS; 389 if (this.range.startNS > this.range.totalNS) this.range.startNS = this.range.totalNS; 390 this.range.startX = this.range.startNS * (this.canvas?.clientWidth || 0) / this.range.totalNS 391 this.range.endX = this.range.endNS * (this.canvas?.clientWidth || 0) / this.range.totalNS 392 this.markA.frame.x = this.range.startX 393 this.markA.inspectionFrame.x = this.markA.frame.x - markPadding 394 this.markB.frame.x = this.range.endX 395 this.markB.inspectionFrame.x = this.markB.frame.x - markPadding 396 } 397 398 setRangeNS(startNS: number, endNS: number) { 399 this.range.startNS = startNS 400 this.range.endNS = endNS 401 this.fillX() 402 this.draw(); 403 } 404 405 getRange(): TimeRange { 406 return this.range; 407 } 408 409 cancelPressFrame() { 410 if (this.pressFrameIdA != -1) cancelAnimationFrame(this.pressFrameIdA); 411 if (this.pressFrameIdD != -1) cancelAnimationFrame(this.pressFrameIdD); 412 if (this.pressFrameIdW != -1) cancelAnimationFrame(this.pressFrameIdW); 413 if (this.pressFrameIdS != -1) cancelAnimationFrame(this.pressFrameIdS); 414 } 415 416 cancelUpFrame() { 417 if (this.upFrameIdA != -1) cancelAnimationFrame(this.upFrameIdA); 418 if (this.upFrameIdD != -1) cancelAnimationFrame(this.upFrameIdD); 419 if (this.upFrameIdW != -1) cancelAnimationFrame(this.upFrameIdW); 420 if (this.upFrameIdS != -1) cancelAnimationFrame(this.upFrameIdS); 421 } 422 423 424 keyPress(ev: KeyboardEvent) { 425 if (this.animaStartTime == undefined || 426 (this.pressedKeys.length > 0 && this.pressedKeys[this.pressedKeys.length - 1] != ev.key.toLocaleLowerCase()) 427 ) { 428 let dat = new Date(); 429 dat.setTime(dat.getTime() - 400); 430 this.animaStartTime = dat.getTime(); 431 } 432 this.currentDuration = (new Date().getTime() - this.animaStartTime); 433 if (Math.trunc(this.currentDuration / this.cacheInterval.interval) != this.cacheInterval.value) { 434 this.cacheInterval.flag = true; 435 this.cacheInterval.value = Math.trunc(this.currentDuration / this.cacheInterval.interval) 436 } else { 437 this.cacheInterval.flag = false; 438 } 439 this.range.refresh = this.cacheInterval.flag; 440 if (this.pressedKeys.length > 0) { 441 if (this.pressedKeys[this.pressedKeys.length - 1] != ev.key.toLocaleLowerCase()) { 442 this.cancelPressFrame(); 443 this.cancelUpFrame(); 444 this.pressedKeys.push(ev.key.toLocaleLowerCase()); 445 let dat = new Date(); 446 dat.setTime(dat.getTime() - 400); 447 this.animaStartTime = dat.getTime(); 448 this.keyboardKeyPressMap[this.pressedKeys[this.pressedKeys.length - 1]]?.bind(this)(); 449 } 450 } else { 451 this.cancelPressFrame(); 452 this.cancelUpFrame(); 453 this.pressedKeys.push(ev.key.toLocaleLowerCase()); 454 let dat = new Date(); 455 dat.setTime(dat.getTime() - 400); 456 this.animaStartTime = dat.getTime(); 457 this.keyboardKeyPressMap[this.pressedKeys[this.pressedKeys.length - 1]]?.bind(this)(); 458 } 459 } 460 461 keyPressW() { 462 let animW = () => { 463 if (this.scale === 50) { 464 this.range.refresh = true; 465 this.notifyHandler(this.range); 466 this.range.refresh = false; 467 return; 468 } 469 this.range.startNS += (this.centerXPercentage * this.currentDuration * this.scale / this.p); 470 this.range.endNS -= ((1 - this.centerXPercentage) * this.currentDuration * this.scale / this.p); 471 this.fillX(); 472 this.draw(); 473 this.range.refresh = false; 474 this.pressFrameIdW = requestAnimationFrame(animW) 475 } 476 this.pressFrameIdW = requestAnimationFrame(animW) 477 } 478 479 keyPressS() { 480 let animS = () => { 481 if (this.range.startNS <= 0 && this.range.endNS >= this.range.totalNS) { 482 this.range.refresh = true; 483 this.notifyHandler(this.range); 484 this.range.refresh = false; 485 return; 486 } 487 this.range.startNS -= (this.centerXPercentage * this.scale / this.p * this.currentDuration); 488 this.range.endNS += ((1 - this.centerXPercentage) * this.scale / this.p * this.currentDuration); 489 this.fillX(); 490 this.draw(); 491 this.range.refresh = false; 492 this.pressFrameIdS = requestAnimationFrame(animS) 493 } 494 this.pressFrameIdS = requestAnimationFrame(animS) 495 } 496 497 keyPressA() { 498 let animA = () => { 499 if (this.range.startNS == 0) { 500 this.range.refresh = true; 501 this.notifyHandler(this.range); 502 this.range.refresh = false; 503 return; 504 } 505 let s = this.scale / this.p * this.currentDuration * .4; 506 this.range.startNS -= s; 507 this.range.endNS -= s; 508 this.fillX(); 509 this.draw(); 510 this.range.refresh = false; 511 this.pressFrameIdA = requestAnimationFrame(animA) 512 } 513 this.pressFrameIdA = requestAnimationFrame(animA) 514 } 515 516 keyPressD() { 517 let animD = () => { 518 if (this.range.endNS >= this.range.totalNS) { 519 this.range.refresh = true; 520 this.notifyHandler(this.range); 521 this.range.refresh = false; 522 return; 523 } 524 let s = this.scale / this.p * this.currentDuration * .4; 525 this.range.startNS += s; 526 this.range.endNS += s; 527 this.fillX(); 528 this.draw(); 529 this.range.refresh = false; 530 this.pressFrameIdD = requestAnimationFrame(animD) 531 } 532 this.pressFrameIdD = requestAnimationFrame(animD) 533 } 534 535 keyboardKeyPressMap: any = { 536 "w": this.keyPressW, 537 "s": this.keyPressS, 538 "a": this.keyPressA, 539 "d": this.keyPressD, 540 } 541 542 keyboardKeyUpMap: any = { 543 "w": this.keyUpW, 544 "s": this.keyUpS, 545 "a": this.keyUpA, 546 "d": this.keyUpD, 547 } 548 549 keyUp(ev: KeyboardEvent) { 550 this.cacheInterval.value = 0; 551 if (this.pressedKeys.length > 0) { 552 let number = this.pressedKeys.findIndex((value) => value === ev.key.toLocaleLowerCase()); 553 if (number == this.pressedKeys.length - 1) { 554 this.animaStartTime = undefined; 555 this.cancelPressFrame(); 556 this.keyboardKeyUpMap[ev.key]?.bind(this)(); 557 } 558 if (number != -1) { 559 this.pressedKeys.splice(number, 1); 560 } 561 } 562 } 563 564 565 keyUpW() { 566 let startTime = new Date().getTime(); 567 let animW = () => { 568 if (this.scale === 50) { 569 this.range.refresh = true; 570 this.notifyHandler(this.range); 571 this.range.refresh = false; 572 return; 573 } 574 let dur = (new Date().getTime() - startTime); 575 this.range.startNS += (this.centerXPercentage * 100 * this.scale / this.p); 576 this.range.endNS -= ((1 - this.centerXPercentage) * 100 * this.scale / this.p); 577 this.fillX(); 578 this.draw(); 579 this.range.refresh = false; 580 if (dur < 200) { 581 this.upFrameIdW = requestAnimationFrame(animW); 582 } else { 583 this.range.refresh = true; 584 this.notifyHandler(this.range); 585 this.range.refresh = false; 586 } 587 } 588 this.upFrameIdW = requestAnimationFrame(animW); 589 } 590 591 keyUpS() { 592 let startTime = new Date().getTime(); 593 let animS = () => { 594 if (this.range.startNS <= 0 && this.range.endNS >= this.range.totalNS) { 595 this.range.refresh = true; 596 this.notifyHandler(this.range); 597 this.range.refresh = false; 598 return; 599 } 600 let dur = (new Date().getTime() - startTime); 601 this.range.startNS -= (this.centerXPercentage * 100 * this.scale / this.p); 602 this.range.endNS += ((1 - this.centerXPercentage) * 100 * this.scale / this.p); 603 this.fillX(); 604 this.draw(); 605 this.range.refresh = false; 606 if (dur < 200) { 607 this.upFrameIdS = requestAnimationFrame(animS); 608 } else { 609 this.range.refresh = true; 610 this.notifyHandler(this.range); 611 this.range.refresh = false; 612 } 613 } 614 this.upFrameIdS = requestAnimationFrame(animS); 615 } 616 617 keyUpA() { 618 let startTime = new Date().getTime(); 619 let animA = () => { 620 if (this.range.startNS <= 0) { 621 this.range.refresh = true; 622 this.notifyHandler(this.range); 623 this.range.refresh = false; 624 return; 625 } 626 let dur = (new Date().getTime() - startTime); 627 let s = this.scale * 80 / this.p; 628 this.range.startNS -= s; 629 this.range.endNS -= s; 630 this.fillX(); 631 this.draw(); 632 this.range.refresh = false; 633 if (dur < 200) { 634 this.upFrameIdA = requestAnimationFrame(animA); 635 } else { 636 this.range.refresh = true; 637 this.notifyHandler(this.range); 638 this.range.refresh = false; 639 } 640 } 641 this.upFrameIdA = requestAnimationFrame(animA); 642 } 643 644 keyUpD() { 645 let startTime = new Date().getTime(); 646 let animD = () => { 647 if (this.range.endNS >= this.range.totalNS) { 648 this.range.refresh = true; 649 this.notifyHandler(this.range); 650 this.range.refresh = false; 651 return; 652 } 653 let dur = (new Date().getTime() - startTime); 654 let s = this.scale * 80 / this.p; 655 this.range.startNS += s; 656 this.range.endNS += s; 657 this.fillX(); 658 this.draw(); 659 this.range.refresh = false; 660 if (dur < 200) { 661 this.upFrameIdD = requestAnimationFrame(animD); 662 } else { 663 this.range.refresh = true; 664 this.notifyHandler(this.range); 665 this.range.refresh = false; 666 } 667 } 668 this.upFrameIdD = requestAnimationFrame(animD); 669 } 670} 671