Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeView.js

Issue 2773173002: [DevTools] Enable full-size screenshots (Closed)
Patch Set: works, but not sharp Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 /** 4 /**
5 * @unrestricted 5 * @unrestricted
6 */ 6 */
7 Emulation.DeviceModeView = class extends UI.VBox { 7 Emulation.DeviceModeView = class extends UI.VBox {
8 constructor() { 8 constructor() {
9 super(true); 9 super(true);
10 this.setMinimumSize(150, 150); 10 this.setMinimumSize(150, 150);
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 this._toolbar.restore(); 352 this._toolbar.restore();
353 } 353 }
354 354
355 /** 355 /**
356 * @override 356 * @override
357 */ 357 */
358 willHide() { 358 willHide() {
359 this._model.emulate(Emulation.DeviceModeModel.Type.None, null, null); 359 this._model.emulate(Emulation.DeviceModeModel.Type.None, null, null);
360 } 360 }
361 361
362 captureScreenshot() { 362 /**
363 var target = this._model.target(); 363 * @return {!Promise}
364 if (!target) 364 */
365 async captureScreenshot() {
366 SDK.DOMModel.muteHighlight();
367 var screenshot = await this._model.captureScreenshot(false);
368 SDK.DOMModel.unmuteHighlight();
369 if (screenshot === null)
365 return; 370 return;
366 var screenCaptureModel = target.model(SDK.ScreenCaptureModel);
367 if (!screenCaptureModel)
368 return;
369 SDK.DOMModel.muteHighlight();
370 371
371 var zoomFactor = UI.zoomManager.zoomFactor(); 372 var pageImage = new Image();
372 var rect = this._contentArea.getBoundingClientRect(); 373 pageImage.src = 'data:image/png;base64,' + screenshot;
373 var availableSize = new UI.Size(Math.max(rect.width * zoomFactor, 1), Math.m ax(rect.height * zoomFactor, 1)); 374 pageImage.onload = async () => {
374 var outlineVisible = this._model.deviceOutlineSetting().get(); 375 var scale = 1 / this._model.scale();
376 var outlineRect = this._model.outlineRect().scale(scale);
377 var screenRect = this._model.screenRect().scale(scale);
378 var visiblePageRect = this._model.visiblePageRect().scale(scale);
379 var contentLeft = screenRect.left + visiblePageRect.left - outlineRect.lef t;
380 var contentTop = screenRect.top + visiblePageRect.top - outlineRect.top;
375 381
376 if (availableSize.width < this._model.screenRect().width ||
377 availableSize.height < this._model.screenRect().height) {
378 UI.inspectorView.minimize();
379 this._model.deviceOutlineSetting().set(false);
380 }
381
382 screenCaptureModel.captureScreenshot('png', 100).then(screenshotCaptured.bin d(this));
383
384 /**
385 * @param {?string} content
386 * @this {Emulation.DeviceModeView}
387 */
388 function screenshotCaptured(content) {
389 this._model.deviceOutlineSetting().set(outlineVisible);
390 var dpr = window.devicePixelRatio;
391 var outlineRect = this._model.outlineRect().scale(dpr);
392 var screenRect = this._model.screenRect().scale(dpr);
393 screenRect.left -= outlineRect.left;
394 screenRect.top -= outlineRect.top;
395 var visiblePageRect = this._model.visiblePageRect().scale(dpr);
396 visiblePageRect.left += screenRect.left;
397 visiblePageRect.top += screenRect.top;
398 outlineRect.left = 0;
399 outlineRect.top = 0;
400
401 SDK.DOMModel.unmuteHighlight();
402 UI.inspectorView.restore();
403
404 if (content === null)
405 return;
406
407 // Create a canvas to splice the images together.
408 var canvas = createElement('canvas'); 382 var canvas = createElement('canvas');
383 canvas.width = Math.floor(outlineRect.width);
384 canvas.height = Math.floor(outlineRect.height);
409 var ctx = canvas.getContext('2d'); 385 var ctx = canvas.getContext('2d');
410 canvas.width = outlineRect.width;
411 canvas.height = outlineRect.height;
412 ctx.imageSmoothingEnabled = false; 386 ctx.imageSmoothingEnabled = false;
413 387
414 var promise = Promise.resolve();
415 if (this._model.outlineImage()) 388 if (this._model.outlineImage())
416 promise = promise.then(paintImage.bind(null, this._model.outlineImage(), outlineRect)); 389 await this._paintImage(ctx, this._model.outlineImage(), outlineRect.rela tiveTo(outlineRect));
417 promise = promise.then(drawBorder);
418 if (this._model.screenImage()) 390 if (this._model.screenImage())
419 promise = promise.then(paintImage.bind(null, this._model.screenImage(), screenRect)); 391 await this._paintImage(ctx, this._model.screenImage(), screenRect.relati veTo(outlineRect));
420 promise.then(paintScreenshot.bind(this)); 392 ctx.drawImage(pageImage, Math.floor(contentLeft), Math.floor(contentTop));
421 393 this._saveScreenshot(canvas);
422 /** 394 };
423 * @param {string} src
424 * @param {!UI.Rect} rect
425 * @return {!Promise<undefined>}
426 */
427 function paintImage(src, rect) {
428 var callback;
429 var promise = new Promise(fulfill => callback = fulfill);
430 var image = new Image();
431 image.crossOrigin = 'Anonymous';
432 image.srcset = src;
433 image.onload = onImageLoad;
434 image.onerror = callback;
435 return promise;
436
437 function onImageLoad() {
438 ctx.drawImage(image, rect.left, rect.top, rect.width, rect.height);
439 callback();
440 }
441 }
442
443 function drawBorder() {
444 ctx.strokeStyle = 'hsla(0, 0%, 98%, 0.5)';
445 ctx.lineWidth = 1;
446 ctx.setLineDash([10, 10]);
447 ctx.strokeRect(screenRect.left + 1, screenRect.top + 1, screenRect.width - 2, screenRect.height - 2);
448 }
449
450 /**
451 * @this {Emulation.DeviceModeView}
452 */
453 function paintScreenshot() {
454 var pageImage = new Image();
455 pageImage.src = 'data:image/png;base64,' + content;
456 pageImage.onload = () => {
457 ctx.drawImage(
458 pageImage, visiblePageRect.left, visiblePageRect.top, Math.min(pag eImage.naturalWidth, screenRect.width),
459 Math.min(pageImage.naturalHeight, screenRect.height));
460 var url = target.inspectedURL();
461 var fileName = url ? url.trimURL().removeURLFragment() : '';
462 if (this._model.type() === Emulation.DeviceModeModel.Type.Device)
463 fileName += Common.UIString('(%s)', this._model.device().title);
464 // Trigger download.
465 var link = createElement('a');
466 link.download = fileName + '.png';
467 link.href = canvas.toDataURL('image/png');
468 link.click();
469 };
470 }
471 }
472 } 395 }
473 396
474 captureFullSizeScreenshot() { 397 /**
398 * @return {!Promise}
399 */
400 async captureFullSizeScreenshot() {
475 SDK.DOMModel.muteHighlight(); 401 SDK.DOMModel.muteHighlight();
476 this._model.captureFullSizeScreenshot(content => { 402 var screenshot = await this._model.captureScreenshot(true);
477 SDK.DOMModel.unmuteHighlight(); 403 SDK.DOMModel.unmuteHighlight();
478 if (content === null) 404 if (screenshot === null)
479 return; 405 return;
406
407 var pageImage = new Image();
408 pageImage.src = 'data:image/png;base64,' + screenshot;
409 pageImage.onload = () => {
480 var canvas = createElement('canvas'); 410 var canvas = createElement('canvas');
481 var pageImage = new Image(); 411 canvas.width = pageImage.width;
482 pageImage.src = 'data:image/png;base64,' + content; 412 canvas.height = pageImage.height;
483 pageImage.onload = () => { 413 var ctx = canvas.getContext('2d');
484 var ctx = canvas.getContext('2d'); 414 ctx.imageSmoothingEnabled = false;
485 ctx.imageSmoothingEnabled = false; 415 ctx.drawImage(pageImage, 0, 0);
486 canvas.width = pageImage.width; 416 this._saveScreenshot(canvas);
487 canvas.height = pageImage.height; 417 };
488 ctx.drawImage(pageImage, 0, 0); 418 }
489 var url = this._model.target() && this._model.target().inspectedURL(); 419
490 var fileName = url ? url.trimURL().removeURLFragment() : ''; 420 /**
491 if (this._model.type() === Emulation.DeviceModeModel.Type.Device) 421 * @param {!CanvasRenderingContext2D} ctx
492 fileName += Common.UIString('(%s)', this._model.device().title); 422 * @param {string} src
493 var link = createElement('a'); 423 * @param {!UI.Rect} rect
494 link.download = fileName + '.png'; 424 * @return {!Promise}
495 canvas.toBlob(function(blob) { 425 */
496 link.href = URL.createObjectURL(blob); 426 _paintImage(ctx, src, rect) {
497 link.click(); 427 return new Promise(fulfill => {
498 }); 428 var image = new Image();
429 image.crossOrigin = 'Anonymous';
430 image.srcset = src;
431 image.onerror = fulfill;
432 image.onload = () => {
433 ctx.drawImage(image, rect.left, rect.top, rect.width, rect.height);
434 fulfill();
499 }; 435 };
500 }); 436 });
501 } 437 }
438
439 /**
440 * @param {!Element} canvas
441 */
442 _saveScreenshot(canvas) {
443 var url = this._model.target() && this._model.target().inspectedURL();
444 var fileName = url ? url.trimURL().removeURLFragment() : '';
445 if (this._model.type() === Emulation.DeviceModeModel.Type.Device)
446 fileName += Common.UIString('(%s)', this._model.device().title);
447 var link = createElement('a');
448 link.download = fileName + '.png';
449 canvas.toBlob(blob => {
450 link.href = URL.createObjectURL(blob);
451 link.click();
452 });
453 }
502 }; 454 };
503 455
504 /** 456 /**
505 * @unrestricted 457 * @unrestricted
506 */ 458 */
507 Emulation.DeviceModeView.Ruler = class extends UI.VBox { 459 Emulation.DeviceModeView.Ruler = class extends UI.VBox {
508 /** 460 /**
509 * @param {boolean} horizontal 461 * @param {boolean} horizontal
510 * @param {function(number)} applyCallback 462 * @param {function(number)} applyCallback
511 */ 463 */
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 return Promise.resolve(); 546 return Promise.resolve();
595 } 547 }
596 548
597 /** 549 /**
598 * @param {number} size 550 * @param {number} size
599 */ 551 */
600 _onMarkerClick(size) { 552 _onMarkerClick(size) {
601 this._applyCallback.call(null, size); 553 this._applyCallback.call(null, size);
602 } 554 }
603 }; 555 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698