mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Manga Reader Double Layout bugfixes (#1341)
* Enforce some max heights on series detail page * Added some icon to layout mode to help the user understand how they work (Robbie needs to css it) * Adding split-double icon * Fixing reverse * Added lots of debug code, refactored documentation, and added some history for wide images * More prefetching code for wide images * Fixed the issue where sometimes paging backwards would skip an image * Fixed up a bug where occasionally on double (manga) paging backwards could skip a page. Fixed a bug on double where last page could get duplicated. * Don't update pageDimensionHistory since we don't need it * Forgot some changes Co-authored-by: Robbie Davis <robbie@therobbiedavis.com>
This commit is contained in:
parent
f72459a728
commit
dacf15f024
@ -1,6 +1,6 @@
|
|||||||
<div class="list-item-container d-flex flex-row g-0 mb-2 p-2">
|
<div class="list-item-container d-flex flex-row g-0 mb-2 p-2">
|
||||||
<div class="pe-2">
|
<div class="pe-2">
|
||||||
<app-image [imageUrl]="imageUrl" [height]="imageHeight" [width]="imageWidth"></app-image>
|
<app-image [imageUrl]="imageUrl" [height]="imageHeight" maxHeight="200px" [width]="imageWidth"></app-image>
|
||||||
<div class="not-read-badge" *ngIf="pagesRead === 0 && totalPages > 0"></div>
|
<div class="not-read-badge" *ngIf="pagesRead === 0 && totalPages > 0"></div>
|
||||||
<span class="download" *ngIf="download$ | async as download">
|
<span class="download" *ngIf="download$ | async as download">
|
||||||
<app-circular-loader [currentValue]="download.progress"></app-circular-loader>
|
<app-circular-loader [currentValue]="download.progress"></app-circular-loader>
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{readerService.imageUrlToPageNum(this.canvasImage.src)}}
|
||||||
|
{{readerService.imageUrlToPageNum(this.canvasImage2.src)}}
|
||||||
|
|
||||||
<div style="margin-left: auto; padding-right: 3%;">
|
<div style="margin-left: auto; padding-right: 3%;">
|
||||||
<button class="btn btn-icon btn-small" title="Shortcuts" (click)="openShortcutModal()">
|
<button class="btn btn-icon btn-small" title="Shortcuts" (click)="openShortcutModal()">
|
||||||
<i class="fa-regular fa-rectangle-list" aria-hidden="true"></i>
|
<i class="fa-regular fa-rectangle-list" aria-hidden="true"></i>
|
||||||
@ -63,13 +66,12 @@
|
|||||||
<div class="image-container {{getFittingOptionClass()}}" [ngClass]="{'d-none': renderWithCanvas, 'center-double': ShouldRenderDoublePage,
|
<div class="image-container {{getFittingOptionClass()}}" [ngClass]="{'d-none': renderWithCanvas, 'center-double': ShouldRenderDoublePage,
|
||||||
'fit-to-width-double-offset' : FittingOption === FITTING_OPTION.WIDTH && ShouldRenderDoublePage,
|
'fit-to-width-double-offset' : FittingOption === FITTING_OPTION.WIDTH && ShouldRenderDoublePage,
|
||||||
'fit-to-height-double-offset': FittingOption === FITTING_OPTION.HEIGHT && ShouldRenderDoublePage,
|
'fit-to-height-double-offset': FittingOption === FITTING_OPTION.HEIGHT && ShouldRenderDoublePage,
|
||||||
'original-double-offset' : FittingOption === FITTING_OPTION.ORIGINAL && ShouldRenderDoublePage,
|
'original-double-offset' : FittingOption === FITTING_OPTION.ORIGINAL && ShouldRenderDoublePage}">
|
||||||
'reverse': ShouldRenderReverseDouble}">
|
|
||||||
<img #image [src]="canvasImage.src" id="image-1"
|
<img #image [src]="canvasImage.src" id="image-1"
|
||||||
class="{{getFittingOptionClass()}} {{readerMode === ReaderMode.LeftRight || readerMode === ReaderMode.UpDown ? '' : 'd-none'}} {{showClickOverlay ? 'blur' : ''}}">
|
class="{{getFittingOptionClass()}} {{readerMode === ReaderMode.LeftRight || readerMode === ReaderMode.UpDown ? '' : 'd-none'}} {{showClickOverlay ? 'blur' : ''}}">
|
||||||
|
|
||||||
<ng-container *ngIf="(ShouldRenderDoublePage || ShouldRenderReverseDouble) && (this.pageNum <= maxPages - 1 && this.pageNum > 0)">
|
<ng-container *ngIf="(this.canvasImage2.src !== '') && (readerService.imageUrlToPageNum(canvasImage2.src) <= maxPages - 1 && !isCoverImage())">
|
||||||
<img [src]="canvasImage2.src" id="image-2" class="image-2 {{getFittingOptionClass()}} {{readerMode === ReaderMode.LeftRight || readerMode === ReaderMode.UpDown ? '' : 'd-none'}} {{showClickOverlay ? 'blur' : ''}} {{ShouldRenderReverseDouble ? 'reverse' : ''}}">
|
<img [src]="canvasImage2.src" id="image-2" class="image-2 {{getFittingOptionClass()}} {{readerMode === ReaderMode.LeftRight || readerMode === ReaderMode.UpDown ? '' : 'd-none'}} {{showClickOverlay ? 'blur' : ''}}"> <!-- {{ShouldRenderReverseDouble ? 'reverse' : ''}} -->
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -162,7 +164,42 @@
|
|||||||
|
|
||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<div class="col-md-6 col-sm-12">
|
<div class="col-md-6 col-sm-12">
|
||||||
<label for="layout-mode" class="form-label">Layout Mode</label>
|
<label for="layout-mode" class="form-label">Layout Mode</label>
|
||||||
|
<ng-container [ngSwitch]="layoutMode">
|
||||||
|
<ng-container *ngSwitchCase="LayoutMode.Single">
|
||||||
|
<div class="split-double">
|
||||||
|
<span class="fa-stack fa-1x">
|
||||||
|
<i class="fa-regular fa-square-full fa-stack-2x"></i>
|
||||||
|
<i class="fa fa-image fa-stack-1x"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngSwitchCase="LayoutMode.Double">
|
||||||
|
<div class="split-double">
|
||||||
|
<span class="fa-stack fa-1x">
|
||||||
|
<i class="fa-regular fa-square-full fa-stack-2x"></i>
|
||||||
|
<i class="fab fa-1 fa-stack-1x"></i>
|
||||||
|
</span>
|
||||||
|
<span class="fa-stack fa right">
|
||||||
|
<i class="fa-regular fa-square-full fa-stack-2x"></i>
|
||||||
|
<i class="fab fa-2 fa-stack-1x"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngSwitchCase="LayoutMode.DoubleReversed">
|
||||||
|
<div class="split-double">
|
||||||
|
<span class="fa-stack fa-1x">
|
||||||
|
<i class="fa-regular fa-square-full fa-stack-2x"></i>
|
||||||
|
<i class="fab fa-2 fa-stack-1x"></i>
|
||||||
|
</span>
|
||||||
|
<span class="fa-stack fa right">
|
||||||
|
<i class="fa-regular fa-square-full fa-stack-2x"></i>
|
||||||
|
<i class="fab fa-1 fa-stack-1x"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<!-- <div class="{{LayoutModeIconClass}}"></div> -->
|
||||||
|
</ng-container>
|
||||||
<select class="form-control" id="page-fitting" formControlName="layoutMode">
|
<select class="form-control" id="page-fitting" formControlName="layoutMode">
|
||||||
<option [value]="opt.value" *ngFor="let opt of layoutModes">{{opt.text}}</option>
|
<option [value]="opt.value" *ngFor="let opt of layoutModes">{{opt.text}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -57,9 +57,14 @@ img {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.reverse {
|
&.reverse {
|
||||||
flex-direction: row-reverse;
|
|
||||||
overflow: unset;
|
overflow: unset;
|
||||||
justify-content: flex-end;
|
display: flex;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin: unset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#image-2 {
|
#image-2 {
|
||||||
@ -172,6 +177,7 @@ img {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 2px solid #ccc;
|
border: 2px solid #ccc;
|
||||||
vertical-align: sub;
|
vertical-align: sub;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
margin-left: 30%;
|
margin-left: 30%;
|
||||||
@ -197,8 +203,21 @@ img {
|
|||||||
.none {
|
.none {
|
||||||
background-color: rgba(255, 255, 255, 0.5);
|
background-color: rgba(255, 255, 255, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For layout only
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.split-double {
|
||||||
|
height: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: .7em;
|
||||||
|
|
||||||
|
.right {
|
||||||
|
left: -7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
::ng-deep {
|
::ng-deep {
|
||||||
.custom-slider .ngx-slider .ngx-slider-bar {
|
.custom-slider .ngx-slider .ngx-slider-bar {
|
||||||
background: #e9ffe2;
|
background: #e9ffe2;
|
||||||
|
@ -38,6 +38,7 @@ const OVERLAY_AUTO_CLOSE_TIME = 3000;
|
|||||||
const CLICK_OVERLAY_TIMEOUT = 3000;
|
const CLICK_OVERLAY_TIMEOUT = 3000;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-manga-reader',
|
selector: 'app-manga-reader',
|
||||||
templateUrl: './manga-reader.component.html',
|
templateUrl: './manga-reader.component.html',
|
||||||
@ -66,6 +67,14 @@ const CLICK_OVERLAY_TIMEOUT = 3000;
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||||
|
|
||||||
|
|
||||||
|
@ViewChild('reader') reader!: ElementRef;
|
||||||
|
@ViewChild('readingArea') readingArea!: ElementRef;
|
||||||
|
@ViewChild('content') canvas: ElementRef | undefined;
|
||||||
|
@ViewChild('image') image!: ElementRef;
|
||||||
|
|
||||||
|
|
||||||
libraryId!: number;
|
libraryId!: number;
|
||||||
seriesId!: number;
|
seriesId!: number;
|
||||||
volumeId!: number;
|
volumeId!: number;
|
||||||
@ -123,33 +132,41 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
isLoose = false;
|
isLoose = false;
|
||||||
|
|
||||||
@ViewChild('reader') reader!: ElementRef;
|
|
||||||
@ViewChild('readingArea') readingArea!: ElementRef;
|
|
||||||
@ViewChild('content') canvas: ElementRef | undefined;
|
|
||||||
@ViewChild('image') image!: ElementRef;
|
|
||||||
private ctx!: CanvasRenderingContext2D;
|
private ctx!: CanvasRenderingContext2D;
|
||||||
/**
|
/**
|
||||||
* Used to render a page on the canvas or in the image tag. This Image element is prefetched by the cachedImages buffer
|
* Used to render a page on the canvas or in the image tag. This Image element is prefetched by the cachedImages buffer.
|
||||||
|
* @remarks Used for rendering to screen.
|
||||||
*/
|
*/
|
||||||
canvasImage = new Image();
|
canvasImage = new Image();
|
||||||
/**
|
/**
|
||||||
* Used solely for LayoutMode.Double rendering. Will always hold the next image in buffer.
|
* Used solely for LayoutMode.Double rendering.
|
||||||
|
* @remarks Used for rendering to screen.
|
||||||
*/
|
*/
|
||||||
canvasImage2 = new Image();
|
canvasImage2 = new Image();
|
||||||
/**
|
/**
|
||||||
* Used solely for LayoutMode.Double rendering. Will always hold the previous image in buffer.
|
* Used solely for LayoutMode.Double rendering. Will always hold the previous image to canvasImage
|
||||||
|
* @see canvasImage
|
||||||
*/
|
*/
|
||||||
canvasImagePrev = new Image();
|
canvasImagePrev = new Image();
|
||||||
/**
|
/**
|
||||||
* Used solely for LayoutMode.Double rendering. Will always hold the next image in buffer.
|
* Used solely for LayoutMode.Double rendering. Will always hold the next image to canvasImage
|
||||||
|
* @see canvasImage
|
||||||
*/
|
*/
|
||||||
canvasImageNext = new Image();
|
canvasImageNext = new Image();
|
||||||
/**
|
/**
|
||||||
* Used solely for LayoutMode.DoubleReverse rendering. Will always hold the image after next in buffer.
|
* Responsible to hold current page + 2. Used to know if we should render
|
||||||
|
* @remarks Used solely for LayoutMode.DoubleReverse rendering.
|
||||||
*/
|
*/
|
||||||
canvasImageNextDouble = new Image();
|
canvasImageAheadBy2 = new Image();
|
||||||
|
/**
|
||||||
|
* Responsible to hold current page -2 2. Used to know if we should render
|
||||||
|
* @remarks Used solely for LayoutMode.DoubleReverse rendering.
|
||||||
|
*/
|
||||||
|
canvasImageBehindBy2 = new Image();
|
||||||
/**
|
/**
|
||||||
* Dictates if we use render with canvas or with image. This is only for Splitting.
|
* Dictates if we use render with canvas or with image.
|
||||||
|
* @remarks This is only for Splitting.
|
||||||
*/
|
*/
|
||||||
renderWithCanvas: boolean = false;
|
renderWithCanvas: boolean = false;
|
||||||
|
|
||||||
@ -296,25 +313,32 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
return Math.max(Math.min(this.pageNum, this.maxPages - 1), 0);
|
return Math.max(Math.min(this.pageNum, this.maxPages - 1), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if we should render a double page.
|
||||||
|
* The general gist is if we are on double layout mode, the current page (first page) is not a cover image or a wide image
|
||||||
|
* and the next page is not a wide image (as only non-wides should be shown next to each other).
|
||||||
|
* @remarks This will always fail if the window's width is greater than the height
|
||||||
|
*/
|
||||||
get ShouldRenderDoublePage() {
|
get ShouldRenderDoublePage() {
|
||||||
|
// window.innerWidth > window.innerHeight // Don't render double if orientation is portrait, mostly mobile
|
||||||
return (
|
return (
|
||||||
this.layoutMode === LayoutMode.Double &&
|
this.layoutMode === LayoutMode.Double &&
|
||||||
!this.isCoverImage() &&
|
!this.isCoverImage() &&
|
||||||
!this.isWideImage(this.canvasImage) &&
|
!this.isWideImage(this.canvasImage) &&
|
||||||
!this.isWideImage(this.canvasImageNext) &&
|
!this.isWideImage(this.canvasImageNext)
|
||||||
window.innerWidth > window.innerHeight // Don't render double if orientation is portrait, mostly mobile
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get ShouldRenderReverseDouble() {
|
get ShouldRenderReverseDouble() {
|
||||||
|
// NOTE: I'm not going to care about window.innerWidth > window.innerHeight since a higher level handler will manage
|
||||||
|
// window.innerWidth > window.innerHeight // Don't render double reversed if orientation is portrait, mostly mobile
|
||||||
return (
|
return (
|
||||||
this.layoutMode === LayoutMode.DoubleReversed &&
|
this.layoutMode === LayoutMode.DoubleReversed &&
|
||||||
!this.isCoverImage() &&
|
!this.isCoverImage() &&
|
||||||
!this.isCoverImage(this.pageNum - 1) &&
|
!this.isCoverImage(this.pageNum - 1) &&
|
||||||
!this.isWideImage(this.canvasImage) &&
|
!this.isWideImage(this.canvasImage) &&
|
||||||
!this.isWideImage(this.canvasImageNext) &&
|
!this.isWideImage(this.canvasImageNext) &&
|
||||||
!this.isLoose &&
|
!this.isLoose
|
||||||
window.innerWidth > window.innerHeight // Don't render double reversed if orientation is portrait, mostly mobile
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,6 +396,17 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
return 'right-side';
|
return 'right-side';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get LayoutModeIconClass() {
|
||||||
|
switch (this.layoutMode) {
|
||||||
|
case LayoutMode.Single:
|
||||||
|
return 'none';
|
||||||
|
case LayoutMode.Double:
|
||||||
|
return 'double';
|
||||||
|
case LayoutMode.DoubleReversed:
|
||||||
|
return 'double-reversed';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get ReaderModeIcon() {
|
get ReaderModeIcon() {
|
||||||
switch(this.readerMode) {
|
switch(this.readerMode) {
|
||||||
case ReaderMode.LeftRight:
|
case ReaderMode.LeftRight:
|
||||||
@ -960,6 +995,12 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
|
|
||||||
const notInSplit = this.currentImageSplitPart !== (this.isSplitLeftToRight() ? SPLIT_PAGE_PART.LEFT_PART : SPLIT_PAGE_PART.RIGHT_PART);
|
const notInSplit = this.currentImageSplitPart !== (this.isSplitLeftToRight() ? SPLIT_PAGE_PART.LEFT_PART : SPLIT_PAGE_PART.RIGHT_PART);
|
||||||
|
|
||||||
|
// console.log('Current, Next: ', this.readerService.imageUrlToPageNum(this.canvasImage.src), ',', this.readerService.imageUrlToPageNum(this.canvasImageNext.src));
|
||||||
|
// console.log('Is canvasImage wide: ', this.isWideImage(this.canvasImage));
|
||||||
|
// console.log('Is canvasImage next wide: ', this.isWideImage(this.canvasImageNext));
|
||||||
|
// console.log('PRev: ', this.readerService.imageUrlToPageNum(this.canvasImagePrev.src));
|
||||||
|
|
||||||
|
|
||||||
let pageAmount = 1;
|
let pageAmount = 1;
|
||||||
if (this.layoutMode === LayoutMode.Double) {
|
if (this.layoutMode === LayoutMode.Double) {
|
||||||
pageAmount = (
|
pageAmount = (
|
||||||
@ -969,12 +1010,11 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
!this.isSecondLastImage() &&
|
!this.isSecondLastImage() &&
|
||||||
!this.isLastImage()
|
!this.isLastImage()
|
||||||
? 2 : 1);
|
? 2 : 1);
|
||||||
}
|
} else if (this.layoutMode === LayoutMode.DoubleReversed) {
|
||||||
if (this.layoutMode === LayoutMode.DoubleReversed) {
|
|
||||||
pageAmount = (
|
pageAmount = (
|
||||||
!this.isCoverImage(this.pageNum - 1) &&
|
//!this.isCoverImage(this.pageNum - 1) && //
|
||||||
!this.isWideImage(this.canvasImagePrev) &&
|
!this.isWideImage(this.canvasImageNext) &&
|
||||||
!this.isWideImage(this.canvasImageNextDouble) &&
|
!this.isWideImage(this.canvasImageAheadBy2) && // Remember we are doing this logic before we've hit the next page, so we need this
|
||||||
!this.isSecondLastImage() &&
|
!this.isSecondLastImage() &&
|
||||||
!this.isLastImage()
|
!this.isLastImage()
|
||||||
? 2 : 1);
|
? 2 : 1);
|
||||||
@ -1014,16 +1054,27 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
|
|
||||||
let pageAmount = 1;
|
let pageAmount = 1;
|
||||||
if (this.layoutMode === LayoutMode.Double) {
|
if (this.layoutMode === LayoutMode.Double) {
|
||||||
|
// Current is current and next is current + 1 (current is the page we are paging from)
|
||||||
|
// console.log('Current, Next: ', this.readerService.imageUrlToPageNum(this.canvasImage.src), ',', this.readerService.imageUrlToPageNum(this.canvasImageNext.src));
|
||||||
|
// console.log('Is canvasImage wide: ', this.isWideImage(this.canvasImage));
|
||||||
|
// console.log('Is canvasImage next wide: ', this.isWideImage(this.canvasImageNext));
|
||||||
|
// console.log('PRev: ', this.readerService.imageUrlToPageNum(this.canvasImagePrev.src)); // Prev is actually currentPage - 1 on double
|
||||||
|
|
||||||
pageAmount = (
|
pageAmount = (
|
||||||
!this.isCoverImage() &&
|
!this.isCoverImage() &&
|
||||||
!this.isWideImage(this.canvasImagePrev)
|
!this.isWideImage(this.canvasImagePrev)
|
||||||
? 2 : 1);
|
? 2 : 1);
|
||||||
}
|
}
|
||||||
if (this.layoutMode === LayoutMode.DoubleReversed) {
|
if (this.layoutMode === LayoutMode.DoubleReversed) {
|
||||||
|
// Current is current - 1 and next is current -2 (current is the page we are paging from)
|
||||||
|
// console.log('Current, Next: ', this.readerService.imageUrlToPageNum(this.canvasImage.src), ',', this.readerService.imageUrlToPageNum(this.canvasImageNext.src));
|
||||||
|
// console.log('Is canvasImage wide: ', this.isWideImage(this.canvasImage));
|
||||||
|
// console.log('Is canvasImage next wide: ', this.isWideImage(this.canvasImageNext));
|
||||||
|
// console.log('PRev: ', this.readerService.imageUrlToPageNum(this.canvasImagePrev.src)); // Prev is actually currentPage + 1 on double reversed
|
||||||
pageAmount = (
|
pageAmount = (
|
||||||
!this.isCoverImage() &&
|
!this.isCoverImage() &&
|
||||||
!this.isCoverImage(this.pageNum - 1) &&
|
!this.isCoverImage(this.pageNum - 1) &&
|
||||||
!this.isWideImage(this.canvasImage) &&
|
!this.isWideImage(this.canvasImage) && // JOE: At this point, these aren't yet set to the new values
|
||||||
!this.isWideImage(this.canvasImageNext)
|
!this.isWideImage(this.canvasImageNext)
|
||||||
? 2 : 1);
|
? 2 : 1);
|
||||||
}
|
}
|
||||||
@ -1202,24 +1253,41 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
this.generalSettingsForm.get('fittingOption')?.setValue(newScale, {emitEvent: false});
|
this.generalSettingsForm.get('fittingOption')?.setValue(newScale, {emitEvent: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If pagenumber is 0 aka first page, which on double page rendering should always render as a single.
|
||||||
|
*
|
||||||
|
* @param pageNumber Defaults to current page number
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
isCoverImage(pageNumber = this.pageNum) {
|
isCoverImage(pageNumber = this.pageNum) {
|
||||||
return pageNumber === 0;
|
return pageNumber === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the image's width is greater than it's height
|
||||||
|
* @param elem Optional Image
|
||||||
|
*/
|
||||||
isWideImage(elem?: HTMLImageElement) {
|
isWideImage(elem?: HTMLImageElement) {
|
||||||
if (elem) {
|
if (elem) {
|
||||||
elem.onload = () => {
|
elem.onload = () => {
|
||||||
return elem.width > elem.height;
|
return elem.width > elem.height;
|
||||||
}
|
}
|
||||||
|
if (elem.src === '') return false;
|
||||||
}
|
}
|
||||||
const element = elem || this.canvasImage;
|
const element = elem || this.canvasImage;
|
||||||
return element.width > element.height;
|
return element.width > element.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the current page is second to last image
|
||||||
|
*/
|
||||||
isSecondLastImage() {
|
isSecondLastImage() {
|
||||||
return this.maxPages - 1 - this.pageNum === 1;
|
return this.maxPages - 1 - this.pageNum === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the current image is last image
|
||||||
|
*/
|
||||||
isLastImage() {
|
isLastImage() {
|
||||||
return this.maxPages - 1 === this.pageNum;
|
return this.maxPages - 1 === this.pageNum;
|
||||||
}
|
}
|
||||||
@ -1230,7 +1298,10 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maintains a circular array of images (that are requested from backend) around the user's current page. This allows for quick loading (seemless to user)
|
||||||
|
* and also maintains page info (wide image, etc) due to onload event.
|
||||||
|
*/
|
||||||
prefetch() {
|
prefetch() {
|
||||||
let index = 1;
|
let index = 1;
|
||||||
|
|
||||||
@ -1251,19 +1322,43 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
//console.log('cachedImages: ', this.cachedImages.arr.map(img => this.readerService.imageUrlToPageNum(img.src) + ': ' + img.complete));
|
//console.log('cachedImages: ', this.cachedImages.arr.map(img => this.readerService.imageUrlToPageNum(img.src) + ': ' + img.complete));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
loadPage() {
|
loadPage() {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.canvasImage2.src = '';
|
this.canvasImage2.src = '';
|
||||||
|
this.canvasImageAheadBy2.src = '';
|
||||||
|
|
||||||
this.isLoose = (this.pageAmount === 1 ? true : false);
|
this.isLoose = (this.pageAmount === 1 ? true : false);
|
||||||
this.canvasImage.src = this.getPageUrl(this.pageNum);
|
this.canvasImage.src = this.getPageUrl(this.pageNum);
|
||||||
|
|
||||||
if (this.layoutMode !== LayoutMode.Single) {
|
if (this.layoutMode !== LayoutMode.Single) {
|
||||||
this.canvasImagePrev.src = this.getPageUrl(this.pageNum + (this.layoutMode !== LayoutMode.DoubleReversed ? - 1 : + 1));
|
this.canvasImageNext.src = this.getPageUrl(this.pageNum + 1); // This needs to be capped at maxPages !this.isLastImage()
|
||||||
this.canvasImageNext.src = this.getPageUrl(this.pageNum + (this.layoutMode !== LayoutMode.DoubleReversed ? + 1 : - 1));
|
this.canvasImagePrev.src = this.getPageUrl(this.pageNum - 1);
|
||||||
this.canvasImageNextDouble.src = this.getPageUrl(this.pageNum + 2);
|
|
||||||
if (this.ShouldRenderDoublePage || this.ShouldRenderReverseDouble) {
|
if (this.pageNum + 2 < this.maxPages - 1) {
|
||||||
this.canvasImage2.src = this.canvasImageNext.src;
|
this.canvasImageAheadBy2.src = this.getPageUrl(this.pageNum + 2);
|
||||||
}
|
}
|
||||||
|
if (this.pageNum - 2 >= 0) {
|
||||||
|
this.canvasImageBehindBy2.src = this.getPageUrl(this.pageNum - 2 || 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.ShouldRenderDoublePage || this.ShouldRenderReverseDouble) {
|
||||||
|
if (this.layoutMode === LayoutMode.Double) {
|
||||||
|
this.canvasImage2.src = this.canvasImageNext.src;
|
||||||
|
} else {
|
||||||
|
this.canvasImage2.src = this.canvasImagePrev.src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('======================================================');
|
||||||
|
// console.log('Page History: ', this.pageDimensionHistory);
|
||||||
|
// console.log('Current Page: ', this.pageNum);
|
||||||
|
// console.log('CanvasImage page: ', this.readerService.imageUrlToPageNum(this.canvasImage.src));
|
||||||
|
// console.log('CanvasImage2 page: ', this.readerService.imageUrlToPageNum(this.canvasImage2.src));
|
||||||
|
// console.log('Canvas Image Next:', this.readerService.imageUrlToPageNum(this.canvasImageNext.src));
|
||||||
|
// console.log('Canvas Image Next Ahead by 2:', this.readerService.imageUrlToPageNum(this.canvasImageAheadBy2.src));
|
||||||
|
// console.log('Canvas Image Prev:', this.readerService.imageUrlToPageNum(this.canvasImagePrev.src));
|
||||||
|
// console.log('======================================================');
|
||||||
}
|
}
|
||||||
this.renderPage();
|
this.renderPage();
|
||||||
this.prefetch();
|
this.prefetch();
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
<div [ngStyle]="{'height': ScrollingBlockHeight}" class="main-container container-fluid pt-2" *ngIf="series !== undefined" #scrollingBlock>
|
<div [ngStyle]="{'height': ScrollingBlockHeight}" class="main-container container-fluid pt-2" *ngIf="series !== undefined" #scrollingBlock>
|
||||||
<div class="row mb-3 info-container">
|
<div class="row mb-3 info-container">
|
||||||
<div class="col-md-2 col-xs-4 col-sm-6 d-none d-sm-block">
|
<div class="col-md-2 col-xs-4 col-sm-6 d-none d-sm-block">
|
||||||
<app-image maxWidth="300px" [imageUrl]="seriesImage"></app-image>
|
<app-image maxWidth="300px" maxHeight="400px" [imageUrl]="seriesImage"></app-image>
|
||||||
<!-- NOTE: We can put continue point here as Vol X Ch Y or just Ch Y or Book Z ?-->
|
<!-- NOTE: We can put continue point here as Vol X Ch Y or just Ch Y or Book Z ?-->
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-10 col-xs-8 col-sm-6 mt-2">
|
<div class="col-md-10 col-xs-8 col-sm-6 mt-2">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user