菜单

CSS或JS实现gif动态图片的终止同播音

2018年11月15日 - CSS/CSS3

CSS或JS实现gif动态图片的停和播音

2015/12/06 · CSS,
JavaScript ·
gif

初稿出处:
张鑫旭   

一、屋外:寒风吹,雪花飘;屋内:空调吹,代码飘

上午出买菜,正好下雨了,还掺杂在冰珠子。鄙人大意,穿的是同等宗帅气但单薄的黄色大衣,立马冻成了中华田园犬。原本计划去钓鱼的,科科,作罢,上午在家看CCTV5
骑士队vs鹈鹕队,下午补动漫码代码做文章,好生惬意。

图片 1

对于习惯性刷微博之本人,总时不时会看到类似下面的玩乐:

测测你与小白(白百何)有哪共同点,戳开动图,最先看清的歌词是呀?ie浏览器的同校可以按esc键(或截屏),据说在谁词暂停,哪个词即是您哦!图片 2

图片 3

OK,
这里出现一个浏览器特性,就是经ESC快捷键,暂停gif的广播。据说FireFox浏览器以前也发生,后来被波及少了,根据@紫云妃的说教是:

是这般的,Firefox原来的展现是:在页面load事件形成,同时x按钮变成刷新按钮后,esc仍然发生几乎独作用,中断时正发送的ajax,websocket,停止gif,apng动画的播放.但这些功能最小众了,影响了普通用户的以,可能不小心按了esc,结果ajax断了,网页出错了.所以Firefox20修改成:网页加载成功后,esc键完全失去效.

而,这种隐晦的不过如会影响正常职能的有些技巧肯定是力不从心落实真正意义上的gif动态图片的息同播音的。一是兼容性,二是功能性,三凡是移动端没有ESC键。

从而,如果我们相见需要可以随时随地停止gif动态图片播放的需求的时段,就待摸索另外的出路。好,寒冬里之暖身结束,开始上正题~~

1、播放多张静态图片

/// 1、原生播放动态图片(轮流播放多张静态图片)
- (void)animationImages {
    //创建UIImageView,添加到界面
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 200, 300)];
    [self.view addSubview:imageView];
    imageView.center = self.view.center;
    //创建一个数组,数组中按顺序添加要播放的图片(图片为静态的图片)
    NSMutableArray *imgArray = [NSMutableArray array];
    for (int i=1; i<23; i++) {
        UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"pickView%02d.png",i]];
        [imgArray addObject:image];
    }
    //把存有UIImage的数组赋给动画图片数组
    imageView.animationImages = imgArray;
    //设置执行一次完整动画的时长
    imageView.animationDuration = 6*0.15;
    //动画重复次数 (0为重复播放)
    imageView.animationRepeatCount = 0;
    //开始播放动画
    [imageView startAnimating];
}

    //停止播放动画  
    - (void)stopAnimating;
    //判断是否正在执行动画  
    - (BOOL)isAnimating;

其次、gif图片自己可控前提下之方法同样:多img资源支配处理

假如说,我们期待暂停的gif是上下一心(开发人员)传上去的,不是用户可无限制上传不可控的gif.
我们得以这样处理,就是准备2套图纸,一个凡gif动态图片,还有一个是一味发同样幅的有序的图。然后采用JS来回切换`的src`值为这有限摆图地址便哼了。

以此办法很简单,我就是无加大实例了。

img.src=”animate.gif”; // 或者表现的凡 img.src=”static.png”;

1
2
3
img.src="animate.gif";
// 或者呈现的是
img.src="static.png";

是主意极其酷的长就是是兼容性强,所有浏览器都得兑现停止效果。然而,这种措施有只局限,就是,暂停时候呈现的图片永远是一样摆放。基本上可以说是停止,而不是暂停。

那么起没发生啊方法好真正意义上的间歇也?还确确实实来!

2、UIWebView心想事成动画效果

/// 2、播放动态图片(gif,UIWebView实现),内存占用39M
- (void)animationImagesWithUIWebView {
    //创建一个webView,添加到界面
    UIWebView *web = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 300)];
    [self.view addSubview:web];

    //得到图片的路径
    NSString *path = [[NSBundle mainBundle] pathForResource:@"pickView使用" ofType:@"gif"];
    //将图片转为NSData
    NSData *gifData = [NSData dataWithContentsOfFile:path];
    //自动调整尺寸
    web.scalesPageToFit = YES;
    //禁止滚动
    web.scrollView.scrollEnabled = NO;
    //设置透明效果
    web.backgroundColor = [UIColor clearColor];
    web.opaque = 0;
    //加载数据
    [web loadData:gifData MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
}

其三、gif图片自己可控前提下的章程二:CSS3 animation控制

为即是咱们看来底gif效果并无是一个着实的gif图片,而是使用CSS3的animation属性控制形成的逐帧动态图表效果。我搜了下,@DO1路人乙产生篇稿子“css3-animation制作逐帧动画”专门介绍了这种技能。说通过了便animation控制Sprites图片的background-position值模拟gif效果。

例如,新版twitter的Like的功效,貌似就是产生应用该技术:
图片 4

采用CSS3
animation实现类gif效果的好处在吃,图片可以无损,且我们好充分轻松地决定图动画的中断与播放,使用的是:animation-play-state: paused;夫宣称。

乃可以狠狠地点击这里:使CSS3
animation实现gif动图的间歇与播放demo

点击demo页面的中断按钮,您会发现,直接就终止住了,如下截图示意,截自IE10浏览器:
图片 5

还点击,就会见在刹车画面后持续播放了。从而实现了咱们针对动画图片的纯正控制力量。

这个道看起来完美,但是,1. IE10+等支持CSS3 animation的浏览器才行;2.
无限要命之问题是图需要是协调主宰,如果想操纵用户上传的着实意义的gif图片,只能……望洋兴叹……………………吗?

3、YYImage实现

/// 3、播放动态图片(gif,YYKit实现),内存占用30M
- (void)animationImagesWithYYImage {
    // YYImage
    YYImage *image = [YYImage imageNamed:@"pickView使用"];
    YYAnimatedImageView *imageView = [[YYAnimatedImageView alloc] initWithImage:image];
    [self.view addSubview:imageView];
}

季、自己无法控制的gif图片的已和广播

如若说,页面及用户上传了头gif图片,哎呀,闪瞎了自之中国田园眼,我如果全部间断,肿么办?如果后台同学没有对准gif进行静态处理,此时,只能依赖前端小伙伴,有啊法啊?

发一个。HTML5
canvas可以读取图片信息,绘制当前图。于是可以兑现图片马赛克,模糊,色值过滤等众多图纸特效。我们这边并非那么复杂,只要读取我们的图,重绘下就是足以。

卿可以狠狠地点击这里:使用JS和canvas实现gif动图的停止和播音demo

点击按钮,然后:
图片 6

图片 7

哪些利用?
本身本着HTMLImageElement原型进行了扩大,增加了stop()play()星星只方式,如下:

if (‘getContext’ in document.createElement(‘canvas’)) {
HTMLImageElement.prototype.play = function() { if (this.storeCanvas) {
// 移除存储的canvas
this.storeCanvas.parentElement.removeChild(this.storeCanvas);
this.storeCanvas = null; // 透明度还原 image.style.opacity = ”; } if
(this.storeUrl) { this.src = this.storeUrl; } };
HTMLImageElement.prototype.stop = function() { var canvas =
document.createElement(‘canvas’); // 尺寸 var width = this.width, height
= this.height; if (width & height) { // 存储之前的地方 if
(!this.storeUrl) { this.storeUrl = this.src; } // canvas大小
canvas.width = width; canvas.height = height; // 绘制图片帧(第一轴)
canvas.getContext(‘2d’).drawImage(this, 0, 0, width, height); //
重置当前图 try { this.src = canvas.toDataURL(“image/gif”); } catch(e)
{ // 跨域 this.removeAttribute(‘src’); // 载入canvas元素
canvas.style.position = ‘absolute’; // 前面插入图片
this.parentElement.insertBefore(canvas, this); // 隐藏原图
this.style.opacity = ‘0’; // 存储canvas this.storeCanvas = canvas; } }
}; }

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
if (‘getContext’ in document.createElement(‘canvas’)) {
    HTMLImageElement.prototype.play = function() {
        if (this.storeCanvas) {
            // 移除存储的canvas
            this.storeCanvas.parentElement.removeChild(this.storeCanvas);
            this.storeCanvas = null;
            // 透明度还原
            image.style.opacity = ”;
        }
        if (this.storeUrl) {
            this.src = this.storeUrl;    
        }
    };
    HTMLImageElement.prototype.stop = function() {
        var canvas = document.createElement(‘canvas’);
        // 尺寸
        var width = this.width, height = this.height;
        if (width & height) {
            // 存储之前的地址
            if (!this.storeUrl) {
                this.storeUrl = this.src;
            }
            // canvas大小
            canvas.width = width;
            canvas.height = height;
            // 绘制图片帧(第一帧)
            canvas.getContext(‘2d’).drawImage(this, 0, 0, width, height);
            // 重置当前图片
            try {
                this.src = canvas.toDataURL("image/gif");
            } catch(e) {
                // 跨域
                this.removeAttribute(‘src’);
                // 载入canvas元素
                canvas.style.position = ‘absolute’;
                // 前面插入图片
                this.parentElement.insertBefore(canvas, this);
                // 隐藏原图
                this.style.opacity = ‘0’;
                // 存储canvas
                this.storeCanvas = canvas;
            }
        }
    };
}

世家如果在页面中自己之JS文件中复制上面的代码,然后便可一直:

var image = document.getElementsByTagName(“img”)[0]; // 停止gif图片
image.stop(); // 播放gif图片 image.play();

1
2
3
4
5
var image = document.getElementsByTagName("img")[0];
// 停止gif图片
image.stop();
// 播放gif图片
image.play();

//zxx:
上面代码并未详细测试,以及可能的心得问题(IE闪动)没有切实可行处理(影响原理示意),若一旦实在应用,需要好更微调完美下。

不足

  1. IE9+支持。IE7/IE8不支持canvas没搞头。
    2.
    只好停止gif,不能够真正含义之中断。因为canvas获得的gif图片信息为率先轴的信息,后面的一般获取不顶。要惦记实现暂停,而休是止,还待更加研究,如果你产生措施,非常欢迎分享。

4、YYImage其他方法

/// 内存占用,YYImage 重写的imageNamed和原生的内存占用差别不大
- (void)YYImageTest2 {
    // 循环500次测试
    for (NSInteger i = 0;  i < 500; i ++ ) {

//        UIImage *image2 = [UIImage imageNamed:@"pickView01"];
//        UIImageView *imageView3 = [[UIImageView alloc] initWithImage:image2];
//        [self.view addSubview:imageView3];

        YYImage *image = [YYImage imageNamed:@"1"];
        UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
        [self.view addSubview:imageView];
    }
}

/// 内存占用,YYImage 重写的imageWithData会对内存进行优化,降低内存占用
- (void)YYImageTest1 {
    // 循环100次测试
    for (NSInteger i = 0;  i < 100; i ++ ) {

        UIImage *image2 = [UIImage imageNamed:@"1"];
        NSData *data = UIImagePNGRepresentation(image2);
//        UIImage *image3 = [UIImage imageWithData:data scale:1]; // 原始方法加载的图片内存中没情况,会一直累加,大概68M
        YYImage *image3 = [YYImage imageWithData:data scale:1];// 每次for循环结束都会回收内存,大概30M,区别很明显
        UIImageView *imageView3 = [[UIImageView alloc] initWithImage:image3];
        [self.view addSubview:imageView3];
    }
}

/// iOS 信号量机制使用
- (void)seamaphore  {
    int data = 3;
    __block int mainData = 0;
    __block dispatch_semaphore_t sem = dispatch_semaphore_create(0);

    dispatch_queue_t queue = dispatch_queue_create("StudyBlocks", NULL);

    dispatch_async(queue, ^(void) {
        int sum = 0;
        for(int i = 0; i < 444445; i++)
        {
            sum += data;

            NSLog(@" >> Sum: %d", sum);
        }
        // 添加信号量
        dispatch_semaphore_signal(sem);
    });
    // 等待信号量
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    for(int j=0;j<5;j++)
    {
        mainData++;
        NSLog(@">> Main Data: %d",mainData);
    }
}

五、结束语

是胡不是霍,是霍躲不过!哈哈!
图片 8
点这个gif也是demo示意gif强力候选。后来相同琢磨,看我文章的尚是住房男多,腐女少,所以,你明白的……
图片 9

——我是多年不见的低调的分隔线—–

正文gif比较多,如果你是运动装备查看本文,会发现,怎么我的电池怎么越来越薄了!不是为天冷冻小了,而是gif比较耗电。所以,从之角度讲,我们实在有必要在移动端默认停止这些gif的播报,用户点击重新播。一来省流量,二来省电。

若没有静态图片资源支持,那不妨试试文章出现的组成部分方法,有胸得记得来这边反映哈!
图片 10

末段,本文的点子还是出通病的,自己吗不曾在事实上项目受到动用过。因此,假如阅读本文的您:

  1. 发出更全面的gif暂停与播音方式;
  2. 发现文中方法有不足以及疏漏;

且好希望可以不吝赐教!

感阅读!周末风和日丽!

 

1 赞 6 收藏
评论

图片 11

5、YYAnimatedImage

/// 3、播放动态图片(gif,YYKit实现),30M
- (void)animationImagesWithYYImage {
    // YYImage
    YYImage *image = [YYImage imageNamed:@"pickView使用"];
    _imageView = [[YYAnimatedImageView alloc] initWithImage:image];
    _imageView.autoPlayAnimatedImage = NO;
    [self.view addSubview:_imageView];
}

// 控制
- (void)btnClicked:(UIButton *)btn  {
    switch (btn.tag) {
        case 1: // play
        {
            [_imageView startAnimating];
        }
            break;
        case 2: // pause
        {

        }
            break;
        case 3: // stop
        {
            [_imageView stopAnimating];
        }
            break;

        default:
            break;
    }
}

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图