Canvas 爱奥尼亚2与纸JS-闪烁的画布和白色的盒子
我对Ionic 2(beta.7)和Paper JS有一个问题:当我开始绘图时,画布左上角会出现一个白色框。请参见示例图片。绘制时画布也会闪烁 关于我正在尝试做的事情的简短描述: 使用设备摄像头拍摄照片,并在画布上绘制该图像,然后允许用户在图像上绘制 知道我做错了什么吗?或者关于如何解决这个问题的建议 我的代码: 拍照(使用ionic native): DrawPicturePage(pictureDraw.ts):Canvas 爱奥尼亚2与纸JS-闪烁的画布和白色的盒子,canvas,ionic2,paperjs,Canvas,Ionic2,Paperjs,我对Ionic 2(beta.7)和Paper JS有一个问题:当我开始绘图时,画布左上角会出现一个白色框。请参见示例图片。绘制时画布也会闪烁 关于我正在尝试做的事情的简短描述: 使用设备摄像头拍摄照片,并在画布上绘制该图像,然后允许用户在图像上绘制 知道我做错了什么吗?或者关于如何解决这个问题的建议 我的代码: 拍照(使用ionic native): DrawPicturePage(pictureDraw.ts): 如果有任何反馈,我们将不胜感激。由于我的画布不适合paperjs,因此图纸无法
如果有任何反馈,我们将不胜感激。由于我的画布不适合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>
不知道这是否是最好的方法,但这是一个有效的解决方案
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>
.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);
}
<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>
@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);
}