- Coolui Scroll v3.2.6更新纯css实现LOGO文字下拉效果
先上效果: [图片] 要实现这个效果,首先要思考如何给文字添加背景图,且只给文字添加。 先简单的实现文字: [代码]<view class="text">Coolui Scroll</view> [代码] [代码].text { font-size: 40px; font-weight: bold; color: black; } [代码] 效果是这样的: [图片] 2. 然后给文字加上背景 [代码].text { font-size: 40px; font-weight: bold; color: black; background-image: url('https://test.wzs.pub/pic/bg2.jpg'); background-size: cover; } [代码] 效果是这样的: [图片] 3. 如何只把背景加到文字上呢? 利用css的background-clip: text;来实现 [代码].text { font-size: 40px; font-weight: bold; color: black; background-image: url('https://test.wzs.pub/pic/bg2.jpg'); background-size: cover; background-clip: text; -webkit-background-clip: text; } [代码] 效果是这样的: [图片] 4. ??没有达到想要的效果? 那是因为你的文字颜色没有透明,所以没有显现出背景图 [代码].text { font-size: 40px; font-weight: bold; color: transparent; background-image: url('https://test.wzs.pub/pic/bg2.jpg'); background-size: cover; background-clip: text; -webkit-background-clip: text; } [代码] 效果达到预期了: [图片] 效果不明显?我们换张图: [图片] 5. 接下来就是如何让文字动起来了 我们设置背景图片不重复,去改变background-position的值 [代码].text { font-size: 40px; font-weight: bold; color: transparent; background-image: url('https://n.sinaimg.cn/sinacn15/0/w2048h1152/20180618/b195-heauxvz0078139.jpg'); background-size: cover; background-repeat: no-repeat; background-clip: text; -webkit-background-clip: text; background-position: -120px center; } [代码] 效果是这样的: [图片] 后面的文字因为透明并没有显示出来,如此以来我们改变background-position的值就能让文字一个一个显示出来。结合小程序scroll-view下拉刷新的移动值threshold就能实现随着下拉文字出现的效果了 示例 demo 请微信扫码打开小程序查看 [图片] 详细文档 gitee文档入口 github文档入口
2023-07-03 - 【集合】花了 3 个月,写了 40 篇小程序文章
前言 花了3个月,一共输出 40 篇文章,这也算是一个阶段性的总结。在此做个文章分类集合,希望对大家有所帮助。 小程序前端 《专治按钮效果不明显(扩散动画效果)》 《小程序开发必备,这 5 款超实用开源插件!》 《仿抽奖助手奖品详情页面向上翻页效果》 《推荐 5 款高仿知名应用的开源项目!》 《生成海报很复杂?有它轻松搞定!》 《推荐一个自定义导航栏开源库》 《前端开发,必备的学习网站!》 《情侣券-领取动画分析》 《通过玩游戏来学习CSS》 《CSS不规范导致的布局显示问题》 《微信小程序如何引入npm包?》 《情侣券-选中卡片翻转动画》 《CSS:实现卡片洗牌效果》 《情侣券 v2.0 使用的 4 款开源组件》 小程序云开发 《使用聚合函数实现打卡排行榜》 《使用云开发做内容安全检查》 《云开发-实现分页功能》 《云开发-实现维护用户表》 《云开发-实现模糊搜索》 《云开发实战:实现订阅消息推送》 《如何优雅的调用云函数?》 《云开发实战-如何维护用户表?(优化版)》 《推荐 10 款使用云开发的开源项目》 《云开发:CloudBase CMS 实战使用指南》 小程序产品 《如何利用小程序提高10倍活动效果?》 《实战:让数据说话之自定义埋点分析》 《#小程序云开发挑战赛#-情侣券》 《小程序运营必备的 3 款官方小程序》 《小程序云开发挑战赛:情侣券 v1.1 版本迭代》 《云开发挑战赛复赛:情侣券介绍PPT》 《参加#小程序云开发挑战赛#复赛收获》 《云开发挑战赛决赛:情侣券介绍PPT》 通用知识 《如何重构?》 《如何高效学习?》 《如何看懂时序图?》 《为什么优秀的程序员都写博客?》 《我从 Android 转到 微信小程序 的思考》 最后 后续计划会写更多云开发相关的文章以及小程序基础系列学习文章。
2020-11-24 - 小程序流量主运营技巧
前言(写给入坑的小白) 本文不涉及任何需要资质的小程序(如:视频类目)。小程序流量主是个人和小微企业主要变现途径之一,满1000人即可开通流量主(登录mp.weixin.qq.com,左侧边栏-推广-流量主-开通即可)。开通后,开发者可从流量主-广告位管理添加广告位,目前有6种广告位。 [图片] 正文(本文约很多字,分为四大主类,手里有1-10个小程序建议全部看完;手里有10个以上小程序,可跳过1、2、3,均为个人观点,不喜使劲喷) 一、小程序定位 小程序定位目前有以下四种,均不需要任何资质,个人(商城除外)/小微企业都可以做,由于本人不擅长文字表达,每个类型只选择一个做分析,谅解。 1、工具类 工具类有很多可以做:题库、技术文档、教程、去水印等。目前最火爆的应该属于疫情相关类的工具,关于疫情数据类小程序不做分析,没资质也没权利,主要说疫情周边可运营的工具。头像口罩,代表小程序:头像加口罩、戴个口罩吧、戴上口罩(每日搜索量约等于2000),可参考以下做法: [图片] 以下为近7日访问数据量 [图片] 盈利方式:流量主 延伸参考:如果仅做头像加口罩的话,那么疫情过后,这个小程序会直线下降,将无任何作用。如果开发者手里目前有类似小程序,可参考“头像加口罩”做法,逐渐去延伸头像周边功能,例: ①、头像加字:头像+数字、头像加V、头像加字、头像加圣诞帽、新年头像边框、头像加福、头像加明星等 ②、聊天背景图、壁纸:武汉加油、卡通、美女(不要漏点太多)、二次元、跑车、科技等 ③、趣味九宫格配图:类似朋友圈9张图,中间获取用户自己头像,周围8张图弄点能吸引用户的等 ④、文字秀:微信昵称下标、上标、个性昵称等 运营分析:如果参考以上4点做法,首先你的程序再疫情结束后,不至于直线下滑,最起码能留住一些用户(UI很重要) 个人建议:工具类的好处就是不需要去长时间盯着后台,建议有想法的开发者,可以入门5-10个左右工具类小程序(功能不要相同)。 推广方式:参考本文第四大板块内容 2、返利类 主流返利平台:淘宝、天猫、拼多多、京东、蘑菇街、唯品会、网易考拉,以下参考 [图片] 盈利方式:返利(主)+流量主(辅) [图片] 基础分析:每个人微信里都会有一个或多个微信群是给你们购物优惠券链接的,他们盈利方式主要是靠每个平台的返利,比如淘宝天猫的叫“阿里妈妈”、拼多多的叫“多多进宝”等 运营分析: ①、平台功能:提供所有优惠券、商品返利、代理入驻、提现(个人可做收款码、企业可对接微信支付到零钱) ②、招代理商、可以给代理商(兼职、宝妈)50%以上的返利 ③、除了商品优惠券之外,可以把返利分给一部分给到用户。首先,用户会花更少的钱买到商品;其次,用户买完东西还会赚点小钱,每个月可提现到微信零钱。这样用户会发生裂变,省钱+赚钱。 个人建议:开发者至少有一个类似的返利小程序,每个月只需运营一天,工作内容一是把用户的返利发给用户&代理商,二是自己去各大平台领取每个月的“工资” 推广方式:参考本文第四大板块内容 3、商城类(个人开发者可跳过) 商城类,本人运营的比较少,每天就10-20单左右,卖啥就不做广告了 盈利方式:差价 基础分析:如果自己手里有一些商品低价资源,可以做一个“综合服务商城类目”,然后去试着用广告主去推一下 运营分析: ①、平台功能:砍价、返利、拼团、回购、入驻、积分、抽奖、游戏营销 ②、广告主曝光&点击报价不要最低,也不要最高,理由就是最低的话,80%的钱会给你推到一些质量很差的微信用户,比如我。 ③、对接圈子,虽然圈子刚起步,不确定能不能做大,万一呢? 个人建议:企业一定要有一个自己的商城,哪怕没人买。这种东西怎么说呢,就好比一个企业站,虽然没什么用,但是得放那儿,万一客户要看呢? 推广方式:参考本文第四大板块内容 4、游戏类(非小游戏) 答题、成语、找茬等类似运营的比较多,可自行搜索,不要认为这是游戏,开发者就望而却步,在线教育类目是可以通过的,这个开发者很多都不知道。以下可参考: [图片] 盈利方式:流量主 基础分析:基本所有的模式都是闯关类型,这种类型的小程序,基本都是用户消磨时间用 运营分析:关卡尽量多,入门、初级、中级、高级,高级模式可以做类比循环,形成无限关卡模式,闯关奖励机制,签到机制等。这种类型的小程序比较方便运营,裂变起来也快。 个人建议:裂变模式一定要有,虽然微信会严格把控这方面功能,但是开发者可以做一些技巧,不要让用户强制或者主动去触发,这样微信对开发者还是很友好的。 推广方式:参考本文第四大板块内容 二、小程序开发 有实力的开发者,自己开发,云开发很快,会前端就可以了,没实力的去正规平台买源码,论坛源码也很多,有部分论坛还是嵌入了比特币勒索,自己做好防护。个人建议:开发者能开发尽量自己开发,后期迭代方便,不要像我一样,50多个小程序80%是买现成去运营的。反正各有各的好处,开发者可自行决定,运营者可选择直接购买源码直接上线运营,前提是自己看好功能是不是和自己要的一样。有些SAAS平台的开发者实力还是可以的,支持定制功能。此处不做广告,自行搜索或者询问朋友。 三、广告位位置及利润 开发者的每个页面广告位一定要分开!一定要分开!一定要分开!这样做的目的是为了分析每个广告位的利润,好去做调整,把收益最大化。 失败案例举例:小程序的主页、个人中心页用同一个banner广告位,这样做出来一点好处都没有,后台只能看到banner收益是多少,看不到是哪个页面收益。极端情况,收益全部再首页,个人中心页没有广告收益,这种情况开发者是不知道的,如果把广告位分开,这种情况可以去优化个人页面,或者主页面换成视频banner。广告位分析页面:流量主--数据统计--广告数据--广告指标明细--细分数据 [图片] [图片] 1、很多人表示,疫情期间流量主收入下滑。这个原因不是因为微信调整流量主收益,根本问题是自己的用户质量。举个例子,当你开通流量主之后,你的用户还是这1000个,假如你第一天收益为100,你很开心,1000用户就能赚100,你第二天就放弃推广了,这样的话,你的用户质量是会逐渐下滑,微信方完全可以认定为你这1000人都是自己的号,去刷广告费的。长此以往下去,你的流量主利润会无限趋向于0。举个栗子: [图片] 2、广告位位置一定要合理好看,但是不代表“流氓”,比如全明星代言的某游戏“元宝无限收一刀999”点哪儿哪充值。开发者需要注意的是小程序的质量,需要用户在每个页面停留的时长最起码30秒,这样一个完整的视频广告才能曝光完。 3、banner广告收益是按有效点击计算的。很多人好几千曝光,但是点击只有几个、十几个,这种情况需要不断去优化接入的场景/位置,提高用户点击意愿。个人技巧:banner广告位尽量不要太多,1-2个就可以。尽量多放几个视频广告位,这样曝光也有收益。格子广告没试过,用过都说不好~ 4、激励广告作为流量主最高收益是有一定道理的,用户为了获取某些奖励是必须观看完整的,所以给开发者建议:用户如果可以获得小程序内某些奖励,可以适当多放一些激励广告位。 5、所有的广告位都是根据用户年龄、爱好等参数去调取相应的广告,开发者不需要去考虑 6、广告收益个人认为:激励》视频》插屏》前贴》banner》格子(格子没试过,暂放倒数第一) 四、小程序推广 尽量做成年人主打的小程序,有些开发者觉得好玩儿,做一些儿童益智类的小程序,你是认为儿童有手机,还是认为家长愿意让孩子玩儿手机呢?这个很不解。没有鄙视的意思,也许是情怀吧~~毕竟我做小程序比较俗,就是为了赚钱。 主流推广方式:公众号引流、截流,由于涉及一些不合常规的内容,本文只说常规操作,剩下的自己领悟,或者可以联系我~ 首先小程序的名字至关重要,一个好的名字可以带来无限的流量,再加上裂变功能(邪恶的微笑)。起名字的时候可以用到的工具:搜索小程序-微信指数,查询关键字,尽量找稳定再1000万以上的搜索量,从关键字中摸索自己的小程序名字。这样用户搜索到你的小程序几率会很高~ 1、工具类核心玩儿法(适用于所有小程序推广):文章引流,截取关键字,火爆主题,比如2019年12月19日庆余年全集泄露、2020年疫情(不要发疫情数据内容,要发一些正能量的有内容文章去引流),我阅读过的文章最低的阅读量8000左右,最高的10万+,据说有好几百万的阅读量。如果你的文章写的好,结尾放一个小广告:为防止疫情蔓延,请给您的头像带上口罩~,啪,一个卡片小程序(或二维码),流量自己想~ 推广对象:18-30岁 2、返利类核心玩儿法: ①、可以参考工具类玩儿法 ②、各大微信群、QQ群,去推广,招代理等方式,或者去买一些基础流量,进行裂变,实际运营看下效果,好继续针对用户群体去推广,建立自己的群体系,群内发商品返利链接。微信好友没人?给你举个例子,我这篇文章发完,如果加个我的二维码,最起码能有100人加我,不是我文章写的有多好,是你永远不知道用户有什么样的目的和需求~ 推广对象:18-60岁 3、商城类核心玩儿法 ①、可参考返利类核心玩儿法,拥有自己的客户群体系,发一些自己的商品还是可以的,一定要带分销体系,你懂得~(最高3级,再高就是传销了) ②、广告主、目前效益个人感觉不明显,每次花1000块钱做广告,利润基本没有,和发广告的钱持平,而且用户留存也不是很高,可能是我的商品比较单一等各方面因素吧,不过赚流量还是不错的。 推广对象:18-30岁(以我的商城为例,还需看商城出售的内容) 4、游戏类核心玩儿法(非小游戏) ①、一个好的名字就够了。举例:精选商品橱窗(腾讯官方),微橱窗(我朋友的)。不得不说,这波流量很高,遗憾的是,他不是火爆的游戏类小程序~ [图片] ②、参考工具类玩儿法,文章引流截流 推广对象:18-40岁 五、小程序矩阵 矩阵一定要有,矩阵一定要有,矩阵一定要有,防截流,底配10个小程序。不是纯矩阵,是微信开发规定,每个小程序可以跳转10个小程序,开发者可以利用这个功能去添加自己的矩阵来获取更多的流量收益,保证自己的用户在自己的矩阵圈活动。 [图片] 写这篇文章主要是给大家传授经验,希望小白能学到点东西,入门后的朋友可领悟到更多运营方法,江湖之大,附月账单有缘再见 [图片]
2020-05-25 - onShareAppMessage 从分享朋友到分享朋友圈 onShareTimeline, 踩坑之旅
我们厂也是混微信生态的, 大厂有个风吹草动的, 我们就要立马操练起来! 前端时间分享朋友圈刚发了个beta版, 我们总部的产品大佬, 立马致电远在西部的开发部门, 干! 立马! 明天上线!!! (GNMA!G, 灵魂相同的开发们才能看懂) 还能说点啥呢? 以上是瞎扯淡, 以下面是干活: 为你提供方便: 接口文档: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html 页面问答: https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onShareTimeline 限制文档: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html#%E5%8D%95%E9%A1%B5%E6%A8%A1%E5%BC%8F%E4%B8%8B%E7%9A%84%E9%99%90%E5%88%B6 文档一定要看, 一遍不行, 再来一遍! 第一步: 实现分享朋友圈 前置条件: [图片] 直接上代码: [图片] 找一步安卓手机, 扫码立显; 做为一个前端小菜, 我脚的走到这步, 应该木有一丁点儿问题! 如果你实现不出来, 那就回归到田野般的生活中找找赶脚 第二步: 踩坑 每次出来个新功能, 实现的道路上总是坑坑洼洼, 我就想问一问, 坐在腾讯大楼喝着菊花枸杞的小伙伴, 程序员何苦为难程序员? (文档写的好一点能si吗?) 大家一直关注的如何传参问题: 传参数方式是酱紫的: [图片] 代码是酱紫的: [图片] 接收参数: onLoad(option) , 直接就可以拿到参数对象, 点一点就就出来, 亲测可用. 第二步: 场景值 众所周知, 分享的页面, 在朋友圈打开是“单页面模式”, 那就收到以下限制: [图片] 需要开发且记且珍惜. 可以根据场景值来判断页面来源 [图片] 未完待续, 有任何问题都可以找留言(包括如何找对象)
2020-07-25 - 如何使用scroll-view制作左右滚动导航条效果
最新:2020/06/13。修改为scroll-view与swiper联动效果,新增下拉刷新以及上拉加载效果。。具体效果查看代码片段,以下文章内容和就不改了 刚刚在社区里看到 有老哥在问如何做滚动的导航栏。这里简单给他写了个代码片段,需要的大哥拿去随便改改,先看效果图: [图片] 代码如下: wxml [代码]<scroll-view class="scroll-wrapper" scroll-x scroll-with-animation="true" scroll-into-view="item{{currentTab < 4 ? 0 : currentTab - 3}}" > <view class="navigate-item" id="item{{index}}" wx:for="{{taskList}}" wx:key="{{index}}" data-index="{{index}}" bindtap="handleClick"> <view class="names {{currentTab === index ? 'active' : ''}}">{{item.name}}</view> <view class="currtline {{currentTab === index ? 'active' : ''}}"></view> </view> </scroll-view> [代码] wxss [代码].scroll-wrapper { white-space: nowrap; -webkit-overflow-scrolling: touch; background: #FFF; height: 90rpx; padding: 0 32rpx; box-sizing: border-box; } ::-webkit-scrollbar { width: 0; height: 0; color: transparent; } .navigate-item { display: inline-block; text-align: center; height: 90rpx; line-height: 90rpx; margin: 0 16rpx; } .names { font-size: 28rpx; color: #3c3c3c; } .names.active { color: #00cc88; font-weight: bold; font-size: 34rpx; } .currtline { margin: -8rpx auto 0 auto; width: 100rpx; height: 8rpx; border-radius: 4rpx; } .currtline.active { background: #47CD88; transition: all .3s; } [代码] JS [代码]const app = getApp() Page({ data: { currentTab: 0, taskList: [{ name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, { name: '有趣好玩' }, ] }, onLoad() { }, handleClick(e) { let currentTab = e.currentTarget.dataset.index this.setData({ currentTab }) }, }) [代码] 最后奉上代码片段: https://developers.weixin.qq.com/s/nkyp64mN7fim
2020-06-13 - 小程序毫秒级倒计时的一种优雅实现
在小程序上用毫秒级定时器来刷新页面或组件,会引发性能问题。 使用 [代码]canvas[代码] 又对字体样式无法进行很好的控制。 一种实现方案 使用秒级的定时器刷新页面或组件实现秒级的倒计时,制作毫秒倒计时的 GIF 并把图放到秒级倒计时后面。 毫秒倒计时 GIF:[图片] 小程序效果如下图所示: [图片] HAVE FUN 😃
2019-09-20 - 如何实现一个自定义数据版省市区二级、三级联动
社区可能有其他的方案了,但是再分享下吧,给有需要的童鞋。 效果图: [图片] 额,这个视频转GIF因为社区上传不了大图,所以剪了一部分,具体的效果还是直接工具打开代码片段预览吧~ 第一步:你的页面JSON引入该组件: [代码]{ "usingComponents": { "city-picker": "/components/cityPicker/index" } } [代码] 第二步:你的页面WXML引入该组件 [代码]<city-picker visible="{{visible}}" column="2" bind:close="handleClick" bind:confirm="handleConfirm" /> [代码] 第三步:你的页面JS调用 [代码]// 显示/隐藏picker选择器 handleClick() { this.setData( visible: !this.data.visible }) }, // 用户选择城市后 点击确定的返回值 handleConfirm(e) { const { detail: { provinceName = '', provinceId = '', cityName, cityId='', areaName = '', areaId = '' } = {} } = e this.setData({ cityId, cityName, areaId, areaName, provinceId, provinceName }) } [代码] 组件属性 属性 默认值 描述 visible false 是否显示picker选择器 column 3 显示几列,可选值:1,2,3 values [0, 0, 0] 必填,默认回填的省市区下标,可选择具体省市区后查看AppData的regionValue字段 close function 点击关闭picker弹窗 confirm function 点击选择器的确定返回值 confirm: 属性 默认值 描述 provinceName 北京市 省份名称 provinceId 110000 省份ID cityName 市辖区 城市名称 cityId 110100 城市ID areaName 东城区 区域名称 areaId 110000 区域Id 至于怎么获取你想默认城市的下标,可以滑动操作下选中省市区后,点击确定后查看appData里的regionValue的值。 以上就是一个自定义数据版本的省市区二级、三级联动啦,老规矩,结尾放代码片段。 https://developers.weixin.qq.com/s/F9k9cTmT7LAz
2022-07-20 - 小程序绘图篇:如何正确地给一个渐变背景按钮绘制阴影
最近在开发一个小程序项目中遇到了一个小的问题。那就是需要给一个背景是渐变色的按钮添加一层阴影,下图中红色线标记的地方。 [图片] 目的是为了让这个按钮更有立体感。刚开始做的时候觉得没有什么难度,在开发工具上也能够很好的展示;但是到了真机测试的时候,才发现原来给按钮绘制阴影的方法在真机上显示不出来。于是就有了下面我寻找解决方案的过程,最终我顺利的解决了这个问题。我把我解决这个问题的思路记录下来,方便我日后回顾,也希望能够跟大家一起交流,我们一起进步。 当我在手机上发现绘制的按钮没有阴影的时候,我就知道接下来我将可能要付出几个小时的时间去解决这个问题。我也做好了心理准备,于是就踏上了寻找解决方案的道路。 第一步:搜索问题 当我遇到这个问题的时候,我的第一反应就是先上网搜索一下看看有没有同学也遇到过这种问题。于是我就搜索小程序canvas绘图与按钮阴影相关的一些问题和资料。我的确找到了一些相关的文章和问题,但是我发现这些资料要么跟自己遇到的问题不太符合,要么搜到的问题还没有回复。 我提取了这些文章和问题中有用的点,得出了下面的结论: 小程序canvas可以绘制圆角阴影 小程序绘制阴影的API有新旧两个版本 没有说明渐变色背景的按钮是否可以直接添加阴影 第二步:分析对比 先来看一下我现在的代码是这样的: [代码]// ... 此处省去部分代码 // 绘制渐变色 _ctxc.beginPath() _ctxc.arc((SHARE_TO_CHAT_CANVAS_WIDTH - w) / 2, btn_h + r, r, 0.5 * Math.PI, 1.5 * Math.PI) // 绘制右边圆弧 _ctxc.arc((SHARE_TO_CHAT_CANVAS_WIDTH + w) / 2, btn_h + r, r, -0.5 * Math.PI, 0.5 * Math.PI) // 闭合路径 _ctxc.closePath() // 添加渐变色 const grd = _ctxc.createLinearGradient((SHARE_TO_CHAT_CANVAS_WIDTH - w) / 2 - r, btn_h, (SHARE_TO_CHAT_CANVAS_WIDTH + w) / 2 + r, btn_h) grd.addColorStop(0, first_color) grd.addColorStop(1, second_color) _ctxc.setFillStyle(grd) // 设置阴影 _ctxc.shadowOffsetX = 2 _ctxc.shadowOffsetY = 2 _ctxc.shadowColor = '#43454c' _ctxc.shadowBlur = 5 // 填充渐变色 _ctxc.fill() // 取消阴影 _ctxc.shadowOffsetX = 0 _ctxc.shadowOffsetY = 0 _ctxc.shadowColor = '#ffffff' _ctxc.shadowBlur = 0 // 绘制中间的文案 _ctxc.font = `normal normal bold 36px sans-serif` _ctxc.fillStyle = '#ffffff' _ctxc.setTextBaseline('middle') _ctxc.setTextAlign('center') _ctxc.fillText(`立即打卡`, SHARE_TO_CHAT_CANVAS_WIDTH / 2, btn_h + r) // 绘制 _ctxc.draw() [代码] 现在的代码在模拟器上可以完美的绘制出我想要的结果,如下图 [图片] 但是在真机上不行。我们可以看到在开发工具上是有阴影效果的,但是在真机上的效果却是没有阴影的。如下图 [图片] 所以我要做的就是逐步排查,要依次确定下面几个问题的答案: 问题一:看一下官方文档给出的代码在真机上能不能够显示出来阴影。 官方文档给出的代码如下: [代码]const ctx = wx.createCanvasContext('myCanvas') ctx.setFillStyle('red') ctx.setShadow(10, 50, 50, 'blue') ctx.fillRect(10, 10, 150, 75) ctx.draw() [代码] 我们直接测试一下在编辑器和手机上的效果,编辑器上的效果如下: [图片] 模拟器上是可以显示效果的,真机上的效果如下: [图片] 也是可以显示的,这说明在真机上的确是可以绘制出来阴影的。 但是我同时也注意到,这个实例的代码使用的是老的API。 [图片] 所以我再次尝试把老的API替换成新的API进行测试 代码修改如下: [代码] // ...省略部分代码 const ctx = wx.createCanvasContext('share-to-chat') ctx.setFillStyle('red') // ctx.setShadow(10, 50, 50, 'blue') // 使用新的API ctx.shadowOffsetX = 10 ctx.shadowOffsetY = 50 ctx.shadowColor = 'blue' ctx.shadowBlur = 50 ctx.fillRect(10, 10, 150, 75) ctx.draw() [代码] 这次修改之后,在编辑器上绘图没有发生什么变化。但是,在真机上却显示不出来了,只有一个红色的矩形,如下图所示: [图片] 所以到这里我们可以知道,使用新的绘制阴影的API在我这台真机上是绘制不出来阴影的。那我们就先使用老的API进行阴影的绘制,到这里这个问题已经有了一点进展了,我们继续进行排查。 问题二:是否能够绘制出来圆角的阴影 我们上面的测试绘制的阴影是矩形的阴影,如果我们绘制的是一个圆弧呢?还能绘制出来阴影吗?我们接着向下走。这次我们先绘制一个圆形,然后再给这个圆添加一个阴影。那么代码如下: [代码]// ...省略部分代码 const ctx = wx.createCanvasContext('share-to-chat') ctx.arc(100, 75, 50, 0, 2 * Math.PI) ctx.setFillStyle('red') ctx.setShadow(10, 50, 50, 'blue') // ctx.shadowOffsetX = 10 // ctx.shadowOffsetY = 50 // ctx.shadowColor = 'blue' // ctx.shadowBlur = 50 ctx.fill() ctx.draw() [代码] 这次在编辑器上的效果如下: [图片] 在手机上的效果如下: [图片] 也是可以的,那么按道理来说,如果我们使用老版本绘制阴影的API的话,我们绘制的这个圆形按钮也应该能够显示出来阴影。来我们来试一试吧。 修改最初的代码如下: [代码] // ...省略部分代码 _ctxc.setFillStyle(grd) // 设置阴影 // _ctxc.shadowOffsetX = 2 // _ctxc.shadowOffsetY = 2 // _ctxc.shadowColor = '#43454c' // _ctxc.shadowBlur = 5 // 使用老的API _ctxc.setShadow(2, 2, 5, '#43454c') // 填充渐变色 _ctxc.fill() // ...省略部分代码 [代码] 在编辑器上还是可以正常绘制阴影的,但是在手机上还是不能够显示阴影。 那么问题出现在哪里呢?这时候就要找能够绘制出来阴影和不能够绘制出来阴影这两种情况我们改变了什么。 问题3:在绘制渐变色背景按钮的同时是否可以绘制阴影 想到这里,我就猜想会不会是因为我绘制的圆形按钮使用的是渐变色背景的原因,导致我们没有办法绘制出来阴影呢?还是要实践一下,继续修改代码。这次我不使用渐变色背景,而改为使用纯色背景来测试一下。修改代码如下: [代码]// ...省略部分代码 // 添加渐变色 // const grd = _ctxc.createLinearGradient((SHARE_TO_CHAT_CANVAS_WIDTH - w) / 2 - r, btn_h, (SHARE_TO_CHAT_CANVAS_WIDTH + w) / 2 + r, btn_h) // grd.addColorStop(0, first_color) // grd.addColorStop(1, second_color) // _ctxc.setFillStyle(grd) // 使用纯色背景 _ctxc.setFillStyle('#4DAEFE') // 设置阴影 // _ctxc.shadowOffsetX = 2 // _ctxc.shadowOffsetY = 2 // _ctxc.shadowColor = '#43454c' // _ctxc.shadowBlur = 5 // 使用老的API _ctxc.setShadow(2, 2, 5, '#43454c') // 填充渐变色 _ctxc.fill() // ...省略部分代码 [代码] 这次在编辑器的显示如下图: [图片] 是有阴影的,那么在手机上效果如何呢?我们看一下: [图片] 很棒,这次终于在真机上也绘制出来的阴影了;距离我们成功也不远啦。 那么我们接下来要解决的问题就是,如何能够把阴影和渐变色背景都添加上去,这一次我们鱼和熊掌都想得到。 那怎么办呢,办法总比问题多,我们只需要在绘制好阴影的基础上再绘制一次渐变的背景就可以了。 就是先绘制一个纯色的带有阴影的按钮,然后在同样的位置我们再次绘制一个有渐变背景色的按钮,最后绘制文字就好啦。真是机智如我呀。最终的代码如下: [代码]// ...省略部分代码 // 开始绘制 _ctxc.beginPath() // 绘制左边圆弧 _ctxc.arc((SHARE_TO_CHAT_CANVAS_WIDTH - w) / 2, btn_h + r, r, 0.5 * Math.PI, 1.5 * Math.PI) // 绘制右边圆弧 _ctxc.arc((SHARE_TO_CHAT_CANVAS_WIDTH + w) / 2, btn_h + r, r, -0.5 * Math.PI, 0.5 * Math.PI) // 绘制中间的渐变矩形 _ctxc.closePath() _ctxc.setFillStyle('#000') // 设置阴影 // 新版本添加阴影 _ctxc.shadowOffsetX = 5 _ctxc.shadowOffsetY = 5 _ctxc.shadowColor = '#a5a6a7' _ctxc.shadowBlur = 5 // 旧版本添加阴影 _ctxc.setShadow(5, 5, 5, '#a5a6a7') _ctxc.fill() // 重置取消阴影 // 新版本重置阴影 _ctxc.shadowOffsetX = 0 _ctxc.shadowOffsetY = 0 _ctxc.shadowColor = '#ffffff' _ctxc.shadowBlur = 0 // 旧版本重置阴影 _ctxc.setShadow(0, 0, 0, '#ffffff') // 绘制渐变色 _ctxc.beginPath() _ctxc.arc((SHARE_TO_CHAT_CANVAS_WIDTH - w) / 2, btn_h + r, r, 0.5 * Math.PI, 1.5 * Math.PI) // 绘制右边圆弧 _ctxc.arc((SHARE_TO_CHAT_CANVAS_WIDTH + w) / 2, btn_h + r, r, -0.5 * Math.PI, 0.5 * Math.PI) // 关闭路径 _ctxc.closePath() const grd = _ctxc.createLinearGradient((SHARE_TO_CHAT_CANVAS_WIDTH - w) / 2 - r, btn_h, (SHARE_TO_CHAT_CANVAS_WIDTH + w) / 2 + r, btn_h) grd.addColorStop(0, first_color) grd.addColorStop(1, second_color) _ctxc.setFillStyle(grd) _ctxc.fill() // 立即打卡的文案字体大小 _ctxc.font = `normal normal bold 40px sans-serif` _ctxc.fillStyle = '#ffffff' _ctxc.setTextBaseline('middle') _ctxc.setTextAlign('center') _ctxc.fillText(`立即打卡`, SHARE_TO_CHAT_CANVAS_WIDTH / 2, btn_h + r) // 绘制 _ctxc.draw() // ...省略部分代码 [代码] 让我们来看一下在手机上的效果吧: [图片] 这一次终于完美地解决了这个问题,开心。 还有,一些同学可能注意到,我上面的代码在添加阴影的时候新版本和老版本的API我都使用了,主要是因为我能够测试的手机比较少,不知道在别的品牌的手机上表现如何。所以为了保险起见,我两种方法都使用了。 还有一点需要注意的是,我本次实践的环境是:基础调试库 2.3.0,手机型号 iPhone 8 最终这个带阴影的有渐变背景色的按钮就完成啦。 第三步:总结与思考 关于小程序绘图这次遇到的问题我们可以总结一下:遇到在编辑器和真机表现不一样的情况,我们首先应该先上网查一下看看小伙伴们有没有遇到类似的问题,如果人家已经有比较好的解决方案,我们就可以参考别人的解决方案去解决我们自己遇到的问题,这样会比较省时省力。如果没有的话,我们就需要自己去逐步排查问题,不断地缩小出现问题的范围,最终定位出出现问题的地方;然后再去想办法解决。 其实,如果想达到这样的效果,我们不一定非得通过代码绘制去实现这么一个功能;也可以直接让设计师把按钮这一部分导出一张小的图片来,我们直接把这个包含阴影的按钮图片绘制在图上就好了。如果我们这个按钮是不经常发生变化的话,那么直接把包含阴影按钮的图片绘制在画布上也许是挺好的一个解决方法。所以,我们首先要考虑的是我们的代码想要达到什么样的效果,那么达到这样的效果有哪些途径,各有什么优缺点。然后我们选择一个最佳的方案去开发就可以啦。 这篇文章到这里就结束啦,希望我的分享能够帮助到一些遇到同样绘图问题的小伙伴。最后一点私心,推荐一下我们开发的这一款小程序主线程。 [图片] 一个可以帮助大家规划时间和任务,并且可以组队学习找伙伴一起打卡的小程序,如果你觉得的不错的话,记得帮我们分享一下哟。
2019-10-28 - 【开箱即用】分享几个好看的波浪动画css效果!
以下代码不一定都是本人原创,很多都是借鉴参考的(模仿是第一生产力嘛),有些已忘记出处了。以下分享给大家,供学习参考!欢迎收藏补充,说不定哪天你就用上了! 一、第一种效果 [图片] [代码]//index.wxml <view class="zr"> <view class='user_box'> <view class='userInfo'> <open-data type="userAvatarUrl"></open-data> </view> <view class='userInfo_name'> <open-data type="userNickName"></open-data> , 欢迎您 </view> </view> <view class="water"> <view class="water-c"> <view class="water-1"> </view> <view class="water-2"> </view> </view> </view> </view> //index.wxss .zr { color: white; background: #4cb4e7; /*#0396FF*/ width: 100%; height: 100px; position: relative; } .water { position: absolute; left: 0; bottom: -10px; height: 30px; width: 100%; z-index: 1; } .water-c { position: relative; } .water-1 { background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjYwMHB4IiBoZWlnaHQ9IjYwcHgiIHZpZXdCb3g9IjAgMCA2MDAgNjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCAzLjQgKDE1NTc1KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT53YXRlci0xPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9IuaIkSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc2tldGNoOnR5cGU9Ik1TUGFnZSI+CiAgICAgICAgPGcgaWQ9Ii0iIHNrZXRjaDp0eXBlPSJNU0FydGJvYXJkR3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMjEuMDAwMDAwLCAtMTMzLjAwMDAwMCkiIGZpbGwtb3BhY2l0eT0iMC4zIiBmaWxsPSIjRkZGRkZGIj4KICAgICAgICAgICAgPGcgaWQ9IndhdGVyLTEiIHNrZXRjaDp0eXBlPSJNU0xheWVyR3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMS4wMDAwMDAsIDEzMy4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0wLDcuNjk4NTczOTUgTDQuNjcwNzE5NjJlLTE1LDYwIEw2MDAsNjAgTDYwMCw3LjM1MjMwNDYxIEM2MDAsNy4zNTIzMDQ2MSA0MzIuNzIxMDUyLDI0LjEwNjUxMzggMjkwLjQ4NDA0LDcuMzU2NzQxODcgQzE0OC4yNDcwMjcsLTkuMzkzMDMwMDggMCw3LjY5ODU3Mzk1IDAsNy42OTg1NzM5NSBaIiBpZD0iUGF0aC0xIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj48L3BhdGg+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==") repeat-x; background-size: 600px; -webkit-animation: wave-animation-1 3.5s infinite linear; animation: wave-animation-1 3.5s infinite linear; } .water-2 { top: 5px; background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjYwMHB4IiBoZWlnaHQ9IjYwcHgiIHZpZXdCb3g9IjAgMCA2MDAgNjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCAzLjQgKDE1NTc1KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT53YXRlci0yPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9IuaIkSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc2tldGNoOnR5cGU9Ik1TUGFnZSI+CiAgICAgICAgPGcgaWQ9Ii0iIHNrZXRjaDp0eXBlPSJNU0FydGJvYXJkR3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMjEuMDAwMDAwLCAtMjQ2LjAwMDAwMCkiIGZpbGw9IiNGRkZGRkYiPgogICAgICAgICAgICA8ZyBpZD0id2F0ZXItMiIgc2tldGNoOnR5cGU9Ik1TTGF5ZXJHcm91cCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTIxLjAwMDAwMCwgMjQ2LjAwMDAwMCkiPgogICAgICAgICAgICAgICAgPHBhdGggZD0iTTAsNy42OTg1NzM5NSBMNC42NzA3MTk2MmUtMTUsNjAgTDYwMCw2MCBMNjAwLDcuMzUyMzA0NjEgQzYwMCw3LjM1MjMwNDYxIDQzMi43MjEwNTIsMjQuMTA2NTEzOCAyOTAuNDg0MDQsNy4zNTY3NDE4NyBDMTQ4LjI0NzAyNywtOS4zOTMwMzAwOCAwLDcuNjk4NTczOTUgMCw3LjY5ODU3Mzk1IFoiIGlkPSJQYXRoLTIiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwMC4wMDAwMDAsIDMwLjAwMDAwMCkgc2NhbGUoLTEsIDEpIHRyYW5zbGF0ZSgtMzAwLjAwMDAwMCwgLTMwLjAwMDAwMCkgIj48L3BhdGg+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==") repeat-x; background-size: 600px; -webkit-animation: wave-animation-2 6s infinite linear; animation: wave-animation-2 6s infinite linear; } .water-1, .water-2 { position: absolute; width: 100%; height: 60px; } .back-white { background: #fff; } @keyframes wave-animation-1 { 0% { background-position: 0 top; } 100% { background-position: 600px top; } } @keyframes wave-animation-2 { 0% { background-position: 0 top; } 100% { background-position: 600px top; } } .user_box { display: flex; z-index: 10000 !important; opacity: 0; /* 透明度*/ animation: love 1.5s ease-in-out; animation-fill-mode: forwards; } .userInfo_name { flex: 1; vertical-align: middle; width: 100%; margin-left: 5%; margin-top: 5%; font-size: 42rpx; } .userInfo { flex: 1; width: 100%; border-radius: 50%; overflow: hidden; max-height: 50px; max-width: 50px; margin-left: 5%; margin-top: 5%; border: 2px solid #fff; } [代码] 二、第二种效果 [图片] [代码]//index.wxml <view class="waveWrapper waveAnimation"> <view class="waveWrapperInner bgTop"> <view class="wave waveTop" style="background-image: url('https://s2.ax1x.com/2019/09/26/um8g7n.png')"></view> </view> <view class="waveWrapperInner bgMiddle"> <view class="wave waveMiddle" style="background-image: url('https://s2.ax1x.com/2019/09/26/umGZ38.png')"></view> </view> <view class="waveWrapperInner bgBottom"> <view class="wave waveBottom" style="background-image: url('https://s2.ax1x.com/2019/09/26/umGuuQ.png')"></view> </view> </view> //index.wxss .waveWrapper { overflow: hidden; position: absolute; left: 0; right: 0; height: 300px; top: 0; margin: auto; } .waveWrapperInner { position: absolute; width: 100%; overflow: hidden; height: 100%; bottom: -1px; background-image: linear-gradient(to top, #86377b 20%, #27273c 80%); } .bgTop { z-index: 15; opacity: 0.5; } .bgMiddle { z-index: 10; opacity: 0.75; } .bgBottom { z-index: 5; } .wave { position: absolute; left: 0; width: 500%; height: 100%; background-repeat: repeat no-repeat; background-position: 0 bottom; transform-origin: center bottom; } .waveTop { background-size: 50% 100px; } .waveAnimation .waveTop { animation: move-wave 3s; -webkit-animation: move-wave 3s; -webkit-animation-delay: 1s; animation-delay: 1s; } .waveMiddle { background-size: 50% 120px; } .waveAnimation .waveMiddle { animation: move_wave 10s linear infinite; } .waveBottom { background-size: 50% 100px; } .waveAnimation .waveBottom { animation: move_wave 15s linear infinite; } @keyframes move_wave { 0% { transform: translateX(0) translateZ(0) scaleY(1) } 50% { transform: translateX(-25%) translateZ(0) scaleY(0.55) } 100% { transform: translateX(-50%) translateZ(0) scaleY(1) } } [代码] 三、第三种效果 [图片] [代码]//index.wxml <view class="container"> <image class="title" src="https://ftp.bmp.ovh/imgs/2019/09/74bada9c4143786a.png"></image> <view class="content"> <view class="hd" style="transform:rotateZ({{angle}}deg);"> <image class="logo" src="https://ftp.bmp.ovh/imgs/2019/09/d31b8fcf19ee48dc.png"></image> <image class="wave" src="wave.png" mode="aspectFill"></image> <image class="wave wave-bg" src="wave.png" mode="aspectFill"></image> </view> <view class="bd" style="height: 100rpx;"> </view> </view> </view> //index.wxss image{ max-width:none; } .container { background: #7acfa6; align-items: stretch; padding: 0; height: 100%; overflow: hidden; } .content{ flex: 1; display: flex; position: relative; z-index: 10; flex-direction: column; align-items: stretch; justify-content: center; width: 100%; height: 100%; padding-bottom: 450rpx; background: -webkit-gradient(linear, left top, left bottom, from(rgba(244,244,244,0)), color-stop(0.1, #f4f4f4), to(#f4f4f4)); opacity: 0; transform: translate3d(0,100%,0); animation: rise 3s cubic-bezier(0.19, 1, 0.22, 1) .25s forwards; } @keyframes rise{ 0% {opacity: 0;transform: translate3d(0,100%,0);} 50% {opacity: 1;} 100% {opacity: 1;transform: translate3d(0,450rpx,0);} } .title{ position: absolute; top: 30rpx; left: 50%; width: 600rpx; height: 200rpx; margin-left: -300rpx; opacity: 0; animation: show 2.5s cubic-bezier(0.19, 1, 0.22, 1) .5s forwards; } @keyframes show{ 0% {opacity: 0;} 100% {opacity: .95;} } .hd { position: absolute; top: 0; left: 50%; width: 1000rpx; margin-left: -500rpx; height: 200rpx; transition: all .35s ease; } .logo { position: absolute; z-index: 2; left: 50%; bottom: 200rpx; width: 160rpx; height: 160rpx; margin-left: -80rpx; border-radius: 160rpx; animation: sway 10s ease-in-out infinite; opacity: .95; } @keyframes sway{ 0% {transform: translate3d(0,20rpx,0) rotate(-15deg); } 17% {transform: translate3d(0,0rpx,0) rotate(25deg); } 34% {transform: translate3d(0,-20rpx,0) rotate(-20deg); } 50% {transform: translate3d(0,-10rpx,0) rotate(15deg); } 67% {transform: translate3d(0,10rpx,0) rotate(-25deg); } 84% {transform: translate3d(0,15rpx,0) rotate(15deg); } 100% {transform: translate3d(0,20rpx,0) rotate(-15deg); } } .wave { position: absolute; z-index: 3; right: 0; bottom: 0; opacity: 0.725; height: 260rpx; width: 2250rpx; animation: wave 10s linear infinite; } .wave-bg { z-index: 1; animation: wave-bg 10.25s linear infinite; } @keyframes wave{ from {transform: translate3d(125rpx,0,0);} to {transform: translate3d(1125rpx,0,0);} } @keyframes wave-bg{ from {transform: translate3d(375rpx,0,0);} to {transform: translate3d(1375rpx,0,0);} } .bd { position: relative; flex: 1; display: flex; flex-direction: column; align-items: stretch; animation: bd-rise 2s cubic-bezier(0.23,1,0.32,1) .75s forwards; opacity: 0; } @keyframes bd-rise{ from {opacity: 0; transform: translate3d(0,60rpx,0); } to {opacity: 1; transform: translate3d(0,0,0); } } [代码] wave.png(可下载到本地) [图片] 在这个基础上,再加上js的代码,即可实现根据手机倾向,水波晃动的效果 wx.onAccelerometerChange(function callback) 监听加速度数据事件。 [图片] [代码]//index.js Page({ onReady: function () { var _this = this; wx.onAccelerometerChange(function (res) { var angle = -(res.x * 30).toFixed(1); if (angle > 14) { angle = 14; } else if (angle < -14) { angle = -14; } if (_this.data.angle !== angle) { _this.setData({ angle: angle }); } }); }, }); [代码] 四、第四种效果 [图片] [代码]//index.wxml <view class='page__bd'> <view class="bg-img padding-tb-xl" style="background-image:url('http://wx4.sinaimg.cn/mw690/006UdlVNgy1g2v2t1ih8jj31hc0p0qej.jpg');background-size:cover;"> <view class="cu-bar"> <view class="content text-bold text-white"> 悦拍屋 </view> </view> </view> <view class="shadow-blur"> <image src="https://raw.githubusercontent.com/weilanwl/ColorUI/master/demo/images/wave.gif" mode="scaleToFill" class="gif-black response" style="height:100rpx;margin-top:-100rpx;"></image> </view> </view> //index.wxss @import "colorui.wxss"; .gif-black { display: block; border: none; mix-blend-mode: screen; } [代码] 本效果需要引入ColorUI组件库
2019-09-26