2010-09-07 11 views
39

मुझे आश्चर्य है कि एंड्रॉइड में 9-patch जैसी कुछ है, लेकिन वेब विकास के लिए?वेब विकास के लिए नौ-पैच छवियां

प्रकटीकरण: मुझे वेब विकास के बारे में कोई जानकारी नहीं है, लेकिन मुझे यह जानकर उत्सुकता थी कि यह मौजूद है या नहीं। और 9-पैच शब्द के साथ एक साधारण वेब खोज ने कोई संबंधित परिणाम नहीं लाया, इसलिए मैंने पाया कि इसमें कोई अन्य शब्द है या यह अस्तित्व में नहीं है या व्यापक रूप से पर्याप्त रूप से उपयोग नहीं किया जाता है।

कोई भी जानता है?

+6

इस प्रश्न पूछने के लिए धन्यवाद। यह वही था जो मैंने खोजा था। –

+0

यदि आप jQuery का उपयोग करना चाहते हैं, [यह उत्तर] (http://stackoverflow.com/a/6806707/386738) उपयोगी हो सकता है – Daniel

उत्तर

5

आप अभी भी रुचि मैं वेब के लिए असली नौ पैच छवि समर्थन बनाने के लिए कैनवास का उपयोग करता है एक जावास्क्रिप्ट फ़ाइल बनाया है, तो: यह सीएसएस 3 में border-image के लिए प्रयोग किया जाता है। ओपन सोर्स प्रोजेक्ट यहां पाया जा सकता:

https://github.com/chrislondon/9-Patch-Image-for-Websites

0

ठीक है, मैं रेगिस्तान त्रुटियों मैं ऊपर के लिंक में पाया सही करने के लिए मुसीबत ले लिया।

निनपैथ एंड्रॉइड को जानना एक उपयोगी टूल है जो गतिशील पेंटिंग और पैडिंग की पहचान जोड़ रहा है (जो पिछले प्लूइंग में गायब था)। मैं पूर्ण कार्यक्षमता के लिए एक छोटी स्क्रिप्ट जोड़ सकता हूं।

पुस्तकालय path9.js में निम्न कोड की जगह!

function NinePatchGetStyle(element, style) 
{ 
    if (window.getComputedStyle) 
    { 
     var computedStyle = window.getComputedStyle(element, ""); 
     if (computedStyle === null) 
      return ""; 
     return computedStyle.getPropertyValue(style); 
    } 
    else if (element.currentStyle) 
    { 
     return element.currentStyle[style]; 
    } 
    else 
    { 
     return ""; 
    } 
} 

// Cross browser function to find valid property 
function NinePatchGetSupportedProp(propArray) 
{ 
    var root = document.documentElement; //reference root element of document 
    for (var i = 0; i < propArray.length; i++) 
    { 
     // loop through possible properties 
     if (typeof root.style[propArray[i]] === "string") 
     { 
      //if the property value is a string (versus undefined) 
      return propArray[i]; // return that string 
     } 
    } 
    return false; 
} 


/** 
* 9patch constructer. Sets up cached data and runs initial draw. 
* @param {Dom Element} div El Elemento dom en donde se pinta el ninepath 
* @param {function} callback La funcion que se llamara cuando se termina 
* la carga de la imagen y el pintado del elemento div. 
* @returns {NinePatch} Un objeto nine path 
*/ 
function NinePatch(div,callback) 
{ 
    this.div = div; 
    this.callback =callback; 
    this.padding = {top:0,left:0,right:0,bottom:0}; 
    // Load 9patch from background-image 
    this.bgImage = new Image(); 
    this.bgImage.src = NinePatchGetStyle(this.div, 'background-image').replace(/"/g, "").replace(/url\(|\)$/ig, ""); 
    var este = this; 

    this.bgImage.onload = function() 
    { 
     este.originalBgColor = NinePatchGetStyle(este.div, 'background-color'); 
     este.div.style.background = 'none'; 

     // Create a temporary canvas to get the 9Patch index data. 
     var tempCtx, tempCanvas; 
     tempCanvas = document.createElement('canvas'); 
     tempCanvas.width = este.bgImage.width; 
     tempCanvas.height = este.bgImage.height; 
     tempCtx = tempCanvas.getContext('2d'); 
     tempCtx.drawImage(este.bgImage, 0, 0); 

     // Obteniendo el padding lateral derecho 
     var dataPad = tempCtx.getImageData(este.bgImage.width-1,0,1,este.bgImage.height).data; 
     var padRight = este.getPadBorder(dataPad,este.bgImage.width,este.bgImage.height); 
     este.padding.top = padRight.top; 
     este.padding.bottom = padRight.bottom; 
     dataPad = tempCtx.getImageData(0,este.bgImage.height-1,este.bgImage.width,1).data; 
     var padBottom = este.getPadBorder(dataPad,este.bgImage.width,este.bgImage.height); 

     este.padding.left = padBottom.top; 
     este.padding.right = padBottom.bottom; 

     // Loop over each horizontal pixel and get piece 
     var data = tempCtx.getImageData(0, 0, este.bgImage.width, 1).data; 

     // Use the upper-left corner to get staticColor, use the upper-right corner 
     // to get the repeatColor. 
     var tempLength = data.length - 4; 
     var staticColor = data[0] + ',' + data[1] + ',' + data[2] + ',' + data[3]; 
     var repeatColor = data[tempLength] + ',' + data[tempLength + 1] + ',' + 
       data[tempLength + 2] + ',' + data[tempLength + 3]; 

     este.horizontalPieces = este.getPieces(data, staticColor, repeatColor); 

     // Loop over each horizontal pixel and get piece 
     data = tempCtx.getImageData(0, 0, 1, este.bgImage.height).data; 
     este.verticalPieces = este.getPieces(data, staticColor, repeatColor); 

     // use this.horizontalPieces and this.verticalPieces to generate image 
     este.draw(); 
     este.div.onresize = function() 
     { 
      este.draw(); 
     }; 
     if(callback !== undefined) 
     { 
      if (typeof(callback) === "function") 
       callback(); 
     } 
    }; 
} 

// Stores the HTMLDivElement that's using the 9patch image 
NinePatch.prototype.div = null; 
// Padding 
NinePatch.prototype.padding = null; 
// Get padding 
NinePatch.prototype.callback = null; 
// Stores the original background css color to use later 
NinePatch.prototype.originalBG = null; 
// Stores the pieces used to generate the horizontal layout 
NinePatch.prototype.horizontalPieces = null; 
// Stores the pieces used to generate the vertical layout 
NinePatch.prototype.verticalPieces = null; 
// Stores the 9patch image 
NinePatch.prototype.bgImage = null; 

// Gets the horizontal|vertical pieces based on image data 
NinePatch.prototype.getPieces = function(data, staticColor, repeatColor) 
{ 
    var tempDS, tempPosition, tempWidth, tempColor, tempType; 
    var tempArray = new Array(); 

    tempColor = data[4] + ',' + data[5] + ',' + data[6] + ',' + data[7]; 
    tempDS = (tempColor === staticColor ? 's' : (tempColor === repeatColor ? 'r' : 'd')); 
    tempPosition = 1; 

    for (var i = 4, n = data.length - 4; i < n; i += 4) 
    { 
     tempColor = data[i] + ',' + data[i + 1] + ',' + data[i + 2] + ',' + data[i + 3]; 
     tempType = (tempColor === staticColor ? 's' : (tempColor === repeatColor ? 'r' : 'd')); 
     if (tempDS !== tempType) 
     { 
      // box changed colors 
      tempWidth = (i/4) - tempPosition; 
      tempArray.push(new Array(tempDS, tempPosition, tempWidth)); 

      tempDS = tempType; 
      tempPosition = i/4; 
      tempWidth = 1; 
     } 
    } 

    // push end 
    tempWidth = (i/4) - tempPosition; 
    tempArray.push(new Array(tempDS, tempPosition, tempWidth)); 
    return tempArray; 
}; 

NinePatch.prototype.getPadBorder = function(dataPad,width,height) 
{ 
    var staticRight = dataPad[0] + ',' + dataPad[1] + ',' + dataPad[2] + ',' + dataPad[3]; 
    var pad={top:0,bottom:0}; 

    // Padding para la parte superior 
    for (var i=0;i<dataPad.length;i+=4) 
    { 
     var tempColor = dataPad[i] + ',' + dataPad[i + 1] + ',' + dataPad[i + 2] + ',' + dataPad[i + 3]; 
     if(tempColor !==staticRight) 
      break; 
     pad.top++; 
    } 
    // padding inferior 
    for (var i=dataPad.length-4;i>=0;i-=4) 
    { 
     var tempColor = dataPad[i] + ',' + dataPad[i + 1] + ',' + dataPad[i + 2] + ',' + dataPad[i + 3]; 
     if(tempColor !==staticRight) 
      break; 
     pad.bottom++; 
    } 
    return pad; 
}; 

// Function to draw the background for the given element size. 
NinePatch.prototype.draw = function() 
{ 
    var dCtx, dCanvas, dWidth, dHeight; 

    if(this.horizontalPieces === null) 
     return; 
    dWidth = this.div.offsetWidth; 
    dHeight = this.div.offsetHeight; 

    dCanvas = document.createElement('canvas'); 
    dCtx = dCanvas.getContext('2d'); 

    dCanvas.width = dWidth; 
    dCanvas.height = dHeight; 

    var fillWidth, fillHeight; 

    // Determine the width for the static and dynamic pieces 
    var tempStaticWidth = 0; 
    var tempDynamicCount = 0; 

    for (var i = 0, n = this.horizontalPieces.length; i < n; i++) 
    { 
     if (this.horizontalPieces[i][0] === 's') 
      tempStaticWidth += this.horizontalPieces[i][2]; 
     else 
      tempDynamicCount++; 
    } 

    fillWidth = (dWidth - tempStaticWidth)/tempDynamicCount; 

    // Determine the height for the static and dynamic pieces 
    var tempStaticHeight = 0; 
    tempDynamicCount = 0; 
    for (var i = 0, n = this.verticalPieces.length; i < n; i++) 
    { 
     if (this.verticalPieces[i][0] === 's') 
      tempStaticHeight += this.verticalPieces[i][2]; 
     else 
      tempDynamicCount++; 
    } 

    fillHeight = (dHeight - tempStaticHeight)/tempDynamicCount; 

    // Loop through each of the vertical/horizontal pieces and draw on 
    // the canvas 
    for (var i = 0, m = this.verticalPieces.length; i < m; i++) 
    { 
     for (var j = 0, n = this.horizontalPieces.length; j < n; j++) 
     { 
      var tempFillWidth, tempFillHeight; 

      tempFillWidth = (this.horizontalPieces[j][0] === 'd') ? 
        fillWidth : this.horizontalPieces[j][2]; 
      tempFillHeight = (this.verticalPieces[i][0] === 'd') ? 
        fillHeight : this.verticalPieces[i][2]; 

      // Stretching : 
      if (this.verticalPieces[i][0] !== 'r') { 
       // Stretching is the same function for the static squares 
       // the only difference is the widths/heights are the same. 
       dCtx.drawImage(
         this.bgImage, 
         this.horizontalPieces[j][1], this.verticalPieces[i][1], 
         this.horizontalPieces[j][2], this.verticalPieces[i][2], 
         0, 0, 
         tempFillWidth, tempFillHeight); 
      } else { 
       var tempCanvas = document.createElement('canvas'); 
       tempCanvas.width = this.horizontalPieces[j][2]; 
       tempCanvas.height = this.verticalPieces[i][2]; 

       var tempCtx = tempCanvas.getContext('2d'); 
       tempCtx.drawImage(this.bgImage, 
         this.horizontalPieces[j][1], this.verticalPieces[i][1], 
         this.horizontalPieces[j][2], this.verticalPieces[i][2], 
         0, 0, 
         this.horizontalPieces[j][2], this.verticalPieces[i][2]); 

       var tempPattern = dCtx.createPattern(tempCanvas, 'repeat'); 
       dCtx.fillStyle = tempPattern; 
       dCtx.fillRect(
         0, 0, 
         tempFillWidth, tempFillHeight); 
      } 

      // Shift to next x position 
      dCtx.translate(tempFillWidth, 0); 
     } 

     // shift back to 0 x and down to the next line 
     dCtx.translate(-dWidth, (this.verticalPieces[i][0] === 's' ? this.verticalPieces[i][2] : fillHeight)); 
    } 

    // store the canvas as the div's background 
    var url = dCanvas.toDataURL("image/png"); 
    var tempIMG = new Image(); 

    var _this = this; 
    tempIMG.onload = function(event) 
    { 
     _this.div.style.background = _this.originalBgColor + " url(" + url + ") no-repeat"; 
    }; 
    tempIMG.src = url; 
}; 


The usage is the following: 


    var elemDom = document.getElementById("idDiv"); 
    var background = "border.9.png"; 
    if (background.match(/\.9\.(png|gif)/i)) // Es nine path? 
    { 
     elemDom.style.backgroundRepeat = "no-repeat"; 
     elemDom.style.backgroundPosition = "-1000px -1000px"; 
     elemDom.style.backgroundImage = "url('"+background+"')"; 
     var ninePatch = new NinePatch(elemDom,function() 
     { 
      elemDom.style.paddingLeft = ninePatch.padding.left; 
      elemDom.style.paddingTop = ninePatch.padding.top; 
      elemDom.style.paddingRight = ninePatch.padding.right; 
      elemDom.style.paddingBottom = ninePatch.padding.bottom; 
     }); 
    } 
संबंधित मुद्दे