      1 /**
      2  * Hilo
      3  * Copyright 2015 alibaba.com
      4  * Licensed under the MIT License
      5  */
      6
      7 /**
      8  * @class DomRenderer The DomRenderer, all the visual object is drawing using dom element.The stage will create different renderer depend on the canvas and renderType properties, developer need not use this class directly.
      9  * @augments Renderer
     10  * @param {Object} properties The properties to create a renderer, contains all writeable props of this class.
     11  * @module hilo/renderer/DOMRenderer
     12  * @requires hilo/core/Class
     13  * @requires hilo/core/Hilo
     14  * @requires hilo/renderer/Renderer
     15  * @requires hilo/view/Drawable
     16  */
     17 var DOMRenderer = (function(){
     18
     19 return Class.create({
     20     Extends: Renderer,
     21     constructor: function(properties){
     22         DOMRenderer.superclass.constructor.call(this, properties);
     23     },
     24     renderType:'dom',
     25     /**
     26      * @private
     27      * @see Renderer#startDraw
     28      */
     29     startDraw: function(target){
     30         //prepare drawable
     31         var drawable = (target.drawable = target.drawable || new Drawable());
     32         drawable.domElement = drawable.domElement || createDOMDrawable(target, drawable);
     33         return true;
     34     },
     35
     36     /**
     37      * @private
     38      * @see Renderer#draw
     39      */
     40     draw: function(target){
     41         var parent = target.parent,
     42             targetElem = target.drawable.domElement,
     43             currentParent = targetElem.parentNode;
     44
     45         if(parent){
     46             var parentElem = parent.drawable.domElement;
     47             if(parentElem != currentParent){
     48                 parentElem.appendChild(targetElem);
     49             }
     50             //fix image load bug
     51             if(!target.width && !target.height){
     52                 var rect = target.drawable.rect;
     53                 if(rect && (rect[2] || rect[3])){
     54                     target.width = rect[2];
     55                     target.height = rect[3];
     56                 }
     57             }
     58         }
     59         else if(target === this.stage && !currentParent){
     60             targetElem.style.overflow = 'hidden';
     61             this.canvas.appendChild(targetElem);
     62         }
     63     },
     64
     65     /**
     66      * @private
     67      * @see Renderer#transform
     68      */
     69     transform: function(target){
     70         Hilo.setElementStyleByView(target);
     71         if(target === this.stage){
     72             var style = this.canvas.style,
     73                 oldScaleX = target._scaleX,
     74                 oldScaleY = target._scaleY,
     75                 scaleX = target.scaleX,
     76                 scaleY = target.scaleY;
     77
     78             if((!oldScaleX && scaleX != 1) || (oldScaleX && oldScaleX != scaleX)){
     79                 target._scaleX = scaleX;
     80                 style.width = scaleX * target.width + "px";
     81             }
     82             if((!oldScaleY && scaleY != 1) || (oldScaleY && oldScaleY != scaleY)){
     83                 target._scaleY = scaleY;
     84                 style.height = scaleY * target.height + "px";
     85             }
     86         }
     87     },
     88
     89     /**
     90      * @private
     91      * @see Renderer#remove
     92      */
     93     remove: function(target){
     94         var drawable = target.drawable;
     95         var elem = drawable && drawable.domElement;
     96
     97         if(elem){
     98             var parentElem = elem.parentNode;
     99             if(parentElem){
    100                 parentElem.removeChild(elem);
    101             }
    102         }
    103     },
    104
    105     /**
    106      * @private
    107      * @see Renderer#hide
    108      */
    109     hide: function(target){
    110         var elem = target.drawable && target.drawable.domElement;
    111         if(elem) elem.style.display = 'none';
    112     },
    113
    114     /**
    115      * @private
    116      * @see Renderer#resize
    117      */
    118     resize: function(width, height){
    119         var style = this.canvas.style;
    120         style.width = width + 'px';
    121         style.height = height + 'px';
    122         if(style.position != "absolute") {
    123           style.position = "relative";
    124         }
    125     }
    126 });
    127
    128 /**
    129  * Create a dom element, you can set the tagName property，such as canvas and div.
    130  * @param {Object} view A visual object.
    131  * @param {Object} imageObj The image object to render, include the image propertiy and other associated properties, such as rect.
    132  * @return {HTMLElement} The created dom element.
    133  * @private
    134  */
    135 function createDOMDrawable(view, imageObj){
    136     var tag = view.tagName || "div",
    137         img = imageObj.image,
    138         w = view.width || (img && img.width),
    139         h =  view.height || (img && img.height),
    140         elem = Hilo.createElement(tag), style = elem.style;
    141
    142     if(view.id) elem.id = view.id;
    143     style.position = "absolute";
    144     style.left = (view.left || 0) + "px";
    145     style.top = (view.top || 0) + "px";
    146     style.width = w + "px";
    147     style.height = h + "px";
    148
    149     if(tag == "canvas"){
    150         elem.width = w;
    151         elem.height = h;
    152         if(img){
    153             var ctx = elem.getContext("2d");
    154             var rect = imageObj.rect || [0, 0, w, h];
    155             ctx.drawImage(img, rect[0], rect[1], rect[2], rect[3],
    156                          (view.x || 0), (view.y || 0),
    157                          (view.width || rect[2]),
    158                          (view.height || rect[3]));
    159         }
    160     }else{
    161         style.opacity = view.alpha != undefined ? view.alpha : 1;
    162         if(view === this.stage || view.clipChildren) style.overflow = "hidden";
    163         if(img && img.src){
    164             style.backgroundImage = "url(" + img.src + ")";
    165             var bgX = view.rectX || 0, bgY = view.rectY || 0;
    166             style.backgroundPosition = (-bgX) + "px " + (-bgY) + "px";
    167         }
    168     }
    169     return elem;
    170 }
    171
    172 })();
    173