2013-10-10 196 views
1

有關縱橫比的快速問題令我有點瘋狂。我的畫布元素的固定尺寸爲250x250(比例爲1:1)。然而,我正在繪製到畫布上的圖像可能是任何尺寸/比例。很顯然,如果我試圖強制圖像爲250x250,它看起來會失真。如何在畫布對象內保持圖像的縱橫比

我試圖讓它尊重寬高比,但我現在在畫布對象中出現了一個奇怪的重疊,我的懸停效果因爲它而有點偏離。我的數學要麼是錯誤的,要麼我將它應用到圖像/畫布上是錯誤的。任何幫助或建議將不勝感激。

http://jsfiddle.net/Ra9KQ/1/

var NameSpace = NameSpace || {}; 

NameSpace.Pixelator = (function() { 

    var _cache = { 
     'wrapper' : null, 
     'canvas' : null, 
     'ctx'  : null, 
     'img'  : new Image() 
    }, 

    _config = { 
     'canvasWidth'  : 250, 
     'canvasHeight'  : 250, 
     'isPlaying'  : false, 
     'distortMin'  : 3, 
     'distortMax'  : 100, 
     'distortValue'  : 100, // matches distortMax by default 
     'initDistortValue' : 3, 
     'speed'   : 2.5, 
     'delta'   : 2.5, // delta (+/- step), matches speed by default 
     'animation'  : null, 
     'origImgWidth'  : null, 
     'origImgHeight' : null, 
     'imgHeightRatio' : null, 
     'imgWidthRatio' : null, 
     'newImgWidth'  : null, 
     'newImgHeight'  : null 
    }, 

    _init = function _init() { 

     _setupCache(); 
     _setupCanvas(); 
     _setupImage(); 

    }, 

    _setupCache = function _setupCache() { 

     _cache.wrapper = $('#dummy-wrapper'); 
     _cache.canvas = document.getElementById('dummy-canvas'); 
     _cache.ctx = _cache.canvas.getContext('2d'); 

    }, 

    _setupCanvas = function _setupCanvas() { 

     _cache.ctx.mozImageSmoothingEnabled = false; 
     _cache.ctx.webkitImageSmoothingEnabled = false; 
     _cache.ctx.imageSmoothingEnabled = false; 

    }, 

    _setupImage = function _setupImage() { 

     $(_cache.img).on('load', function() { 

      _adjustImageScale(); 
      _pixelate(); 
      _assignEvents(); 

     }); 

     _cache.img.src = _cache.canvas.getAttribute('data-src'); 

    }, 

    _adjustImageScale = function _adjustImageScale() { 

     var scaledHeight, 
      scaledWidth; 

     _config.origImgWidth = _cache.img.width; 
     _config.origImgHeight = _cache.img.height; 
     _config.imgHeightRatio = _config.origImgHeight/_config.origImgWidth; 
     _config.imgWidthRatio = _config.origImgWidth/_config.origImgHeight; 

     scaledHeight = Math.round(250 * _config.imgHeightRatio); 
     scaledWidth = Math.round(250 * _config.imgWidthRatio); 

     if (scaledHeight < 250) { 

      _config.newImgHeight = 250; 
      _config.newImgWidth = Math.round(_config.newImgHeight * _config.imgWidthRatio); 

     } else if (scaledWidth < 250) { 

      _config.newImgWidth = 250; 
      _config.newImgHeight = Math.round(_config.newImgWidth * _config.imgHeightRatio); 

     } 

    }, 

    _assignEvents = function _assignEvents() { 

     _cache.wrapper.on('mouseenter', _mouseEnterHandler); 
     _cache.wrapper.on('mouseleave', _mouseLeaveHandler); 

    }, 

    _mouseEnterHandler = function _mouseEnterHandler(e) { 

     _config.delta = -_config.speed; 

     if (_config.isPlaying === false) { 
      _config.isPlaying = true; 
      _animate(); 
     } 

    }, 

    _mouseLeaveHandler = function _mouseLeaveHandler(e) { 

     _config.delta = _config.speed; 

     if (_config.isPlaying === false) { 
      _config.isPlaying = true; 
      _animate(); 
     } 

    }, 

    _pixelate = function _pixelate(val) { 

     var size = val ? val * 0.01 : 1, 
      w = Math.ceil(_config.newImgWidth * size), 
      h = Math.ceil(_config.newImgHeight * size); 

     _cache.ctx.drawImage(_cache.img, 0, 0, w, h); 

     _cache.ctx.drawImage(_cache.canvas, 0, 0, w, h, 0, 0, _config.canvasWidth, _config.canvasHeight); 

    }, 

    _animate = function _animate() { 

     // increase/decrese with delta set by mouse over/out 
     _config.distortValue += _config.delta; 

     if (_config.distortValue >= _config.distortMax || _config.distortValue <= _config.distortMin) { 

      _config.isPlaying = false; 
      cancelAnimationFrame(_config.animation); 
      return; 

     } else { 

      // pixelate 
      _pixelate(_config.distortValue); 
      _config.animation = requestAnimationFrame(_animate); 

     } 

    }; 

    return { 
     init: _init 
    }; 

})(); 

NameSpace.Pixelator.init(); 

回答

2

你的代碼示例w*h區域,這是不方,進_config.canvasWidth*_config.canvasHeight區域,該區域是方形的。以下更改似乎修復您的示例對我來說:

// old code 
_cache.ctx.drawImage(_cache.canvas, 0, 0, w, h, 0, 0, _config.canvasWidth, _config.canvasHeight); 
// new code 
_cache.ctx.drawImage(_cache.canvas, 0, 0, w, h, 0, 0, _config.newImgWidth, _config.newImgHeight); 
+0

DOH!這正是我需要另一雙眼睛的原因。非常感謝! – brandongray

相關問題