Hilo/docs/api-zh/code/renderer/CanvasRenderer.js
2018-08-08 15:57:32 +08:00

203 lines
5.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Hilo
* Copyright 2015 alibaba.com
* Licensed under the MIT License
*/
/**
* @class canvas画布渲染器。所有可视对象将渲染在canvas画布上。舞台Stage会根据参数canvas选择不同的渲染器开发者无需直接使用此类。
* @augments Renderer
* @param {Object} properties 创建对象的属性参数。可包含此类所有可写属性。
* @module hilo/renderer/CanvasRenderer
* @requires hilo/core/Class
* @requires hilo/core/Hilo
* @requires hilo/renderer/Renderer
* @property {CanvasRenderingContext2D} context canvas画布的上下文。只读属性。
*/
var CanvasRenderer = Class.create( /** @lends CanvasRenderer.prototype */ {
Extends: Renderer,
constructor: function(properties) {
CanvasRenderer.superclass.constructor.call(this, properties);
this.context = this.canvas.getContext("2d");
},
renderType: 'canvas',
context: null,
/**
* @private
* @see Renderer#startDraw
*/
startDraw: function(target) {
if (target.visible && target.alpha > 0) {
if (target === this.stage) {
this.context.clearRect(0, 0, target.width, target.height);
}
if (target.blendMode !== this.blendMode) {
this.context.globalCompositeOperation = this.blendMode = target.blendMode;
}
this.context.save();
return true;
}
return false;
},
/**
* @private
* @see Renderer#draw
*/
draw: function(target) {
var ctx = this.context,
w = target.width,
h = target.height;
//draw background
var bg = target.background;
if (bg) {
ctx.fillStyle = bg;
ctx.fillRect(0, 0, w, h);
}
//draw image
var drawable = target.drawable,
image = drawable && drawable.image;
if (image) {
var rect = drawable.rect,
sw = rect[2],
sh = rect[3],
offsetX = rect[4],
offsetY = rect[5];
//ie9+浏览器宽高为0时会报错 fixed ie9 bug.
if (!sw || !sh) {
return;
}
if (!w && !h) {
//fix width/height TODO: how to get rid of this?
w = target.width = sw;
h = target.height = sh;
}
//the pivot is the center of frame if has offset, otherwise is (0, 0)
if (offsetX || offsetY) ctx.translate(offsetX - sw * 0.5, offsetY - sh * 0.5);
ctx.drawImage(image, rect[0], rect[1], sw, sh, 0, 0, w, h);
}
},
/**
* @private
* @see Renderer#endDraw
*/
endDraw: function(target) {
this.context.restore();
},
/**
* @private
* @see Renderer#transform
*/
transform: function(target) {
var drawable = target.drawable;
if (drawable && drawable.domElement) {
Hilo.setElementStyleByView(target);
return;
}
var ctx = this.context,
scaleX = target.scaleX,
scaleY = target.scaleY;
if (target === this.stage) {
var style = this.canvas.style,
oldScaleX = target._scaleX,
oldScaleY = target._scaleY,
isStyleChange = false;
if ((!oldScaleX && scaleX != 1) || (oldScaleX && oldScaleX != scaleX)) {
target._scaleX = scaleX;
style.width = scaleX * target.width + "px";
isStyleChange = true;
}
if ((!oldScaleY && scaleY != 1) || (oldScaleY && oldScaleY != scaleY)) {
target._scaleY = scaleY;
style.height = scaleY * target.height + "px";
isStyleChange = true;
}
if (isStyleChange) {
target.updateViewport();
}
} else {
var x = target.x,
y = target.y,
pivotX = target.pivotX,
pivotY = target.pivotY,
rotation = target.rotation % 360,
transform = target.transform,
mask = target.mask;
if (mask) {
mask._render(this);
ctx.clip();
}
//alignment
var align = target.align;
if (align) {
var pos = target.getAlignPosition();
x = pos.x;
y = pos.y;
}
if (transform) {
ctx.transform(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty);
} else {
if (x != 0 || y != 0) ctx.translate(x, y);
if (rotation != 0) ctx.rotate(rotation * Math.PI / 180);
if (scaleX != 1 || scaleY != 1) ctx.scale(scaleX, scaleY);
if (pivotX != 0 || pivotY != 0) ctx.translate(-pivotX, -pivotY);
}
}
if (target.alpha > 0) ctx.globalAlpha *= target.alpha;
},
/**
* @private
* @see Renderer#remove
*/
remove: function(target) {
var drawable = target.drawable;
var elem = drawable && drawable.domElement;
if (elem) {
var parentElem = elem.parentNode;
if (parentElem) {
parentElem.removeChild(elem);
}
}
},
/**
* @private
* @see Renderer#clear
*/
clear: function(x, y, width, height) {
this.context.clearRect(x, y, width, height);
},
/**
* @private
* @see Renderer#resize
*/
resize: function(width, height) {
var canvas = this.canvas;
var stage = this.stage;
var style = canvas.style;
canvas.width = width;
canvas.height = height;
style.width = stage.width * stage.scaleX + 'px';
style.height = stage.height * stage.scaleY + 'px';
}
});