当前位置: 代码迷 >> 综合 >> Quark-Renderer ---第四篇
  详细解决方案

Quark-Renderer ---第四篇

热度:74   发布时间:2023-11-26 20:17:50.0

2021SC@SDUSC

        这次接着上次的js文件继续分析。在该js文件中还有两个方法没有介绍,一个是resize()方法,另一个是clear()方法。

        对于resize()方法,传入的参数只有两个,一个是宽度width、一个是高度height,对于无法得到canvas实例的,直接返回。当存在canvasInstance的style时,则设置canvasInstance.style的width和height属性。然后将canvas Instance的width和height属性根据宽高和dpr计算得出最后的值。接着判断是否为hiddencanvas,如果不是则返回。如果是的话,则对hiddenCanvas的width、height进行计算,跟canvasInstance计算过程相同。最后判断dpr然后设置scale。

resize(width, height) {//Can NOT get canvas instance in Wechat mini-program.if (!this.canvasInstance) {return;}if (this.canvasInstance.style) {this.canvasInstance.style.width = width + 'px';this.canvasInstance.style.height = height + 'px';}this.canvasInstance.width = width * this.dpr;this.canvasInstance.height = height * this.dpr;if (!this.hiddenCanvas) {return;}this.hiddenCanvas.width = width * this.dpr;this.hiddenCanvas.height = height * this.dpr;if (this.dpr !== 1) {this.hiddenContext.scale(this.dpr, this.dpr);}
}

        最后一个方法是clear()方法,作用是清空改层画布,主要是用来清空整层画布的,便于重画等操作。这个方法在canvas中尤为重要,对于画面的刷新和重画有着重要作用。

        在该方法中,首先对该对象中的值进行赋值操作,主要针对的是一些修改层属性,如motionBlur、lastFrameAlpha、dpr、width、height、ctx等值进行赋值操作。

 clearColor = clearColor || this.clearColor;let haveMotionBLur = this.motionBlur && !clearAll;let lastFrameAlpha = this.lastFrameAlpha;let dpr = this.dpr;let width = 0;let height = 0;let ctx = this.ctx;

        接着进行判断,判断canvasInstance和havaMotionBLur是否为null,如果全都不为null,则对width、height的值进行修改,改成canvas Instance的width、height的值。然后判断hiddencanvas是否为undefined,如果是,则进行创建hiddenCanvas,调用的是之前的createHiddenCanvas()方法。然后对hiddenContext的属性进行赋值,如globalCompositeOperation改为‘copy’,然后hiddenContext调用drawImage()方法,传入参数canvasInstance、以及其他的大小范围参数。

if (haveMotionBLur && this.canvasInstance) {width = this.canvasInstance.width;height = this.canvasInstance.height;if (!this.hiddenCanvas) {this.creatHiddenCanvas();}this.hiddenContext.globalCompositeOperation = 'copy';this.hiddenContext.drawImage(this.canvasInstance, 0, 0, width / dpr, height / dpr);}

        对于drawImage()方法,在lib中的js文件中右相对应的接口,对应不同的参数,在clear中用的是第二个。

interface CanvasDrawImage {drawImage(image: CanvasImageSource, dx: number, dy: number): void;drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
}

        而后调用clearRect()方法,ctx.clearRect(0, 0, this.width, this.height),该方法和drawImage方法一样都有接口进行对应匹配。

        然后对于传入的参数clearColor进行判断,是否存在,是否为透明,如果存在且不为透明,则进行判断clearColor的colorStops属性,如果存在,对在方法中定义的clearColorCradientOrPattern进行赋值,调用style的getGradient函数,该函数在style.js中。接着对clearColor的__canvasGradient进行赋值,等于之前设定的值。而后如果clearColor.image存在,且colorStops不存在,则让clearColorCradientOrPattern等于Pattern.prototype.getCanvasPattern.call(clearColor, ctx),这样就对clearColorCradientOrPattern进行了赋值操作,

if (clearColor && clearColor !== 'transparent') {var clearColorGradientOrPattern; // Gradientif (clearColor.colorStops) {// Cache canvasInstance gradientclearColorGradientOrPattern = clearColor.__canvasGradient || Style.getGradient(ctx, clearColor, {x: 0,y: 0,width: width,height: height});clearColor.__canvasGradient = clearColorGradientOrPattern;} else if (clearColor.image) {// PatternclearColorGradientOrPattern =     Pattern.prototype.getCanvasPattern.call(clearColor, ctx);}ctx.save();ctx.fillStyle = clearColorGradientOrPattern || clearColor;ctx.fillRect(0, 0, width, height);ctx.restore();
}

        最后对ctx进行操作,设置他的fillstyle,填充矩形以及恢复操作。然后该clear方法就结束了。

        ctx.save();ctx.fillStyle = clearColorGradientOrPattern || clearColor;ctx.fillRect(0, 0, width, height);ctx.restore();

        最后对于该Canvas Layer类,返回一个canvas Layer实例,然后导出就完成了。

module.exports = CanvasLayer;