2016-05-25 78 views
1

我有一個問題與離子2(測試版7)和紙JS:當我開始繪圖時,畫布的左上角出現一個白色框。請參閱示例圖片here。繪圖時畫布也會閃爍。Ionic 2與紙JS - 閃爍的帆布和白色的盒子

關於我正在做的事情的簡短說明: 用設備相機拍照並在畫布上繪製該圖像,然後允許用戶在圖像上繪圖。

任何想法我做錯了什麼?或者有關如何解決這個問題的建議?

我的代碼:

拍攝照片(使用離子天然):

public takePicture(): void { 
    // Options for the camera plugin 
    let options = { 
     quality: 20, 
     destinationType: Camera.DestinationType.FILE_URI, 
     sourceType: 1, 
     encodingType: Camera.EncodingType.JPEG, 
     mediaType: Camera.MediaType.PICTURE, 
     correctOrientation: true 
    }; 
    Camera.getPicture(options).then((imageData) => {    

     this.nav.push(DrawPicturePage, { imagePath: imageData }); 

    }, (err) => { 
    }); 
} 

DrawPicturePage(pictureDraw.ts):

import {Platform, Page, NavController, NavParams} from 'ionic-angular'; 
import {ElementRef, ViewChild, NgZone} from '@angular/core'; 

import * as paper from 'paper'; 


@Page({ 
    templateUrl: 'build/pages/pictureDraw/pictureDraw.html', 
}) 

export class DrawPicturePage { 

    @ViewChild("theCanvas") theCanvas: ElementRef; 
    @ViewChild("content") content: ElementRef; 

    private path; 

    private ctx: CanvasRenderingContext2D; // canvas context 
    private imagePath: string = ''; 

    private canvasWidth: number = 100; 
    private canvasHeight: number = 100; 

    private canvasInnerWidth: number = 0; 
    private canvasInnerHeight: number = 0; 

    private width: string = '0%'; 
    private height: string = '0%'; 

    constructor(
     public navParams: NavParams, 
     private zone: NgZone) { 

      this.imagePath = navParams.get('imagePath'); 

    } 

    public ngAfterViewInit(): void { 
     this.ctx = this.theCanvas.nativeElement.getContext("2d"); 
     this.loadImage(); 
    } 

    private loadImage(): void { 

     let image = new Image(); 
     image.src = this.imagePath; 

     image.onload =() => { 

      // count the image ratio 
      let ratio: number = image.width/image.height; 

      // create a canvas and a context for image resizing 
      let oc = document.createElement('canvas'); 
      let octx = oc.getContext('2d'); 

      oc.width = image.width; 
      oc.height = image.height; 

      // resize to max size 1600x900 
      if (image.width > image.height && image.width > 1600) { 
       oc.width = 1600; 
       oc.height = 1600/ratio; 
       if (oc.height > 900) { 
        oc.height = 900; 
        oc.width = 900 * ratio; 
       } 

      } else if (image.height > 1600) { 
       oc.height = 1600; 
       oc.width = 1600 * ratio; 
       if (oc.width > 900) { 
        oc.width = 900; 
        oc.height = 900/ratio; 
       } 
      } 

      octx.drawImage(image, 0, 0, oc.width, oc.height); 

      // calculate the UI size of the canvas 
      if (image.width > image.height) { 
       // landscape 
       this.canvasWidth = this.content.nativeElement.offsetWidth; 
       this.canvasHeight = this.canvasWidth/ratio; 
      } else { 
       // portrait 
       this.canvasHeight = this.content.nativeElement.offsetHeight; 
       this.canvasWidth = this.canvasHeight * ratio; 
      } 

      // set the canvas UI width and height 
      this.zone.run(() => { 
       this.width = Math.round(this.canvasWidth) + 'px'; 
       this.height = Math.round(this.canvasHeight) + 'px'; 
      }); 

      // set the canvas inner width and height 
      this.canvasInnerWidth = oc.width; 
      this.canvasInnerHeight = oc.height; 

      this.setupPaperJS(oc); 

     }; 
    } 

    /** setup paper js */ 
    private setupPaperJS(canvas: any = null): void { 

     paper.install(window); 
     paper.setup(this.theCanvas.nativeElement); 

     this.theCanvas.nativeElement.width = this.canvasInnerWidth; 
     this.theCanvas.nativeElement.height = this.canvasInnerHeight; 

     // draw the image 
     this.ctx.drawImage(canvas, 0, 0, canvas.width, canvas.height, 
      0, 0, this.theCanvas.nativeElement.width, this.theCanvas.nativeElement.height); 
    } 

    private downEvent(event: TouchEvent): void { 
     console.info('downEvent'); 
     let touch: { x: number, y: number } = this.touchCoordToCanvasCoord(event.touches[0].screenX, event.touches[0].screenY); 
     let point: paper.Point = new paper.Point(); 
     point.x = touch.x; 
     point.y = touch.y; 

     if (this.path) { 
      this.path.selected = false; 
     } 

     // Create a new path 
     this.path = new paper.Path({ 
      segments: [point], 
      strokeColor: 'red', 
      strokeWidth: 10 
     }); 
    } 

    private dragEvent(event: TouchEvent): void { 
     console.info('dragEvent'); 

     let touch: { x: number, y: number } = this.touchCoordToCanvasCoord(event.touches[0].screenX, event.touches[0].screenY); 
     let point: paper.Point = new paper.Point(); 
     point.x = touch.x; 
     point.y = touch.y; 

     this.path.lineTo(point); 

    } 

    private upEvent(event: TouchEvent): void { 
     console.info('upEvent'); 

     this.path.simplify(10); 

    } 

    /** Converts the touch coordinate to canvas coordinates */ 
    private touchCoordToCanvasCoord(touchX: number, touchY: number): { x: number, y: number } { 

     let rv: { x: number, y: number } = { x: 0, y: 0 }; 

     let x0: number = 0, y0: number = 0; 
     x0 = this.theCanvas.nativeElement.getBoundingClientRect().left; 
     y0 = this.theCanvas.nativeElement.getBoundingClientRect().top + 45; 

     rv.x = this.canvasInnerWidth/(window.screen.width - 2 * x0) * (touchX - x0); 
     rv.y = this.canvasInnerHeight/(window.screen.height - 2 * y0) * (touchY - y0); 

     if (rv.x < 0) rv.x = 0; 
     if (rv.y < 0) rv.y = 0 

     if (rv.x > this.canvasInnerWidth) rv.x = this.canvasInnerWidth; 
     if (rv.y > this.canvasInnerHeight) rv.y = this.canvasInnerHeight; 

     return rv; 
    } 

    /*------------------------------- functions called from template -------------------------------*/ 

    private getWidth(): string { 
     return this.width; 
    } 

    private getHeight(): string { 
     return this.height; 
    } 


} 

模板:

<ion-navbar primary *navbar> 
    <ion-title>My title</ion-title> 
</ion-navbar> 
<ion-content> 
    <div #content style="width: 100%; height: 100%;"> 
     <canvas #theCanvas class="canvasStyle" [style.width]="getWidth()" [style.height]="getHeight()" (touchstart)="downEvent($event)" 
      (touchend)="upEvent($event)" (touchmove)="dragEvent($event)"></canvas> 
    </div> 
</ion-content> 

和「canva sStyle「等級:

.canvasStyle{ 
    top: 50%; 
    left: 50%; 
    margin-right: -50%; 
    transform: translate(-50%, -50%); 
    position: absolute; 
    background-color: rgba(0,0,0,0); 
    -webkit-tap-highlight-color:rgba(0,0,0,0); 
} 

任何反饋將不勝感激。

回答

1

繪圖工作不正常,因爲我的畫布沒有正確設置爲paperjs。 「閃爍」似乎是由畫布的大尺寸引起的。

我最終做的是在一個畫布上繪製圖像,然後在另一個較小的畫布上使用paperjs。然後,在保存最終圖像之前,我在畫布畫布上畫了紙畫布。

所以在HTML我有:

<canvas #imageCanvas class="canvasStyle" [style.width]="getWidth()" [style.height]="getHeight()"></canvas> 
<canvas #paperCanvas class="canvasStyle" [style.width]="getWidth()" [style.height]="getHeight()" (touchstart)="downEvent($event)" 
     (touchend)="upEvent($event)" (touchmove)="dragEvent($event)"></canvas> 

而且在我的.ts:

@ViewChild("imageCanvas") imageCanvas: ElementRef; 
@ViewChild("paperCanvas") paperCanvas: ElementRef; 

... 

public ngAfterViewInit(): void { 
    this.ctx = this.imageCanvas.nativeElement.getContext('2d'); 
} 

... 

private setupPaperJS(canvas): void { 

    paper.install(window); 
    paper.setup(this.paperCanvas.nativeElement); 

    this.imageCanvas.nativeElement.width = this.canvasInnerWidth; 
    this.imageCanvas.nativeElement.height = this.canvasInnerHeight; 

    // draw the image 
    this.ctx.drawImage(canvas, 0, 0, canvas.width, canvas.height, 
     0, 0, this.imageCanvas.nativeElement.width, this.imageCanvas.nativeElement.height); 
} 

... 

private combineCanvases() { 
    this.ctx.drawImage(this.paperCanvas.nativeElement, 0, 0, this.paperCanvas.nativeElement.width, this.paperCanvas.nativeElement.height, 
      0, 0, this.imageCanvas.nativeElement.width, this.imageCanvas.nativeElement.height); 
} 

不知道這是最好的方式,但它是一個可行的解決方案。