澳门新葡萄京官网注册 4

澳门新葡萄京官网注册CSS3动画:流彩文字效果+图片模糊效果+边框伸展效果实现

用灵动标签调用文章的时候,如果没有特殊设置,每条文章的显示样式是一样的。有些人会追求“多彩”的外观,比如设置第三和第六条为红色或者加下划线等等,那么要怎么实现呢?

早在iOS8时期,苹果就给我们提供了IB_DESIGNABLE 和
IBInspectable,让我们可以在xib中直接设置预览UIView的子类的某些属性。
之前由于项目是纯代码写的,所以一直没用到它们。正好这次的项目要用storyboard来实现,所以准备将一些自定义控件进行修改,让它们可以在xib中进行预览,以减少代码量和增加开发效率。
接下来,我们自定义一个包含文字、图片、角标的按钮控件(这种控件很常见吧,通常是上面图片下面文字,然后图片上还可能有角标)来试试这个功能。

前言

首先第一步,先布局html代码如下:

<div class="wrap">
    <img src="images/1.jpg" class="blur"/>
    <div class="text-gradient ">天赐神功</div>
    <div class="border"></div>
</div>

上面一看第一个图片img 就是实现图片模糊效果的DOM元素,text-gradient实现的是流彩文字效果的DOM元素,border实现的是边框伸展效果的DOM元素

想一想样式该咋写呢,根据这个布局,我们先来实现图片模糊效果。

比如调用16条,第8条和第16条采用其它样式,与其它14条样式不同。

1.最基础的功能

首先,用纯代码实现一个自定义的view,效果如下图:

澳门新葡萄京官网注册 1

效果图

代码比较简单,就不上代码了。

图片模糊效果

图片模糊效果要用到的是css3的filter属性,想详细了解可以点击《CSS3 Filter详解(改变模糊度 亮度
透明度等方法)》。

先写下wrap的样式:

.wrap{
    position: relative;
    width:300px;
    height:225px;
    text-align: center;
}

.blur的样式如下:

.wrap .blur{
    position: absolute;
    top:0;
    left:0;
    width:300px;
    height:225px;
    z-index:1;
}
.wrap:hover img.blur{
    transition: all .5s ease;
    filter: url(blur.svg#blur); /* FireFox, Chrome, Opera */
    -webkit-filter: blur(10px); /* Chrome, Opera */
    -moz-filter: blur(10px);
    -ms-filter: blur(10px); 
    filter: blur(10px); 
    filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius=10, MakeShadow=false); /*IE6~IE9 */
}

我们逐步来分析下这个代码:

首先一般的CSS3 blur滤镜实现代码如下:

.blur {    
    -webkit-filter: blur(10px); /* Chrome, Opera */
       -moz-filter: blur(10px);
        -ms-filter: blur(10px);    
            filter: blur(10px);    
}

SVG滤镜实现:

不管倒腾什么方法,搞一个代码如下,且全名为blur.svg的SVG文件:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" 
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns:ev="http://www.w3.org/2001/xml-events"     
     baseProfile="full">     
    <defs>
        <filter id="blur">
            <feGaussianBlur stdDeviation="10" />
        </filter>
    </defs>
</svg>

上面defs标签的代码就是添加的滤镜代码。

如下CSS调用代码:

filter: url(blur.svg#blur); /* FireFox, Chrome, Opera */

然后,效果就出来了。如果你手上的浏览器是FireFox25-就能看到效果。

IE10以及IE11以及以后的IE11+都是支持SVG的滤镜的,但是,此demo在这些浏览器下是无效的,为何?

好像因为其不支持直接在CSS使用使用filter: url的写法,其实,要想实现IE10,
IE11下的模糊效果,也是可以,就是适用性差了点,图片要写入SVG代码,类似下面:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" 
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns:ev="http://www.w3.org/2001/xml-events"     
     baseProfile="full">
     <defs>
        <filter id="blur">
            <feGaussianBlur stdDeviation="10" />
        </filter>
    </defs>
    <image xlink:href="mm1.jpg" x="0" y="0" height="191" width="265" filter="url(#blur)" />
</svg>

然后,SVG作为背景图片载入:

.blur {
    background-image: url(blur.svg);
}

这样就可以了。

IE6?-IE9浏览器可以借助IE filter模糊滤镜实现,如下CSS:

filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius=10, MakeShadow=false); 

所以最终综合代码:

.blur {    
    filter: url(blur.svg#blur); /* FireFox, Chrome, Opera */

    -webkit-filter: blur(10px); /* Chrome, Opera */
       -moz-filter: blur(10px);
        -ms-filter: blur(10px);    
            filter: blur(10px);

    filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius=10, MakeShadow=false); /* IE6~IE9 */
}

如果还想详细了解可点击《小tip:
使用CSS将图片转换成模糊(毛玻璃)效果》

代码如下:

2.添加IB_DESIGNABLE 和 IBInspectable关键字

流彩文字效果

先上css代码:

.wrap:hover .text-gradient { 
    position: relative;
    z-index:2;
    display: inline-block;
    color: black;
    font-size: 30px;
    background-image: -webkit-linear-gradient(left, #147B96, #E6D205 25%, #147B96 50%, #E6D205 75%, #147B96);
    -webkit-text-fill-color: transparent;
    -webkit-background-clip: text;
    -webkit-background-size: 200% 100%;
    -webkit-animation: masked-animation 4s infinite linear;
 }
 @-webkit-keyframes masked-animation {
     0% { background-position: 0 0;}
     100% { background-position: -100% 0;}
 }

说明:

  1. 将渐变色设置为文字所在盒的背景色:background-image: linear-gradient(...)
  2. 取文字的形状与背景(长方形)的交集:-webkit-background-clip: text
  3. 删除覆盖在得到交集之上的原文字形状:-webkit-text-fill-color: transparent

background-clip 属性规定背景的绘制区域。

语法:

background-clip: border-box|padding-box|content-box;

值对应于:背景被裁剪到边框盒,内边距框,内容框。
这里用到的text只适用于chrome浏览器。

在经过上述步骤后得到了渐变色填充文字的效果,但实则呈现的是经过裁剪之后的背景,故要实现色彩的流动,则需要背景进行循环地流动,则可使用CSS3
animation循环改变background-position可破之,但在动画效果上有两坑需要注意:

  • background: linear-gradient(...)是多个属性的简写,在@keyframes中修改某项的值请使用具体的属性,否则若使用简写则会覆盖之前的设置。
  • 初始设置背景时需要设置background-size-x>100%。让背景图片大小水平方向扩大一倍,这样background-position才有移动与变化的空间。

可参考文章:《小tip:CSS3下的渐变文字效果实现》

div class=”must”[e:loop={3,16,0,0}]?phpif($bqno==8||$bqno==16){echo ‘li style=”margin-right:0px;”’;}else{echo ‘li’;}?h1 class=”app_img”a href=”?=$bqsr[titleurl]?” title=”?=$bqsr[title]?” span/spanimg src=”?=$bqr[titlepic]?$bqr[titlepic]:’[!---news.url--]e/data/images/notimg.gif’?” alt=”?=$bqsr[title]?” width=”74″ height=”74″ //a/h1h2a href=”?=$bqsr[titleurl]?” title=”?=$bqsr[title]?”?=esub($bqr[title],6,”)?/a/h2/li[/e:loop]/div

首先,在类的前面加上IB_DESIGNABLE关键字

#import <UIKit/UIKit.h>
IB_DESIGNABLE
@interface  XXX : UIView
@end

边框伸展效果

实现边框伸展效果总代码:

.border{
    position: absolute;
    width:300px;
    height:225px;
    z-index:2;
    top:0;
    left:0;
}
 .border::before, .border::after {
     content:" ";
     display: block;
     position: absolute;
     width: 0;
     height: 0; 
     box-sizing: border-box;
     transition-property: height,width,left,top;
     transition-duration: 0.5s;
     transition-timing-function: ease-in;
     z-index:2;
 }
 .border::before {
     height: 100%;
     left: 50%;
 }
 .wrap:hover > .border::before {
     left: 0;
     width: 100%;
     border: 6px solid #000;
     border-left-color: transparent;
     border-right-color: transparent;
 }
 .border::after {
     width: 100%;
     top: 50%;
 }
 .wrap:hover > .border::after {
     height: 100%;
     top: 0;
     border: 4px solid #000;
     border-top-color: transparent;
     border-bottom-color: transparent;
 }

主要通过border:6px solid
#000这个属性,当width和height都设置为100%时,把左右或上下的border设置为transparent就可以实现::after和::before拼装成长方形,两边都是从中间扩展,所以最初left和top设置为50%;最后需要注意
transition-property: height,width,left,top;的设置。

最终效果如图所示:

澳门新葡萄京官网注册 2

百度网盘可下载demo运行查看,下载请点击《CSS3动画:流彩文字效果+图片模糊效果+边框伸展效果实现》

表示:第8条和第16条为,而其它14条是,li后面没有了style=”margin-right:0px;”样式。

然后,考虑哪些属性是可以在xib中设置的

需要注意的是,在xib中能够显示的属性只有
Boolean、Number、String、Localized String、
Point、Size、Rect、Range、Color、Image
几种,其他属性包括自定义的枚举,即便加了IBInspectable在xib中也是不会显示的
1.view的圆角

@property (nonatomic,assign) IBInspectable CGFloat cornerRadius;   //圆角

2.图片的Image

@property (nonatomic,copy) IBInspectable UIImage * image;  //图片
@property (nonatomic,assign) IBInspectable CGSize imageSize;  //图片大小

3.标题文字

@property (nonatomic,copy) IBInspectable NSString * title;  //标题

4.角标文字

//角标文字(如果为nil或者空字符串,则隐藏角标)
@property (nonatomic,copy) IBInspectable NSString * badge; 

添加完IBInspectable关键字后,就可以在xib中看到这些属性了

澳门新葡萄京官网注册 3

属性

试着修改一下值,发现并没有什么变化。因为还没有写实现的代码。
一般情况下,当属性值在xib中被修改时,会调用属性的setter方法,以及view的drawRect:方法,所以我们需要在里面实现对view的绘制代码。

同样,这么一个功能可以扩展出很多大家想要的效果,具体的还是需要大家的探讨和摸索。

需要注意的是,xib绘制时,并不会调用init方法,所以如果要添加子控件的话,是要在setter或drawRect:进行创建后,再修改对应属性效果。

因此,将几个子控件的初始化方法独立成getview的方法如下

#pragma mark - getViews
- (UIImageView *)getImageView{
    if (_imageView == nil) {
        self.imageView = ({
            UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectZero];
            imageView.clipsToBounds = YES;
            [self addSubview:imageView];
            imageView;
        });
    }
    return _imageView;
}

- (UILabel *)getTitleLabel{
    if (_titleLabel == nil) {
        self.titleLabel = ({
            UILabel * label = [[UILabel alloc]initWithFrame:CGRectZero];
            label.textColor = [UIColor blackColor];
            label.textAlignment = NSTextAlignmentCenter;
            label.numberOfLines = 2;
            label.font = [UIFont systemFontOfSize:13];
            [self addSubview:label];
            label;
        });
    }
    return _titleLabel;
}

- (UILabel *)getBadgeLabel{
    if (_badgeLabel == nil) {
        self.badgeLabel = ({
            UILabel * label = [[UILabel alloc]initWithFrame:CGRectZero];
            label.textColor = [UIColor whiteColor];
            label.clipsToBounds = YES;
            label.textAlignment = NSTextAlignmentCenter;
            label.font = [UIFont systemFontOfSize:8];
            label.backgroundColor = [UIColor redColor];
            [self addSubview:label];
            label.hidden = YES;
            label;
        });
    }
    return _badgeLabel;
}

然后,在setter方法中调用getview的方法设置属性

#pragma mark - setter
//设置view的圆角
-(void)setCornerRadius:(CGFloat)cornerRadius{
    _cornerRadius = cornerRadius;
    self.layer.cornerRadius = cornerRadius;
    self.layer.masksToBounds = cornerRadius > 0?true:false;
}
//设置标题文字
-(void)setTitle:(NSString *)title{
    _title = title;
    [self getTitleLabel].text = title;
    [[self getTitleLabel] sizeToFit];
    //设置label的文字时,需要手动调用刷新界面的方法,不然会出现布局乱的bug
    [self reloadView];
}
//设置图片
-(void)setImage:(UIImage *)image{
    _image = image;
    [self getImageView].image = image;
}
//设置角标
-(void)setBadge:(NSString *)badge{
    _badge = badge;
    [self getBadgeLabel].text = badge;
    if (_badge==nil) {
        _badgeLabel.hidden = YES;
        return;
    }
    _badgeLabel.hidden = NO;
    //设置label的文字时,需要手动调用刷新界面的方法,不然会出现布局乱的bug,原因不明
    [self reloadView];
}

这里,将绘制view的方法独立出来

- (void)reloadView{
    [self layoutBadgeView];
    [self layoutImageAndTitle];
}

-(void)layoutBadgeView{
//绘制圆角的角标
   float _badgeRadius = 5;
    _badgeLabel.text = _badge;
    [_badgeLabel sizeToFit];
    float minheight = _badgeRadius * 2;
    float width = CGRectGetWidth(_badgeLabel.frame) + minheight;
    float heigh = CGRectGetHeight(_badgeLabel.frame) > minheight ? CGRectGetHeight(_badgeLabel.frame):minheight;
    _badgeLabel.frame = CGRectMake(0, 0, width, heigh);
    _badgeLabel.layer.cornerRadius = heigh/2;
}

- (void)layoutImageAndTitle{
  //调整标题和图片的位置
    CGRect rect = self.bounds;
    float _alignPadding = 5;
    float height = CGRectGetHeight(_titleLabel.frame) + _alignPadding + _imageSize.height;
    _imageView.frame = CGRectMake((rect.size.width - _imageSize.width)/2,(rect.size.height - height)/2,_imageSize.width, _imageSize.height);
    _titleLabel.frame = CGRectMake(0, CGRectGetMaxY(_imageView.frame) + _alignPadding, rect.size.width , CGRectGetHeight(_titleLabel.frame));
    _badgeLabel.frame = CGRectMake(CGRectGetMaxX(_imageView.frame), CGRectGetMinY(_imageView.frame), CGRectGetWidth(_badgeLabel.frame), CGRectGetHeight(_badgeLabel.frame));
}

#pragma mark - DrawRect
- (void)drawRect:(CGRect)rect {
    [self reloadView];
    //调整层级顺序
    [self bringSubviewToFront:_titleLabel];
    [self bringSubviewToFront:_badgeLabel];
}

以上,一个很基础的控件就完成了。
接下来,还需要对它进行一些扩展,让它能够有更好的适应性。包括:
1.设置图片圆角、背景色、填充模式
2.设置角标样式(圆角和数字)
3.设置标题字体
4.设置图片与文字的位置关系

具体代码在GZCAlignButton
效果如下:

澳门新葡萄京官网注册 4

效果图

总结:
优点:对某些经常用到的控件来说,这个功能很是方便,能够提高效率。
缺点:对一些常用属性如Font等不支持,有时候渲染会与实际有所误差;而且实时预览仅对控件本身和父类的代码有效,如果有使用导入其他头文件里的宏定义方法影响到绘制的,会造成无法预览。

参考文章:
http://www.cocoachina.com/ios/20150227/11202.html
http://www.jianshu.com/p/e4accdbfd841
http://blog.csdn.net/lotheve/article/details/49230219

更新一个扩展实例:

要调用某个标题分类的文章,实现第一条为图片头条,其他为标题列表。一般情况下,我们会分开来调用,图片归图片,文字归文字,但是这样不仅不方便,而且也因为标题的重复而影响美观。这时候上面的原理就可以实现了。

下面是代码:

[e:loop={'chanye',4,18,0,'ttid=22'}]?if($bqno==1){?div class=”topic_now”div class=”tit”h3本期话题/h3/divdiv class=”con”div class=”huati”a href=”?=$bqsr[titleurl]?” target=”_blank” title=”?=$bqr[title]?”img src=”?=$bqr[titlepic]?” alt=”?=$bqr[title]?” /div class=”cover”?=esub($bqr[title],30)?/div/a /div/div/divdiv class=”topic_before”div class=”tit”a href=”/t/huati/” class=”more” target=”_blank”更多+/ah3往期话题/h3/divdiv class=”con”ul?php}else{?li a href=”?=$bqsr[titleurl]?” title=”?=$bqr[title]?” class=”fl” target=”_blank”img src=”?=$bqr[titlepic]?” alt=”?=$bqr[title]?”/ah4a href=”?=$bqsr[titleurl]?” title=”?=$bqr[title]?” target=”_blank”?=esub($bqr[title],30)?/a/h4p?=esub($bqr[smalltext],10)?/p/li?}?/ul/div/div[/e:loop]

实现效果如下:

就是这么着,这是一句灵动标签实现的。

发表评论

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