金沙棋牌官方平台

当前位置:金沙棋牌 > 金沙棋牌官方平台 > 图片方面的自适应处理,固定宽度高度按比例自

图片方面的自适应处理,固定宽度高度按比例自

来源:http://www.logblo.com 作者:金沙棋牌 时间:2019-11-06 08:14

基本概念

金沙棋牌官方平台 1

上面就是我们对于 rimage (图片宽高比)、rviewport (容器宽高比) 的定义。

<p>根据这个公式,可以轻松计算出:</p>

加入重定位和重绘制策略

综合以上五种缩放模式,我们可以看到对于 Cover、Fixed-Width、Fixed-Height 模式而言,有存在被裁剪的可能性。特别是 Fixed-Height 模式,对于横屏游戏来说这是比较常用的模式,但是在屏幕较小的时候难免会被裁剪,而且我们是不希望贴边元素被裁剪掉的,譬如位于右上角的音乐图标。而对于 Fixed-Width、Fixed—Height 模式,它们还存在舞台区域需要补充绘制的情况,因此对某些舞台元素来说需要重新设定其渲染大小。

所以,除了基本的缩放适配模式实现之外,为了解决贴边元素不被裁剪以及对一些舞台元素重绘制的需求,我们还需要加入两个策略:重定位和重绘制。

a. 重定位

贴边元素重定位策略的实现原理很简单,对需要重新定位的元素对象额外设置 topleftrightbottom 的自定义属性(当然你可以命名为其他属性名),这样我们就可以在适配的时候根据这些自定义属性以及实际显示的 Canvas 大小进行重新计算位置。

为了保证性能,下面是策略里需要注意的地方:

  1. 在舞台里,并不是所有游戏元素都是需要被重定位的,因此我们只需要创建一个数组记录需要被重定位的元素。
  2. 适当控制重定位次数,我们不需要在每一帧 tick 绘制的时候都进行重定位,只需要在 Canvas 大小改变的时候进行处理。

以下是重定位策略相关的代码:

JavaScript

// halfCutHeight、halfCutWidth是根据适配后的实际Canvas大小计算出来的相对距离 _setSize: function(){ // ... if(self.isPortrait) { // ... self.halfCutWidth = (self.canvasWidth * self.radioY - this.winWidth ) / 2 / self.radioY; self.halfCutHeight = (self.canvasHeight * self.radioX

  • this.winHeight) / 2 / self.radioX; }else { // ... self.halfCutWidth = (self.canvasWidth * self.radioX - this.winWidth ) / 2 / self.radioX; self.halfCutHeight = (self.canvasHeight *金沙棋牌官方平台, self.radioY - this.winHeight) / 2 / self.radioY; } // ... }, // 贴边元素重定位核心处理函数 _adjustPosition: function(item){ var self = this; item && self.adjustPositionArr.push(item); self.adjustPositionArr.map(function(item, index, arr){ (typeof item.top == "number") && (item.y = item.top + self.halfCutHeight >= 0 ? self.halfCutHeight : 0); (typeof item.left == "number") && (item.x = item.left + self.halfCutWidth >= 0 ? self.halfCutWidth : 0); (typeof item.bottom == "number") && (item.y = self.canvasHeight - item.getBounds().height - item.bottom + self.halfCutHeight >= 0 ? self.halfCutHeight : 0); (typeof item.right == "number") && (item.x = self.canvasWidth - item.getBounds().width - item.right - self.halfCutWidth); }); }, // 暴露方法:提供给开发者记录需要重定位的贴边元素 adjustPosition: function(item){ var self = this; self._adjustPosition(item); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// halfCutHeight、halfCutWidth是根据适配后的实际Canvas大小计算出来的相对距离
_setSize: function(){
  // ...
  if(self.isPortrait) {
    // ...
    self.halfCutWidth =  (self.canvasWidth * self.radioY - this.winWidth ) / 2 / self.radioY;
    self.halfCutHeight = (self.canvasHeight * self.radioX - this.winHeight) / 2 / self.radioX;
  }else {
    // ...
    self.halfCutWidth = (self.canvasWidth * self.radioX - this.winWidth ) / 2 / self.radioX;
    self.halfCutHeight = (self.canvasHeight * self.radioY - this.winHeight) / 2 / self.radioY;
  }
  // ...
},
// 贴边元素重定位核心处理函数
_adjustPosition: function(item){
  var self = this;
  item && self.adjustPositionArr.push(item);
  self.adjustPositionArr.map(function(item, index, arr){
    (typeof item.top == "number") && (item.y = item.top + self.halfCutHeight >= 0 ? self.halfCutHeight : 0);
    (typeof item.left == "number") && (item.x =  item.left + self.halfCutWidth >= 0 ? self.halfCutWidth : 0);
    (typeof item.bottom == "number") && (item.y = self.canvasHeight - item.getBounds().height - item.bottom + self.halfCutHeight >= 0 ? self.halfCutHeight : 0);
    (typeof item.right == "number") && (item.x = self.canvasWidth - item.getBounds().width - item.right  - self.halfCutWidth);
  });
},
// 暴露方法:提供给开发者记录需要重定位的贴边元素
adjustPosition: function(item){
  var self = this;
  self._adjustPosition(item);        
}

b. 重绘制

对于一些以舞台区域(gameArea)作为其大小设置的参考标准的元素,在适配时遇到需要补全绘制区域时,舞台区域大小发生变化,相应地,该元素就需要进行重新绘制,这就是重绘制策略的存在意义。

同样地,为了保证性能,重绘制策略也是同样需要保证:

  1. 创建对应的数组记录全显图形对象。
  2. 不在每一帧 tick 时进行重绘制,只在适配的时候重绘制。

以下是重绘制策略的相关代码:

JavaScript

// 全显图形重绘制核心处理函数 _adjustFullSize: function(item){ var self = this; item && self.adjustFullSizeArr.push(item); self.adjustFullSizeArr.map(function(item, index, arr){ item.drawRect(0, 0, self.canvasWidth, self.canvasHeight); }); }, // 暴露方法:提供给开发者记录需要重绘制的全显图形 adjustPosition: function(item){ var self = this; self._adjustPosition(item); }

1
2
3
4
5
6
7
8
9
10
11
12
13
// 全显图形重绘制核心处理函数
_adjustFullSize: function(item){
  var self = this;
  item && self.adjustFullSizeArr.push(item);
  self.adjustFullSizeArr.map(function(item, index, arr){
    item.drawRect(0, 0, self.canvasWidth, self.canvasHeight);
  });
},
// 暴露方法:提供给开发者记录需要重绘制的全显图形
adjustPosition: function(item){
  var self = this;
  self._adjustPosition(item);        
}

至此,Canvas 横屏适配问题才得以完全解决。

这部分内容篇幅较长,笔者简单总结下,一个简单的解决 Canvas 横屏适配问题的方案至少需要包括两点实现:

  • 选用合适的缩放模式
    方案内置五种缩放模式,在实际应用中根据场景不同而采用不同的缩放进行适配。
  • 加入重定位和重绘制策略
    为了保证贴边元素不被裁剪以及舞台元素动态渲染大小以适应舞台区域的动态变化。

最终的整体效果可前往体验地址进行体验,体验时可点击文本元素进行切换模式。另外,整体的实现方案是基于 CreateJS 框架进行实现的,文中的实现方案的代码会托管笔者github上。

 

将图片放进容器

解决 DOM 的横屏适配问题

在移动端,常见的移动端适配方案是 REM 方案,而为了减少 JS 与 CSS 的耦合,笔者团队开发页面时采用的是 VW + REM 方案。(想要了解该方案的同学可详细阅读《利用视口单位实现适配布局》)。

因为页面适配的场景往往是竖屏式的,因此 VW + REM 方案表现得十分完美。但是遇上横屏式,它的缺点就暴露了出来。

 

金沙棋牌官方平台 2

现行的 vw 单位适配方案带来的问题

如上图所示,由于响应断点的限制最大宽度处理,会导致页面两侧留白,当然这可以通过去掉最大宽度限制来解决。而真正的缺点在于,由于 vw 单位的特性,适配换算大小是根据屏幕宽度而言的,因此屏幕宽度越大导致容器、文字会越大,还可能导致 DOM 元素超出屏幕外,且文字过大并不是我们所想要的用户体验。

那么,换成 px 单位的固定布局如何?

但 px 单位的固定布局只适合于部分场景,对于需要内容全屏覆盖的场景(如下图所示),就可能存在这样的不理想的用户体验:绝对定位的元素之间空隙过大,导致布局不美观,又或者空隙过小,导致元素叠放被遮挡。

 

金沙棋牌官方平台 3

px单位固定布局适配方案带来的问题

我们了解到,vw 单位的特点是适配换算大小时是根据屏幕宽度而定的,那么在强制横屏显示时,我们就可以同理转换为屏幕高度来而定,也就是 vw 单位替换成 vh 单位

这样进一步改良之后就会得到满意的适配效果,如下图所示。

 

金沙棋牌官方平台 4

更好的适配解决方案—— vw、vh 单位搭配

具体实现可参考如下 SCSS 代码:

JavaScript

$vw_base: 375; $vw_fontsize: 20; html { font-size: 20px; //不支持vw单位时,回退到px单位 font-size: ($vw_fontsize / $vw_base) * 100vw; } @media screen and (orientation: landscape) { html { font-size: 20px; font-size: ($vw_fontsize / $vw_base) * 100vh; } }

1
2
3
4
5
6
7
8
9
10
11
12
$vw_base: 375;
$vw_fontsize: 20;
html {
  font-size: 20px; //不支持vw单位时,回退到px单位
  font-size: ($vw_fontsize / $vw_base) * 100vw;
}
@media screen and (orientation: landscape) {
  html {
    font-size: 20px;
    font-size: ($vw_fontsize / $vw_base) * 100vh;
  }
}

 

结论

我们考虑rimage < rviewport后加完整了,图片放进容器之后的宽、高如下:

金沙棋牌官方平台 5

这样我们就求到了图片在应用background-size属性之后在容器中实际的宽、高。

}

选用合适的缩放模式

横屏适配的核心是缩放,通过 scale 属性等手法将Canvas缩放至适合屏幕窗口大小。类似于 background-size 属性的表现,缩放适配也可以有很多种模式,或有裁剪或无裁剪,或根据长边缩放或根据短边缩放等等。根据一些常见的实际应用场景,有比较常用的五种缩放模式:Contain、Cover、Fill、Fixed-Width、Fixed-Height。根据游戏的不同的实际场景需求,我们可以选其中一种缩放模式进行适配。

下面,我们逐一解释以上五种缩放模式的定义、实现与其适用的场景。

a. Contain模式

Canvas可以类比为一张图,而图片的适配,我们可以联想到经常用以适配背景图片的属性 background-size ,其属性值包括 containcover

借助 contain 的概念,我们把缩放的其中一种模式称为 Contain 模式。因为在这种模式下,舞台内容(gameArea)会保持宽高比进行缩放适配浏览器可视窗口(window),缩放至其能显示完整的舞台内容。

根据下图推导,我们可以得出在这种缩放模式下的缩放比例(scaleRadio),为浏览器可视窗口与游戏内容的宽度比或高度比之间较小者

 

金沙棋牌官方平台 6

Contain 模式下的缩放比例推导图

根据推导结论,简单代码实现如下:

JavaScript

// Contain模式核心原理函数 CONTAIN: function(){ var self = this; self.radioX = self.radioY = Math.min((self.winWidth / self.designWidth) , (self.winHeight / self.designHeight)); self.canvasWidth = self.designWidth; self.canvasHeight = self.designHeight; }

1
2
3
4
5
6
7
// Contain模式核心原理函数
CONTAIN: function(){
  var self = this;
  self.radioX = self.radioY = Math.min((self.winWidth / self.designWidth) , (self.winHeight / self.designHeight));
  self.canvasWidth = self.designWidth;
  self.canvasHeight = self.designHeight;
}

可以看出,在 Contain 模式下,如果舞台内容宽高比与浏览器可视窗口的宽高比不相等时,舞台内容并没有填满整个浏览器可视窗口,此时就会出现上下或左右两侧会存在留空部分。

对于这种 Contain 模式,会比较适合舞台背景为纯色或者是渐变类型的H5轻互动,舞台内容与窗口的紧邻处得以自然过渡衔接,不会突兀。

b. Cover模式

同样地,借助 cover 的概念把其中一种模式称为 Cover 模式。在这种模式下,舞台内容(gameArea)会保持宽高比进行缩放适配浏览器可视窗口(window),缩放至舞台内容填满窗口。

根据下图推导,我们可以得出在这种缩放模式下的缩放比例(scaleRadio),为浏览器可视窗口与游戏内容的宽度比或高度比之间较大者

 

金沙棋牌官方平台 7

Cover 模式下的缩放比例推导图

根据推导结论,简单代码实现如下:

JavaScript

// Cover模式核心原理函数 COVER: function(){ var self = this; self.radioX = self.radioY = Math.max((self.winWidth / self.designWidth) , (self.winHeight / self.designHeight)); self.canvasWidth = self.designWidth; self.canvasHeight = self.designHeight; }

1
2
3
4
5
6
7
// Cover模式核心原理函数
COVER: function(){
  var self = this;
  self.radioX = self.radioY = Math.max((self.winWidth / self.designWidth) , (self.winHeight / self.designHeight));
  self.canvasWidth = self.designWidth;
  self.canvasHeight = self.designHeight;
}

在 Cover 模式下,如果舞台内容宽高比与浏览器可视窗口的宽高比不相等时,由于舞台内容需要填满整个浏览器可视窗口,此时就会出现上下或者左右两侧被裁剪的情况。

那么,如果能保证游戏场景内的重点显示内容全部显示,被裁剪内容无关紧要时,那么这种 H5 轻互动类型就可以考虑采用 Cover 模式。

怎么做到保证想要重点显示的内容可以不被裁剪呢?这时要谈到一个“安全区域”的概念,指的是绝对不会被裁剪的内容区域,它应该是由最小的屏幕可视窗口(目前应该是 iPhone 4 )与最大的屏幕可视窗口(目前应该是 iPhone 7 Plus)叠加后得出的重叠区域,如下图所示。

 

金沙棋牌官方平台 8

“安全区域”即为红色虚线框内部分

开发者应该在设计阶段与设计师、产品等相关人员进行沟通,告知其不想被裁剪的内容都应该在“安全区域”进行设计布局。

c. Fill模式

Fill 模式,可以类比为 backgrouns-size: 100% 100% 的表现,在这种模式下,不会保持宽高比,舞台内容(gameArea)的宽高分别按照舞台内容与浏览器可视窗口(window)的宽度比与高度比进行缩放,缩放至舞台内容拉伸铺满窗口。

根据下图推导,我们可以得出在这种缩放模式下的缩放比例(scaleRadio),为对于游戏内容的宽应用其与可视窗口的宽度比,而游戏内容的高应用其与可视窗口的高度比

 

金沙棋牌官方平台 9

Fill 模式下的缩放比例推导图

根据推导结论,简单代码实现如下:

JavaScript

// Fill模式核心原理函数 FILL: function(){ var self = this; self.radioX = (self.winWidth / self.stageWidth); self.radioY = (self.winHeight / self.stageHeight); self.canvasWidth = self.designWidth; self.canvasHeight = self.designHeight; }

1
2
3
4
5
6
7
8
// Fill模式核心原理函数
FILL: function(){
  var self = this;
  self.radioX = (self.winWidth / self.stageWidth);
  self.radioY = (self.winHeight / self.stageHeight);
  self.canvasWidth = self.designWidth;
  self.canvasHeight = self.designHeight;
}

这种模式下既不会留空,也不会被裁剪,但是在舞台内容宽高比与浏览器可视窗口的宽高比不相等时,显示的内容会有一定程度的拉伸形变。

这种暴力的处理方式虽然免去了留空和裁剪的烦恼,但是会存在拉伸形变,这就得看是否能够被接受了。

d. Fixed-Width模式

区别于图像,Canvas 是可以进行动态绘制大小的。所以,我们可以考虑根据屏幕窗口大小变化来动态绘制 Canvas。
从保持舞台横向内容不变的角度考虑,我们提出这样的模式:舞台内容(gameArea)等比进行缩放至与浏览器可视窗口的一致的宽度大小,而舞台的高度(Canvas高度)进行重新绘制其高度为浏览器可视窗口的高度,称之为 Fixed-Width 模式。

根据下图推导,我们可以得出在这种缩放模式下的缩放比例(scaleRadio),为浏览器可视窗口与游戏内容的宽度比

 

金沙棋牌官方平台 10

Fixed-Width 模式下的缩放比例推导图

根据推导结论,简单代码实现如下:

JavaScript

// Fixed-Width模式核心原理函数 FIXED_WIDTH: function(){ var self = this; self.radioX = self.radioY = self.winWidth / self.designWidth; self.canvasWidth = self.designWidth; self.canvasHeight = self.winHeight / self.radioY; }

1
2
3
4
5
6
7
// Fixed-Width模式核心原理函数
FIXED_WIDTH: function(){
  var self = this;
  self.radioX = self.radioY = self.winWidth / self.designWidth;
  self.canvasWidth = self.designWidth;
  self.canvasHeight =  self.winHeight / self.radioY;
}

在 Fixed-Width 模式下,无论在什么分辨率下,舞台横向内容保持不变,而纵向高度则会动态裁补,这就会比较适用于那些场戏场景可以纵向拓展的 H5 轻互动类型。

e. Fixed-Height模式

说完 Fixed-Width 模式,换个角度考虑便得出 Fixed-Height 模式,舞台内容(gameArea)等比进行缩放至与浏览器可视窗口的一致的高度大小,而舞台的宽度(Canvas宽度)进行重新绘制其宽度为浏览器可视窗口的宽度。

根据下图推导,我们可以得出在这种缩放模式下的缩放比例(scaleRadio),为浏览器可视窗口与游戏内容的高度比

 

金沙棋牌官方平台 11

Fixed-Height 模式下的缩放比例推导图

根据推导结论,简单代码实现如下:

JavaScript

// Fixed-Height模式核心原理函数 FIXED_HEIGHT: function(){ var self = this; self.radioX = self.radioY= self.winHeight / self.designHeight; self.canvasWidth = self.winWidth / self.radioX; self.canvasHeight = self.designHeight; }

1
2
3
4
5
6
7
// Fixed-Height模式核心原理函数
FIXED_HEIGHT: function(){
  var self = this;
  self.radioX = self.radioY= self.winHeight / self.designHeight;
  self.canvasWidth = self.winWidth / self.radioX;
  self.canvasHeight = self.designHeight;
}

与 Fixed-Width 模式相反,Fixed-Height 模式下,舞台纵向内容保持不变,而横向宽度则会动态裁补。对于这种模式的应用场景应该会比较广泛,譬如常见的跑酷游戏类型H5轻互动。

今天有个客户说网站改版后缩略和大图都有点变形,于是我就去分析了一下原因。主要有如下的问题:
1、缩略图变形那是因为之前的缩略的高宽比例和新改版后的比例不一致,重新上传缩略吧!实在是太难了。
图片的缩小只要按比例缩小就不会变形,拉大肯定会变形的。于是我就想用固定高度的方式去解决这个问题,用JS或
程序实现也很简单,基本算法是: w1/h1=w2/h2 要求得h2的值稍微移下项就行h2=w2*(h1/w1)
要是你使用的是动易系统,那你只需要在标签调用的时候设定宽度而高度为0就可以了,如{$ProductThumb(100,0)}

比例 hidden

现在讨论图片放进容器后的图片与容器的比例关系hidden,这样我们就可以以此关系让图片随着容器的变化而变化。 注意,hidden是一个小于1的比例,至于为什么要这样设定后面有解释。

contain布局为例,rimage > rviewport :

金沙棋牌官方平台 12

而以cover布局为例,rimage > rviewport :

金沙棋牌官方平台 13

以此类推,得到所有情况的 hidden

金沙棋牌官方平台 14

这样可以看到四种可能性,但是别忘了我们在上面可是推导过 w’image 、h’image

所以hidden最终的结果是:

金沙棋牌官方平台 15

可以看出来,hidden就只有两种结果,rimage / rviewportr viewport / rimage,而且这个数是小于1的(这是上面就确定的)。

所以,hidden的计算可以简化为:

金沙棋牌官方平台 16

金沙棋牌官方平台 17

参考资料

《如何打造一个高效适配的H5》
《Cocos2d-JS的屏幕适配方案》
《Cocos2d-JS 多分辨率适配方案》
《Cocos2d-JS 对齐策略》
《Laya引擎-自动横屏适配》
《Phaser-scaleManager对象》
《How to create mobile games for different screen sizes and resolutions》
《Egret-屏幕适配策略》

游戏 H5 适配 横屏

Web开发

感谢您的阅读,本文由 凹凸实验室 版权所有。如若转载,请注明出处:凹凸实验室()

1 赞 3 收藏 1 评论

金沙棋牌官方平台 18

用的CSS代码,测试通过成功。现在贴出来和大家分享下。

后记

你可能想,搞了半天,这到底能干吗?直接用background-size不就好了,为什么还要得到具体的宽、高,得到了伸缩比又能怎么样。 我也想了想,如果只是图片,似乎上面都是废话。但如果是DOM呢?这是不是就是一种布局方式?

我也不知道,知识有时候就是这样。当你需要用到的时候,你才觉得有用。

<p>一般情况之下,我们知道图片的尺寸大小,根据纵横比例,我们可以通过下面的公式计算出内距<code>padding-top</code>或<code>padding-bottom</code>的百分比值:</p>

H5 游戏开发:横屏适配

2017/10/31 · HTML5 · 1 评论 · 横屏, 游戏

原文出处: 凹凸实验室   

对于移动端的轻量级 HTML5 互动小游戏(简称为 H5 轻互动),如果从屏幕呈现模式来划分的话,可以归类为:竖屏式和横屏式。

 

金沙棋牌官方平台 19

HTML5互动小游戏案例截图

平常我们做过的需求里,主要是以竖屏式为主,而横屏式较少。对于竖屏式场景来说,大家的经验会比较丰富,因此,此次主要式探讨下横屏式场景下的一些需要注意的点,特别是怎样去做横屏适配。

对于 H5 轻互动游戏来说,要实现横屏的话,主要是解决两点:
1.无论用户手持方向如何,都需要保证屏幕横向显示。
2.由于屏幕分辨率的多样化,因此就算是横屏下也是需要进行横屏适配,保证画面在所有分辨率下都能够合理适配。

下面,我们针对这两点分别阐述如何解决。

<a href=" src="2.png" width="200px" alt/></a>
</div>
    </form>
</body>
</html>

关于作者:risker

金沙棋牌官方平台 20

2014年大学毕业,现在在北京某互联网公司从事前端开发的工作,近半年主要做移动web开发。微博粉丝太少,求粉。 个人主页 · 我的文章 · 7 ·   

金沙棋牌官方平台 21

金沙棋牌官方平台 22

后话

本文主要的核心在于探讨横屏游戏中的处理点与解决方案,因此如果实现代码方面有任何错漏之处,请大胆地提出纠正吧!又或者读者们有更好的见解之处,也欢迎留言分享噢。

<html xmlns="">
<head runat="server">
    <title></title>
    <style type="text/css">
    .article_content img{
vertical-align: middle;
max-width: 542px;
height: expression_r(this.width >542 ? (542*(this.height/this.width)): true);
width: expression_r(this.width >542 ? 542: true);

CSS Contain 和 Cover 的数学公式

2015/11/01 · CSS · Contain, Cover

本文作者: 伯乐在线 - risker 。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

background-sizecontaincover是怎么用的,大家应该都明白。但是里面也有一些有趣的数学关系。

Flexible Images

强制横屏显示

页面内容显示方向可分为竖排方向和横排方向,如下图所示。

 

金沙棋牌官方平台 23

页面内容显示方式:竖向排版和横向排版

对于竖屏式 H5 轻互动来说,页面会被期望保持竖排方向显示。而如果页面出现横排方向显示的情况,开发者往往会选择利用提示蒙层来进行友好提示,让用户自主保持竖屏体验,如下图所示。

 

金沙棋牌官方平台 24

提示蒙层提醒用户保持竖屏体验

同样地,在横屏式 H5 轻互动游戏中可以采取相同的措施进行简单处理,在页面内容按竖排方向显示时,开发者进行对用户提示其保持横屏体验。

但是,这对用户体验并不友好,因为这对于那些习惯于打开锁定为竖排方向功能(如下图所示)的 iOS 平台用户,或者是关闭屏幕旋转功能(如下图所示)的 Android 平台用户来说,他们需要多一个处理步骤——先关闭竖排方向锁定或是开启屏幕旋转,然后再横向手持设备。

 

金沙棋牌官方平台 25

竖排方向锁定功能(iOS)与屏幕旋转(Android)功能

因此,更好的做法是强制横屏显示,对屏幕 resize 事件进行监听,当判断为竖屏时将整个根容器进行逆时针 CSS3 旋转 90 度即可,代码如下所示。

JavaScript

// 利用 CSS3 旋转 对根容器逆时针旋转 90 度 var detectOrient = function() { var width = document.documentElement.clientWidth, height = document.documentElement.clientHeight, $wrapper = document.getElementById("J_wrapper"), style = ""; if( width >= height ){ // 横屏 style += "width:" + width + "px;"; // 注意旋转后的宽高切换 style += "height:" + height + "px;"; style += "-webkit-transform: rotate(0); transform: rotate(0);"; style += "-webkit-transform-origin: 0 0;"; style += "transform-origin: 0 0;"; } else{ // 竖屏 style += "width:" + height + "px;"; style += "height:" + width + "px;"; style += "-webkit-transform: rotate(90deg); transform: rotate(90deg);"; // 注意旋转中点的处理 style += "-webkit-transform-origin: " + width / 2 + "px " + width / 2 + "px;"; style += "transform-origin: " + width / 2 + "px " + width / 2 + "px;"; } $wrapper.style.cssText = style; } window.onresize = detectOrient; detectOrient();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 利用 CSS3 旋转 对根容器逆时针旋转 90 度
var detectOrient = function() {
  var width = document.documentElement.clientWidth,
      height =  document.documentElement.clientHeight,
      $wrapper =  document.getElementById("J_wrapper"),
      style = "";
  if( width >= height ){ // 横屏
      style += "width:" + width + "px;";  // 注意旋转后的宽高切换
      style += "height:" + height + "px;";
      style += "-webkit-transform: rotate(0); transform: rotate(0);";
      style += "-webkit-transform-origin: 0 0;";
      style += "transform-origin: 0 0;";
  }
  else{ // 竖屏
      style += "width:" + height + "px;";
      style += "height:" + width + "px;";
      style += "-webkit-transform: rotate(90deg); transform: rotate(90deg);";
      // 注意旋转中点的处理
      style += "-webkit-transform-origin: " + width / 2 + "px " + width / 2 + "px;";
      style += "transform-origin: " + width / 2 + "px " + width / 2 + "px;";
  }
  $wrapper.style.cssText = style;
}
window.onresize = detectOrient;
detectOrient();

但是!这里有坑:如果你是采用 CreateJS 框架进行开发,那么就不能通过 CSS3 途径对包含 Canvas 的根容器进行旋转处理,因为旋转后会导致 Canvas 内的舞台元素的事件响应位置错乱。
解决办法是,换成利用 CreateJS 框架内的 Stage 的 rotation 属性对整个舞台旋转处理,代码如下:

JavaScript

if(self.isPortrait) { // 竖屏 // 舞台旋转 self.stage.x = self.canvasHeight; // 注意:x偏移相当于旋转中点处理,更简单 self.stage.rotation = 90; // more... }else { // 横屏 self.stage.x = 0; self.stage.rotation = 0; // more... }

1
2
3
4
5
6
7
8
9
10
if(self.isPortrait) { // 竖屏
  // 舞台旋转
  self.stage.x = self.canvasHeight; // 注意:x偏移相当于旋转中点处理,更简单
  self.stage.rotation = 90;
  // more...
}else { // 横屏
  self.stage.x = 0;
  self.stage.rotation = 0;
  // more...
}

}

三种方法

  • stretch : 把图片的宽高强行设置为容器的宽高

金沙棋牌官方平台 26

注: h’image、w’image、r’image分别为图片改变后的高、宽、宽高比。之后文章这些名词也是这个意思,不再解释。

stretch的方式可想而知后果:

金沙棋牌官方平台 27

那么保持怎样的数学关系才能保证图片放进容器之后不会变形呢? 答案也是明显的:

r’image = rimage

接下来介绍的两种方法就是不会变形的,也就是说能够上面的公式对于它们来说是已知条件。

  • contain : 让图片适应容器,我们把它“装”进容器,同时也会留下空白。就像我们看电影时的”黑边”。

对于contain方法来说,也只有图片放进容器后的高度( h’image )是未知的,我们来算一下:

金沙棋牌官方平台 28

如果不知道contain为什么是这样的建议先看看background-size

  • cover : 也可以让图片“遮”住容器。

contain对应,cover方法要来算一下 w’image

金沙棋牌官方平台 29

}

横屏适配处理

面对移动端多分辨率繁复冗杂的情况,我们对于一般情况下(也就是常见的竖屏式)页面适配处理可以说是烂熟于心,但是切换到横屏式场景下,同样的页面适配方法可以直接应用吗?会不会有什么问题呢?

下面笔者分别从 DOM 和 Canvas 两方面去着手阐述如何做横屏适配处理。

代码页可以实现固定图片的最大宽度,高度按宽度的缩小而缩小。网上找了一下,找到了些思路。最后修改为自己要

宽高比的影响

不知道大家注意到没有,刚才我们推导contain的 h’imagecover的 w’image 时使用的图片的宽高比总是大于容器的宽高比。

这导致了什么?导致了我们推导时使用的 条件3 是不一定正确的。 额,这么说我也有点晕,看图:

金沙棋牌官方平台 30

可以看到,我们只考虑了 rimage > rviewport的情况。

更重要的是,在现代浏览器中发展到可以自动调整图像的比例,可以根据容器的大小缩放或者放大图像,并且图像的宽高比保持不变。
max-width:100%除了可以应用于自适应元素容器上之外也可以应用于固定元素容器上。而且可以应用于视频和其他富媒体上也具有同等的效果。
img, embed, object, video { max-width: 100%; }
不幸的是,max-width属性在IE7以及其以下版本并无法支持。

解决 Canvas 的横屏适配问题

解决 Canvas 的横屏适配问题,目前在实际应用中有两种主流的方案:

  1. 通过做两套Canvas的方案。
  2. 采用缩放的手段进行适配的方案。

两套 Canvas 的方案的做法是,页面包含两个 Canvas 分别用于横竖屏时的相应显示,但是它们的数据是打通的。但是,该方案难免会有局限性,比较适合游戏逻辑数据处理简单、且舞台元素少且居中的场景;

而缩放适配方案做法是,采用的最为常见的缩放手段——利用 CSS3 Transform 的 scale 属性,达到“一种设计尺寸适配多种分辨率屏幕”的目的。

 

金沙棋牌官方平台 31

采用了不同适配方案的案例

在市面上的一些成熟的主流 HTML5 游戏引擎,例如 Cocos2D、Laya、Egret 等等,它们本身就集成了横屏适配的方案。如果你有去了解过,可以发现它们普遍都是采用缩放的理念进行适配。

但是,对于我们常用的 CreateJS、PixiJS 框架来说,它们并没有配套的现成的横屏适配解决方案可以被采用的,尤其是我们如果采用原生 Javascript 去开发一个横屏游戏的时候。

因此,下面我们来研究下如何解决 Canvas 横屏适配问题。

注意:下面文中示例代码都是在 CreateJS 框架的基础上进行编写的。

css代码:
.article_content img{
vertical-align: middle;
max-width: 542px;
height: expression_r(this.width >542 ? (542*(this.height/this.width)): true);
width: expression_r(this.width >542 ? 542: true);

参考文章

CSS – Contain & Cover

我的博客,欢迎订阅

微博粉丝太少,求粉

1 赞 收藏 评论

<p>针对这个问题,Rolf Timmermans 写了一篇文章<a href=" background images with fixed or fluid aspect ratios</a>,文章中介绍了如何解决背景图像的固定和流体的纵横比例。接下来我们一起来看看Rolf Timmermans是如何实现的。</p>
<h3>

网页图片变形解决方法-固定宽度高度按比例自动缩小CSS代码

<pre>

下面的例子是固定了最大的宽度是542px,你可以根据实际情况修改!

Flexible Images

 

<ul><li><a href=" CSS cover images</a></li>
<li><a href=" Images</a></li>
<li><a href=" Fluid Image Techniques for Responsive Site Design</a></li>
<li><a href=" IMAGES</a></li>
<li><a href=" background images with fixed or fluid aspect ratios</a></li>
<li><a href=" To Create Flexible Images And Media In CSS Layouts</a></li>
<li><a href=" ways of making images flexible in responsive web design</a></li>
<li><a href=" Images for Responsive Designs</a></li>
<li><a href=" Images: How they Almost Worked and What We Need</a></li>
<li><a href=" Images)技术简介</a></li>
<li><a href=" Image with vertical centering for Responsive Web Design</a></li>
<li><a href=" Fluid Image Containers with a Little CSS Padding Hack</a></li>
<li><a href=" Flexible Scalable Background Image, Redux</a></li>
<li><a href=" A Responsive Image Solution</a></li>
</ul><h2>

在HTML页面中的代码:
<div class="article_content">
<a href="http://www.wolishop.com/"><img src="<A href='/Article/UploadFiles/201006/20100623002135712.gif"/></a>
</div>

金沙棋牌官方平台 32

2、源图变形是因为在CSS代码里做了处理,之前为了防止图片撑坏DIV的布局用了overfloat:hidden;,后来客户说要

<p><strong>特别声明:</strong>以上方法以及思咱来自于Rolf Timmermans的<a href=" background images with fixed or fluid aspect ratios</a>一文。</p>

 

</code></pre>

求固定下宽度,高度没有设置就按原图片的高度显示。要是宽高没有按比例缩小就会变形。于是我就想是不是用CSS

金沙棋牌官方平台 33

 

从上面的代码中我们可以想像出我们要的效果,figure占整个容器.content宽度的"45.9016393%"
也就是"280px/610px"。虽然整个布局是自适应布局,但图片依旧撑破容器:

自行测试实例:

<p>这种效果我们可以给元素设置一个高度,来减少<code>padding-top</code>或者<code>padding-bottom</code>的百分比值。假设我们的大图尺寸是700像素宽度和267像素高,而我们决定显示的图片尺寸是在300像素宽度和167像素的高度。现在我们需要计算高度<code>height</code>和内距<code>padding-top</code>或<code>padding-bottom</code>的值:</p>

}
    </style>
</head>
<body>
    <form id="form1" runat="server">
<div class="article_content">
<a href=" src="1.png" width="200px" alt/></a>

自适应纵横比例</h3>

<p>假设我们有一张700像素宽和467像素高的图像。当宽度改变时,我们需要维护其纵横向比例是“16:9”。下面有一个示例,我们使用像素为单位,当然也可以使用<code>em</code>为单位,但我们的结构和前面示例一样:</p>

padding-top:66.7142857%; // 467px / 700px = 0.667142857

<p>在保持背景图片的纵横比例,关键之处是是让背景图片垂直居中。而其中主要是基于宽度的百分比来设置内距<code>padding</code>的百分比值。这种技术早前在<a href=";

background-color: hsla(333,50%,60%,.8);

Flexible Images

假设我们有一个两栏自适应的布局,在主内容中应用了一个图片,其结构如下:
<div class="figure"> <div class="inner"> ![](http://upload-images.jianshu.io/upload_images/2244949-f80854741861cd7f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <p class="figcaption">Lo, the robot walks</p> </div> </div>

color: #fff;

<p>如需转载,烦请注明出处:<a href=";

固定纵横比例</h3>

<pre>

Flexible Images

<p>在固定纵横比例的基础之上,做进一步的调整。假设我们在宽屏的PC上显示大的图片,而在移动设备上,我们不想使用相同的纵横比或图像变得太小。当然我们也不想使用完全相同的高度或让图像变得太高。我们更希望当宽度变小时,其高度也变得更小。而我们也把这种称为流体纵横比例。</p>

Flexible Images

<p>覆盖背景图像的纵横比例必须得满足以下几个条件:</p>
<ul><li>呈现一个固定的纵横比例,除非特定的最大尺寸超过图像宽度</li>
<li>支持不同的纵横比例</li>
<li>支持最大高度<code>max-height</code>和最大宽度<code>max-width</code></li>
<li>支持不同的背景图像</li>
<li>背景图像填充整个容器</li>
<li>背景图像居中显示</li>
</ul><p>先来看一个简单的模板:</p>

p {

这并不是我们想要我效果,我们真正想要达到的效果应该是这样的,换句话说理想中要的将是下图的效果:

Flexible Images

Flexible Images

<p>效果如下所示:</p>

background: url("http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg") no-repeat center;

Flexible Images

<p>上图显示了两个维度之间的关系。斜线的坡度对应于内距<code>padding-top</code>或<code>padding-bottom</code>的属性值。开始高度的值代表元素的高度<code>height</code>的属性值。</p>

<p>上面两种方案主要是根据背景图片的纵横比例来实现图像的自适应效果。但在<a href=" href=" CSS cover images</a>一文中提供另一种以纵横比实现图像自适应的效果。</p>

<p>除了上述的几种方案之外,其实还有其他的一些解决方案,比如<a href=" href=" Images)技术简介</a>》一文中就介绍了如何使用“Cookie+Server”、“使用<code>noscript</code>标签创建”等其他方法。<a href=" Shora</a>在《<a href=" Fluid Image Containers with a Little CSS Padding Hack</a>》还介绍了一种老方案——<strong>内距和绝对定位实现图片自适应</strong>。当然除了这些还有其他的。<a href=" Alexander</a>特意为解决响应式设计的图片问题,在《<a href=" A Responsive Image Solution</a>》一文中搜集了很多个JavaScript解决方案。感兴趣的同学,可以仔细研究研究。</p>

<p>对应的样式代码:</p>

方案一:max-width
在介绍响应式设计的文章中,为了解决图片的自适应问题,都会提到使用max-width
。Richard Rutter设计首先提出使用max-width的方案:
img { max-width: 100%; }
在上面的示例基础上,我们为img添加max-width值为“100%”:

<p>上面介绍了使用不同方案来解决图片自适应在Web页面设计中的问题。不管哪种方案,都有自己的优势与不足。抛开JavaScript的解决方案,不管是<code>max-width</code>、<code>background-image</code>还是<code>object-fit</code>都避免不了浏览器的兼容性问题,特别是<code>object-fit</code>尤为突出。在实际应用中,个人更趋向于方案二,因为其可以按照图片纵横向比例显示,不过这种方案比较麻烦的是,需要使用背景图片。</p>

</code></pre>

<p>使用背景图像的方案存在一个问题,不管是固定纵横比例还是流体纵横比例,我们都离不开<code>background-size</code>属性,而此值是CSS3的一个属性,仅有现代浏览器支持。如果要兼容低版本的IE还需要另寻他法。比如说<a href=" href=" href=" Easy Background Resize</a>等插件。<a href=" Bester</a>在<a href=" Flexible Scalable Background Image, Redux</a>一文中也做过这方面的介绍。</p>

<code>padding-top(或padding-bottom) = 467 / 700 = 0.667142857 = 66.7142857%

其他方案</h2>

那接下来,我们观注的就是,如何让我们的效果达到上图所示的效果。

<code><div class="CoverImage FlexEmbed FlexEmbed--3by1"></div>

金沙棋牌官方平台 34

<pre>

<p>使用<code>Object-fit</code>属性有一个受限条件,需要在样式中显示的设置图片的尺寸。然后通过其属性值<code>fill</code>、<code>cover</code>或<code>contain</code>值来控制图像显录的纵横比例。在此并不建议使用,不过当作兴趣爱好,可以深入了解他。如果你对此属性感兴趣,可以阅读《<a href=" Object-fit和Object-position</a>》一文,文中详细介绍了<code>object-fit</code>属性的具体使用。</p>

金沙棋牌官方平台 35

padding: 10px 10px 0;

<p>很显然,这样的效果不理想,不是我们所需要的效果。那有什么方法可以让背景图片根据自身的比例来自适应呢?</p>

background-size: cover;

</code></pre>

<h3>

<p>如此一来,我们可以将前面的示例调整为:</p>
<code>//SCSS
.figure {
margin: .5em;
//背景图像宽度必须宽度为700px
max-width: 700px; //图片的宽度
.inner {

我们可以根据上图所示的公式计算出背景图像纵横比例。基于固定纵横比例的示例之上,将上面的示例修改成流体纵横比例:
<code>.figure {
margin: .5em;
//背景图像的宽度为700px
max-width: 700px;
.inner {
border: 10px solid hsla(333,50%,60%,.8);
border-radius: 10px;
}
.image-wrapper {
background: url("http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg") no-repeat center;
background-size: cover;
height: 92px;
padding-top:25%;
}
p {
background-color: hsla(333,50%,60%,.8);
padding: 10px 10px 0;
color: #fff;
}
}
</code>

方案三:Object-fit</h2>

金沙棋牌官方平台 36

<p><strong>注:由于示例图片尺寸比例不够标准,此处想要表达的意思是:假设原图的比例是4:1(比如背景图片尺寸是800px宽,200px高);自适应后比例为2:1,(背景图片尺寸变为300px的宽和150px的高)。换句话说就是从4:1比例的800<em>200的图片变成比例为2:1的300</em>150的图片。</strong></p>

<p>其效果如下:</p>

.image-wrapper {

总结</h2>

}

Flexible Images

另外一点,在一些浏览器中仅指定图片的宽度,可能会导致浏览器重新处理布局,调整页面的时间周期会增加两到三倍,虽然周期不到一毫秒,但是累积起来,尤其是页面上有很多个这样的元素的时候,还是或多或少会影响页面的性能。为了解决这个问题,可以显式的指定图片的height值为auto
img { max-width: 100%; height: auto; }
方案二:background-image
在响应式设计中实现图片自适应另一种方案可以采用background-image。因为在CSS3有一个background-size
属性可以让我们的背景图片适应容器大小。
先简单的来模拟一个效果,基于上例的基础上,我们将模板结构做一下调整:
<div class="figure"> <div class="inner"> <div class="image-wrapper"></div> <p class="figcaption">Lo, the robot walks</p> </div> </div>
将图片变成背景图片应用于image-wrapper容器之上。
//SCSS .figure { float: right; margin: 0.5em 0; margin-left: 1.9672131%; //12px/610px width: 45.9016393%; // 280px/610 .inner { border: 10px solid hsla(333,50%,60%,.8); border-radius: 10px; } .image-wrapper { width: 100%; background: url("http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg") no-repeat center; min-height: 100px; background-size: cover; } p { background-color: hsla(333,50%,60%,.8); padding: 10px 10px 0; color: #fff; } }
可以清楚的看到,在<code>.image-wrapper</code>应用了背景图片,并且配合了<code>background-size:cover</code>一起使用:
<code>.image-wrapper {
width: 100%;
background: url("http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg") no-repeat center;
min-height: 100px;
background-size: cover;
}
</code>
不过这里让你为难的是,在<code>.image-wrapper</code>容器中没有任何内容,以至于无法撑开容器的高度,因此想正常的显示出图片,那必须给容器指一个准确的高度或一个最小高度,言外之意,我们宽度可以自适应,但比例不会根据图片的宽高比例来定,另外图片会进行截取,如示例所示:

<p>在响应式设计中,布局可以根据设备调整宽度。就算是用百分比调整宽度,也会自动按比例调整元素的高度。换句话说,其宽度比例保持不变来调整大小。如果我们要使背景图片达到同等的效果,我们就必须得知道如何保持任何HTML元素的纵横比例。</p>

这是一个很常见的结构,其效果就是一张图片,图片下面有一个简单的文本描述。在整个效果中,针对figure
内元素写了一点样式
//SCSS .figure { float: right; margin: 0.5em 0; margin-left: 1.9672131%; //12px/610px width: 45.9016393%; // 280px/610px .inner { border: 10px solid hsla(333,50%,60%,.8); border-radius: 10px; } img { vertical-align: top; } p { background-color: hsla(333,50%,60%,.8); padding: 10px 10px 0; color: #fff; } }

金沙棋牌官方平台 37

<h2>

border: 10px solid hsla(333,50%,60%,.8);

Flexible Images

金沙棋牌官方平台 38

<h2>

}

扩展阅读</h2>

</code></pre>

金沙棋牌官方平台 39

<p>效果如下:</p>

<h2>

border-radius: 10px;

<code>padding-top或padding-bottom = (背景图片高度 / 背景图片宽度) * 100%

<pre>
<code><div class="figure">
<div class="inner">
<div class="image-wrapper"></div>
<p class="figcaption">Lo, the robot walks</p>
</div>
</div>
</code></pre>

Flexible Images

<p><a href=";

<code>//SCSS
.CoverImage {
border: 5px solid green;
margin: .5em auto;
background: url("http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg") no-repeat center;
background-size: cover;
max-height: 700px;
max-width: 467px;
}
.FlexEmbed {
display: block;
overflow: hidden;
position: relative;
&:before {
content: "";
display: block;
width: 100%;
}
}
.FlexEmbed--3by1:before {
padding-bottom: 33.33333%;
}
.FlexEmbed--2by1:before {
padding-bottom: 50%;
}
.FlexEmbed--16by9:before {
padding-bottom: 56.25%;
}
.FlexEmbed--4by3:before {
padding-bottom: 75%;
}
</code>

<p>他的特征同样是依靠覆盖背景图像的纵横比例来实现,假设我们的比例为:</p>

<h2>模板</h2>

<p>当然,大家可以根据自己的项目需求去考虑使用什么方案解决问题,在这里只是自己一点总结。如果您对自适应图片的处理有更好的解决经验,欢迎一起分享。</p>

金沙棋牌官方平台 40

本文由金沙棋牌发布于金沙棋牌官方平台,转载请注明出处:图片方面的自适应处理,固定宽度高度按比例自

关键词: