mirror of
https://github.com/hiloteam/Hilo.git
synced 2025-12-08 20:35:59 +00:00
203 lines
5.9 KiB
JavaScript
203 lines
5.9 KiB
JavaScript
/**
|
||
* 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';
|
||
}
|
||
|
||
}); |