循环播放一张图片,如果图片大小小于屏幕,继续使用该图片进行填充

场景:

  需要做出来的效果差不多如标题所述,即如果屏幕宽度为720,而图片的宽度只有150,现在需要从中间开始,往两边移动该图片,

我们现在以往右边移动为例,如果往右移动了150,此时绘制了一整个完整图形,继续移动,此时不仅要从中间绘制出新的图形,已经绘制的完整图形也得向右移动。进而达到动画的效果。

分析:

  为了达到上面的效果,最开始想到的是使用动画,但是发现:

  1)如果选择平移动画,只能移动图片,不会保留之前图片走过的路径,这样的话背景图就不会出现连续的情况,而只是有单张图,并不是这里想要的。

  2)选择多张图片循环播放,向gif那样,可如此一来使用到的图片资源过多,也不予考虑。

解决方案:

  最后决定自己实现一个view,通过在onDraw中不断的从中间向两边绘制一个图片,并平移已绘制的图形,进而达到想要的效果。

  这个看起来有些像游戏中的实现,即一个人物在屏幕中走,其实它一直都是在屏幕中央,只是背景图在不断的往左边绘制。

  

  如图所示。

  目前来看思路还是挺明确的,但是在实现的过程中,还是有一些情况要考虑清楚,这里做个简单的分析。

  1)图片从中间一点点绘制出来,这里需要一个偏移量xOffset,同时移动还有速度,所以得有个变量speed

  2)图片在屏幕中的显示存在两种情况:显示完全,显示不完全。

    i)针对显示不完全的情况,我们需要根据Bitmap的createBitmap来创建新的bitmap并将其绘制出来。

      那么显示不完全的图形的宽度是多少呢?明显的,中间新绘制出来的图形宽度为xOffset,最右边不完整图形的宽度为sourceWidth-超出屏幕的宽度。

      既然要以xOffset为createBitmap的参数来构建新的bitmap,那么xOffset得有个最大值xOffsetLimit,这里得对xOffset的值做个限定【1,xOffsetLimit】,

      每当xOffset+speed>xOffsetLimit时,都得重置xOffset为1.

      此时xOffsetLimit=sourceWidth。

      但是!!

      如果sourceWidth>parentWidth时,xOffset只需限定到parentWidth,即xOffsetLimit=parentWidth。所以xOffsetLimit得取图片和区域宽度中较小的那个。

    ii)显示完全的情况,我们要考虑,整个区域(我们这里以半个屏幕为例),最多能绘制几个完整图形?

      此时很自然的,我们会想到,最多能绘制多少,那就parentWidth(区域宽度)/ sourceWidth(完整图形宽度)= maxCompleteNum(最大完整图形个数)

      但是!!

      同时我们也得考虑到,由于屏幕是在不断移动中的,可能在某一刻,绘制的完整图形个数是maxCompleteNum(如上图,为2),

      但是继续右移时,最右边的完整图形超出了屏幕,而中间新绘制出来的图形却还没有达到完整,此时屏幕中实际存在的完整图形只有1个!!

      所以,这里我们还需要一个变量,记录此时此刻在屏幕中所能绘制的完整图形个数completeNumBeforeOut。

   3)通过以上分析,我们知道屏幕中最多出现maxCompleteNum个完整图形,某个时刻绘制的完整图形个数应为completeNumBeforeOut。但是屏幕一直在绘制,我们怎么知道completeNumBeforeOut的值?

      此时,我们得先有个变量drawnNum,即从开始到某个时刻,已经绘制的完整图形的个数。每当xOffset加完speed,都会去判断是否超过了xOffsetLimit,如果超过了,在将xOffset置回1的同时,也会让drawnNum加1.

      但由于最多只能绘制maxCompleteNum个完整图形,所以当drawnNum加完1之后,还得将其限制在【0,maxCompleteNum】。

      由于drawnNum是从开始到现在所绘制的完整图形个数,所以它是一直递加直到最大值,那么当前这个时候,到底有几个完整图形显示在屏幕中?

      此时得用循环来判断了。如果xOffset+ i*sourceWidth <= screenWidth(屏幕宽度),表示还没有超过屏幕,即i对应的这个图形还是完整的,所以此时completeNumBeforeOut可加1.其中i的范围是【1,drawnNum】

   4)此外,我们还得记录当前这个时刻,绘制的图形是否已经超出了屏幕,即该有个变量hasExist。

      hasExist = xOffset+drawnNum*sourceWidth > screenWidth。这个应该不难理解了,需要注意的是,这里表达式及上一个表达式,都是假定xOffset是相对屏幕中间而言的,事实上计算式得加上screenWidth/2。

   5)目前位置,变量差不多都齐全了,我们开始进行绘制。

      先判断当前屏幕中是否有完整图形存在,即completeNumBeforeOut,如果大于0,则在相应位置绘制出相应的个数。

      接着将从中间新移动出的图形绘制出来,其宽度为xOffset。

      最后,得用到上面的hasExist进行判断。即如果hasExist为false,那么还没有超出屏幕,则不进行操作。

        如果hasExist为true,即已经超过了屏幕了,那么绘制最右边的图形。

  6)以上流程下来,看起来挺不错的,事实上还存在一个挺大的问题。

    由于xOffset每次都是加speed,所以当xOffset达到最大值的时候,往往不会等于xOffsetLimit,而是

      maxOffsetCount(xOffset超过limit前可添加speed的最大次数) = (xOffsetLimit - 1) / 2;

      maxOffset(xOffset的最大值) = 1+ maxOffsetCount * speed;

      在以上判断是否超出屏幕的判断总,我们是假定xOffset + drawnNum * sourceWidth > screenWidth一定会满足条件。

      但事实上,由于drawnNum存在最大值maxCompleteNum,而xOffset也存在最大值maxOffset,存在这样一种情况,即maxOffset + maxCompleteNum * sourceWidth任然还差一些,不能超过screenWidth。

      (以sourceWidth=147,parentWidth=720为例,此时最多可绘制1个完整图形,最大偏移量为136,而要超出屏幕xoffset必须要达到139.5 。因为136在加上一个speed(15)就又还原了,所以此时不可能会超出屏幕)

      为了避免以上情况,当判断maxOffset + maxCompleteNum * sourceWidth < screenWidth时,得使maxCompleteNum加上1!!

之后附上源码

时间: 2024-11-09 10:37:39

循环播放一张图片,如果图片大小小于屏幕,继续使用该图片进行填充的相关文章

在ASP.NET MVC下实现单个图片上传, 客户端服务端双重限制图片大小和格式, 服务端裁剪图片

在"MVC文件图片ajax上传轻量级解决方案,使用客户端JSAjaxFileUploader插件01-单文件上传"一文中,使用JSAjaxFileUploader这款插件实现了单文件上传,在chrome, firefox下运行良好,但在某些版本的IE浏览器(比如IE8,IE9)下却无法正常运行,这可能是因为JSAjaxFileUploader插件在编写时没有考虑到某些低版本IE浏览器导致的.本篇,就在ASP.NET MVC4下实现单个图片上传,具体功能包括: 1.在客户端选择图片,并限

微信小程序富文本中的图片大小超出屏幕

这个问题我在小程序社区中提的,后来有个帮我回答了这个问题,我试了一下可以. 解决办法是过滤富文本内容,给图片标签添加一个样式,限制图片的最大宽度. replace(/\<img/gi,   '<img class="rich-img" ' ); 就可以了 rich-text   .rich-img { width: 100% ; height: auto ; } 原文地址:https://www.cnblogs.com/fangyinghua/p/9264425.html

Css Sprite 图片等比缩放图片大小

图片大小80*40,即每张图片大小40*40,如何以20*20显示图片?1. 首先看下如何以40*40显示第二张图片: 正常显示css代码 .sprite { background-image: url(spritesheet.png); background-repeat: no-repeat; display: block; } .sprite-circle { width: 40px; height: 40px; background-position: -40px 0; } 正常显示ht

使用javascript实现图片上下切换效果并且实现顺序循环播放

<!doctype html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"&g

UI基础--使用UIScrollView、UIPageControl、NSTimer实现图片循环播放

实现思路: 1.创建一个UIScrollView,这里设置为宽度300,高度130,通过storyboard创建: 2.使用代码在UIScrollView中添加ImageView,横向放入多张ImageView: 3.设置UIScrollView的contentSize为所有图片的宽度总和: 4.要保证UIScrollView的宽度等于一张ImageView的宽度,才能正确分页: 5.添加UIPageControl控件,设置当前页数和总页数: 6.添加NSTimer实现自动循环: UIPageC

JS可控制的图片自动循环播放查看效果

JS可控制的图片自动循环播放查看效果 <html> <head> <title>JS可控制的图片自动循环播放查看效果丨芯晴网页特效丨CsrCode.Cn</title> </head> <body> <SCRIPT LANGUAGE="JavaScript"> <!-- Begin var rotate_delay = 5000; // delay in milliseconds (5000 =

在WPF中显示GIF图片并实现循环播放

WPF中有一个MediaElement媒体控件,可以来播放媒体,同时也可以显示GIF图片.但看到网上有些人说用MediaElement不能加载作为资源或内嵌的资源的GIF图片,我猜他们一定是在前台用XAML来使用MediaElement,而我在这里打算后台使用MediaElement,直接使用自定义控件,继承自MediaElement. 1 public class ImageGifView : MediaElement 2 { 3 public ImageGifView() 4 { 5 thi

C# 压缩图片到指定宽度,假如图片小于指定宽度 判断图片大小是否大于指定大小(KB) 如果大于则压缩图片质量 宽高不变

class Program { static void Main(string[] args) {//G:\zhyue\backup\projects\Test\ConsoleApplication1\img //var url = "http://seo.jrechina.com/houselist/"; //var res = WebRequestExt.GetData(url); string img_url = @"D:\Documents\Pictures\壁纸\1

iOS scrollview循环播放加缩放

前些日子一直在研究3d的框架没有时间写博客,不过最后需求改了,也没研究出个啥.这段时间出了新的需求,需要循环播放图片,并且滑动的时候中间的图片有缩放的效果.刚开始想在网上搜索,不过并没有找到合适的demo,没办法只能写个了. 首先说下思路,做这个效果需要解决三个问题. 第一个问题,如何控制每次滑动的距离.iOS中好像并没有设置scrollview每次滑动的距离吧.设置其画框的大小和pageenable的时候已经决定了其每次滑动的距离.但是需求要显示三张图片啊,中间大图,两边的图片只显示一部分.也