|
HTML- <view wx:if="{{advertiseFlag}}" class="advertise-wrapper" style="background-color:{{transitionData.statusBtn == 'playing'?'rgba(255,255,255,0)':''}}" bindtap="jumpFn">
- <view class="advertise-box" style="width:{{transitionData.width}};height:{{transitionData.height}};left:{{transitionData.left}};top:{{transitionData.top}};opacity:{{transitionData.opacity}};animation:{{transitionData.animation}}">
- <image data-status="{{transitionData.statusBtn}}" catchtap="handleJumpValue" src="{{ advertiseMsg.url || 'https://yizhen-mamapai-dev.oss-cn-zhangjiakou.aliyuncs.com/certification/2024-06-13/b1791b525e974c0aae8a0c82a8410a9b.png'}}">
- </image>
- <view class="jump-box" catchtap="jumpFn" data-status="{{transitionData.statusBtn}}">
- 跳过{{defaultTime?defaultTime:''}}
- </view>
- </view>
- </view>
复制代码 CSS- .advertise-wrapper {
- width: 100%;
- height: 100vh;
- background: rgba(0, 0, 0, 0.75);
- position: fixed;
- top: 0;
- left: 0;
- z-index: 999;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .advertise-box {
- width: 580rpx;
- height: 980rpx;
- position: absolute;
- transition: all 1s linear;
- }
- @keyframes shrinkAndMoveToPosition {
- from {
- transform: scale(1);
- opacity: 1;
- }
- to {
- transform: scale(0.5);
- opacity: 0;
- }
- }
- .advertise-box image {
- width: 100%;
- height: 100%;
- }
- .jump-box {
- background: rgba(0, 0, 0, 0.8);
- border-radius: 10px;
- padding: 4rpx 16rpx;
- position: absolute;
- top: 20rpx;
- right: 20rpx;
- color: #fff;
- font-size: 12px;
- }
复制代码 JS
动画函数
options的参数- from : 起始值 比如:0
- to : 结束值 比如:100
- totalMS :变化总时间 比如: 1000
- duration : 每多少秒变化的次数 比如: 1
- onmove :开始移动的回调函数
- onend :移动结束的回调函数
复制代码- let timer;
- function createAnimation(option) {
- // 起始值、结束值、变化总时间
- var {
- from,
- to,
- totalMS,
- duration,
- onmove,
- onend
- } = option;
- totalMS = totalMS || 1000;
- duration = duration || 10; // 每多少时间变化一次
- var times = Math.floor(totalMS / duration); // 变化的次数
- var dis = (to - from) / times; // 每次变化的量
- var curTimes = 0;
- // 每次变化的函数
- var timer = setInterval(() => {
- from += dis;
- curTimes++;
- // 变化完成,这里保证onmove 在 onend以前执行
- if (curTimes >= times) {
- from = to;
- onmove && onmove(from);
- onend && onend();
- clearInterval(timer);
- return;
- }
- onmove && onmove(from);
- }, duration);
- }
复制代码 获取dom
我们点击跳转的时候,首先需要获取到当前点击 dom 的 status,如果当前的状态为 playing 直接 return,否则开始获取当前的 dom 信息,找到当前点击的 dom 和所要跳转到的 dom 所在位置,然后找到所要跳转的位置后,把当前点击的dom和所要去的dom传给开始的动画函数- handleGetDom(type) {
- if (!type || type <= 0) return
- let _this = this
- wx.createSelectorQuery().select('.advertise-box').boundingClientRect()
- .selectAll('.grid-container .item').boundingClientRect().exec((ret) => {
- const [popRect, endDoms] = ret;
- const targetIndex = endDoms.findIndex((item) => item.id == type);
- if (targetIndex === -1) return;
- const endDom = endDoms[targetIndex];
- _this.startTransition(popRect, endDom);
- })
- },
复制代码 开始动画过渡
根据获取 dom 和所要去的 dom 的位置,在拿到要结束 dom 之前先把 status 状态设置为 playing ,这样后我们就可以设置动画效果然后把对应的参数传给动画函数 createAnimation 。- // 开始动画过渡
- startTransition(popRect, endDom) {
- const _this = this;
- // 设置点击状态为playing
- _this.setData({
- transitionData: {
- ..._this.data.transitionData,
- statusBtn: 'playing'
- }
- });
- const centerX = endDom.left
- const centerY = endDom.top
- _this.setData({
- transitionData: {
- ..._this.data.transitionData,
- animation: "shrinkAndMoveToPosition 2s forwards"
- }
- });
- createAnimation({
- from: popRect.left,
- to: centerX,
- totalMS: 1000,
- onmove: (n) => {
- _this.updateTransitionData(endDom, centerX, centerY);
- },
- onend: () => {
- _this.endTransition(endDom);
- }
- });
- },
复制代码 动画的更新函数
这个地方需要注意的是在支付宝中 left、top 不用需要加 px,width和height自行决定用不用除以2- // 更新动画过程中的数据
- updateTransitionData(endDom, centerX, centerY) {
- this.setData({
- transitionData: {
- ...this.data.transitionData,
- width: `${endDom.width / 2}px`,
- height: `${endDom.height / 2}px`,
- left: `${centerX}px`,
- top: `${centerY}px`
- }
- });
- },
复制代码 动画的结束函数
在动画结束的时候我们需要把 status 更改为 end , opacity 设置为 0,清除定时器就可以了- // 结束动画并处理跳转
- endTransition(endDom) {
- const _this = this;
- wx.showTabBar();
- _this.setData({
- transitionData: {
- ..._this.data.transitionData,
- statusBtn: 'end',
- opacity: 0
- },
- advertiseFlag: false
- });
- clearInterval(timer);
- const currItem = {
- ...endDom.dataset.item,
- richTextType: 2,
- appletAdvertisementId: endDom.dataset.item.type
- }
- _this.handleJumpTypePage(currItem);
- },
复制代码 动画所有相关的事件函数- // 跳转类型 handleJumpValue(e) { let { relationHomeSwitch, relationHomeType, id } = this.data.advertisingPopup this.handleClickDataSave(id) if (relationHomeType && relationHomeSwitch == 1) { let status = e.currentTarget.dataset.status // 判断是否有点击过 statusBtn if (status == 'playing') return; this.handleGetDom(relationHomeType) } else if (relationHomeSwitch == 2) { let data = { ...this.data.advertisingPopup, richTextType: 3, } this.handleJumpTypePage(data) } else { wx.showTabBar(); this.setData({ advertiseFlag: false }); clearInterval(timer); } }, // 获取dom handleGetDom(type) {
- if (!type || type <= 0) return
- let _this = this
- wx.createSelectorQuery().select('.advertise-box').boundingClientRect()
- .selectAll('.grid-container .item').boundingClientRect().exec((ret) => {
- const [popRect, endDoms] = ret;
- const targetIndex = endDoms.findIndex((item) => item.id == type);
- if (targetIndex === -1) return;
- const endDom = endDoms[targetIndex];
- _this.startTransition(popRect, endDom);
- })
- }, // 开始动画过渡
- startTransition(popRect, endDom) {
- const _this = this;
- // 设置点击状态为playing
- _this.setData({
- transitionData: {
- ..._this.data.transitionData,
- statusBtn: 'playing'
- }
- });
- const centerX = endDom.left
- const centerY = endDom.top
- _this.setData({
- transitionData: {
- ..._this.data.transitionData,
- animation: "shrinkAndMoveToPosition 2s forwards"
- }
- });
- createAnimation({
- from: popRect.left,
- to: centerX,
- totalMS: 1000,
- onmove: (n) => {
- _this.updateTransitionData(endDom, centerX, centerY);
- },
- onend: () => {
- _this.endTransition(endDom);
- }
- });
- }, // 更新动画过程中的数据
- updateTransitionData(endDom, centerX, centerY) {
- this.setData({
- transitionData: {
- ...this.data.transitionData,
- width: `${endDom.width / 2}px`,
- height: `${endDom.height / 2}px`,
- left: `${centerX}px`,
- top: `${centerY}px`
- }
- });
- }, // 结束动画并处理跳转
- endTransition(endDom) {
- const _this = this;
- wx.showTabBar();
- _this.setData({
- transitionData: {
- ..._this.data.transitionData,
- statusBtn: 'end',
- opacity: 0
- },
- advertiseFlag: false
- });
- clearInterval(timer);
- const currItem = {
- ...endDom.dataset.item,
- richTextType: 2,
- appletAdvertisementId: endDom.dataset.item.type
- }
- _this.handleJumpTypePage(currItem);
- }, // 点击 handleHomeConfigClick(id) { let params = { id: id } api.post('/main-service/home-config/click', params).then((res) => { if (res.code == 1) { console.log(res, 'res'); } }).catch((err) => { console.log(err, 'err'); }) }, jumpFn() { wx.showTabBar(); this.setData({ advertiseFlag: false }); clearInterval(timer); }, // 动画end
复制代码 完整实现代码- // pages/prize/prize.jsconst api = require('../../common/api')const App = getApp()const getAuthCode = require('../../common/authen.js').getAuthCodelet timer;let count = 0;function createAnimation(option) { // 起始值、结束值、变化总时间 var { from, to, totalMS, duration, onmove, onend } = option; totalMS = totalMS || 1000; duration = duration || 10; // 没多少时间变化一次 var times = Math.floor(totalMS / duration); // 变化的次数 var dis = (to - from) / times; // 每次变化的量 var curTimes = 0; // 每次变化的函数 var timer = setInterval(() => { from += dis; curTimes++; // 变化完成,这里保证onmove 在 onend以前执行 if (curTimes >= times) { from = to; onmove && onmove(from); onend && onend(); clearInterval(timer); return; } onmove && onmove(from); }, duration);}Page({ data: { transitionData: { statusBtn: '', // 是否已经点击过 left: '', top: '', width: '580rpx', height: '980rpx', opacity: 1 }, marketingId: "", // 营销id styleConfigData: {}, imgSrc: [], paramStr: '', indicatorDots: false, autoplay: true, vertical: false, interval: 2000, circular: true, duration: 1500, defaultTime: 4, //默认时间 advertiseFlag: false, advertiseMsg: {}, activityData: { sourceType: '' }, styleHomeImage: {}, activeIndex: "", // 切换下标 interval: 3000, advertisingRotation: [], // 广告位轮播 newHomepage: [], }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { // this.getImage() // this.getStyleConfig() this.getAuth() this.getHomeConfigPage() this.handleGetAxiosData() this.getAdvertisement() }, onShow() { let token = wx.getStorageSync('token') if (App.globalData.activityData.sourceType == 'activity' && App.globalData.inviteCustomerNum < 2 && token) { this.handleActivity() } }, handleActivity() { const params = App.globalData.activityData api.post('/main-service/customer-invite-record', params).then((res) => { if (res.code === 1) { console.log('邀请处理成功') App.globalData.inviteCustomerNum = 2 } if (res.code == 1010002) { console.log('邀请处理失败') App.globalData.inviteCustomerNum = 1 } }) }, // 获取首页头部配置 getHomeConfigPage() { api.get("/main-service/home-config/list").then((res) => { if (res.code == 1) { let originalHomepage = res.data && res.data.sort((a, b) => { return a.type - b.type }) || [] // 处理数据,添加额外属性用于渲染 const processedHomepage = originalHomepage.map(item => { return { ...item, shouldDisplay: this.shouldDisplayItem(item), className: this.getClassByType(item.type), imageMode: this.getImageMode(item.type), showMenu: item.type >= 5, defaultImage: this.getDefaultImage(item.type) }; }); this.setData({ newHomepage: processedHomepage }) } }).catch((err) => { console.log(err, 'err'); }) }, // 获取页面样式配置 getStyleConfig() { api.get('/main-service/activity_style_config').then((res) => { if (res.code === 1) { const { data } = res this.setData({ styleConfigData: { ...data, topImg: res.data.imgUrl.split(",")[0], bottomImg: res.data.imgUrl.split(",")[1], } }) } }) }, //数据 handleGetAxiosData() { let params = { type: 39 } api.get(`/main-service/sys/info`, params).then((res) => { console.log(res, 'res') if (res.code == 1) { this.setData({ styleHomeImage: res.data.remark ? JSON.parse(res.data.remark) : {}, }) } }) }, getImage() { api.get('/main-service/home-page/advertising').then(res => { this.setData({ imgSrc: res.data.weChatBackgroundUrl }) }) }, // 获取 广告位轮播图 getAdvertisement() { const params = { position: 1 } api.get('/main-service/advertisement', params).then((res) => { if (res.code == 1) { this.setData({ advertisingRotation: res.data }) } }) }, // 改变图片 changeImg(e) { this.activeIndex = e.detail.current this.setData({ activeIndex: e.detail.current }) }, getAuth() { getAuthCode().then(res => { let authCode = res.authCode; let params = { code: authCode }; this.getAdvertiseMsg(params); }); }, //获取弹窗广告信息 getAdvertiseMsg(params) { api.get("/main-service/applet-advertisement/v2", params).then(res => { if (res.code == 1) { this.setData({ advertiseFlag: res.data.status == 1 ? true : false, advertiseMsg: res.data, advertisingPopup: { ...res.data } }); if (res.data.id) { wx.hideTabBar(); } if (res.data.status == 1) { timer = setInterval(() => { if (this.data.defaultTime > 0) { let time = (this.data.defaultTime -= 1); this.setData({ defaultTime: time }); return; } if (!this.data.defaultTime) { clearInterval(timer); this.isLike(); } }, 1000); } } }); }, //是否感兴趣 isLike() { let id = this.data.advertiseMsg.id; if (id) { api.get(`/main-service/applet-advertisement/${id}`).then(res => { if (res.code == 1) { console.log("感兴趣"); } }); } }, // 跳转详情 handleJumpDetails(item) { let { id, jumpType } = item.currentTarget.dataset.value if (jumpType == 13) { wx.navigateTo({ url: `/addressManagement/pages/richText/richText?jumpId=${id}` }); } }, // 页面跳转 handleJumpToPage(e) { let { item } = e.currentTarget.dataset this.handleHomeConfigClick(item.id) wx.hideLoading() let data = { ...item, richTextType: 2, appletAdvertisementId: item.type } wx.hideLoading() this.handleJumpTypePage(data) }, // 根据跳转类型处理页面跳转 handleJumpTypePage(item) { const jumpType = Number(item.jumpType); this.jumpFn() const routes = { 1: () => this.handlePageTo(), 2: () => wx.navigateTo({ url: "/addressManagement/pages/invitingWithCourtesy/invitingWithCourtesy" }), 3: () => wx.navigateTo({ url: `/addressManagement/pages/invitationGiftDetail/invitationGiftDetail?id=${item.jumpValue}` }), 4: () => wx.switchTab({ url: '/pages/activity/activity' }), 5: () => wx.navigateTo({ url: `/pages/activityDetail/activityDetail?activityId=${item.jumpValue}` }), 6: () => wx.navigateTo({ url: `/addressManagement/pages/richText/richText?jumpId=${item.appletAdvertisementId}&type=${item.richTextType}` }), // 7: () => wx.navigateTo({ url: `/pages/content-detail/content-detail?id=${item.jumpValue}&type=1` }), // 8: () => wx.navigateTo({ url: `/pages/content-detail/content-detail?id=${item.jumpValue}&type=3` }), 9: () => wx.navigateTo({ url: `/addressManagement/pages/richText/richText?jumpId=${item.appletAdvertisementId}&status=btn&type=${item.richTextType}` }), 10: () => wx.navigateTo({ url: `/addressManagement/pages/marketing/marketing?id=${item.type}&type=home` }), }; if (routes[jumpType]) { routes[jumpType](); } }, // 点击数据 handleClickDataSave(id) { let params = { appletAdvertisementCustomerRecordId: id } api.get('/main-service/applet-advertisement/save-click-data', params).then((res) => { if (res.code == 1) { console.log(res, 'res'); } }).catch((err) => { console.log(err, 'err'); }) }, // 跳转类型 handleJumpValue(e) { let { relationHomeSwitch, relationHomeType, id } = this.data.advertisingPopup this.handleClickDataSave(id) if (relationHomeType && relationHomeSwitch == 1) { let status = e.currentTarget.dataset.status // 判断是否有点击过 statusBtn if (status == 'playing') return; this.handleGetDom(relationHomeType) } else if (relationHomeSwitch == 2) { let data = { ...this.data.advertisingPopup, richTextType: 3, } this.handleJumpTypePage(data) } else { wx.showTabBar(); this.setData({ advertiseFlag: false }); clearInterval(timer); } }, // 获取dom handleGetDom(type) {
- if (!type || type <= 0) return
- let _this = this
- wx.createSelectorQuery().select('.advertise-box').boundingClientRect()
- .selectAll('.grid-container .item').boundingClientRect().exec((ret) => {
- const [popRect, endDoms] = ret;
- const targetIndex = endDoms.findIndex((item) => item.id == type);
- if (targetIndex === -1) return;
- const endDom = endDoms[targetIndex];
- _this.startTransition(popRect, endDom);
- })
- }, // 开始动画过渡
- startTransition(popRect, endDom) {
- const _this = this;
- // 设置点击状态为playing
- _this.setData({
- transitionData: {
- ..._this.data.transitionData,
- statusBtn: 'playing'
- }
- });
- const centerX = endDom.left
- const centerY = endDom.top
- _this.setData({
- transitionData: {
- ..._this.data.transitionData,
- animation: "shrinkAndMoveToPosition 2s forwards"
- }
- });
- createAnimation({
- from: popRect.left,
- to: centerX,
- totalMS: 1000,
- onmove: (n) => {
- _this.updateTransitionData(endDom, centerX, centerY);
- },
- onend: () => {
- _this.endTransition(endDom);
- }
- });
- }, // 更新动画过程中的数据
- updateTransitionData(endDom, centerX, centerY) {
- this.setData({
- transitionData: {
- ...this.data.transitionData,
- width: `${endDom.width / 2}px`,
- height: `${endDom.height / 2}px`,
- left: `${centerX}px`,
- top: `${centerY}px`
- }
- });
- }, // 结束动画并处理跳转
- endTransition(endDom) {
- const _this = this;
- wx.showTabBar();
- _this.setData({
- transitionData: {
- ..._this.data.transitionData,
- statusBtn: 'end',
- opacity: 0
- },
- advertiseFlag: false
- });
- clearInterval(timer);
- const currItem = {
- ...endDom.dataset.item,
- richTextType: 2,
- appletAdvertisementId: endDom.dataset.item.type
- }
- _this.handleJumpTypePage(currItem);
- }, // 点击 handleHomeConfigClick(id) { let params = { id: id } api.post('/main-service/home-config/click', params).then((res) => { if (res.code == 1) { console.log(res, 'res'); } }).catch((err) => { console.log(err, 'err'); }) }, jumpFn() { wx.showTabBar(); this.setData({ advertiseFlag: false }); clearInterval(timer); }, // 动画end handlePageTo: function () { let that = this wx.showLoading({ title: '加载中', mask: true }) this.checkAttestation() // that.getUserInfo() }, // getUserInfo() { // let that = this // getAuthCode().then((res) => { // const { // authCode // } = res // let params = { // loginType: 7, // isRelatedPhoneNumber: 0, // grantCode: authCode // } // api.post('/main-service/customer/login', params).then(({ // data // }) => { // const { // isRelatedPhoneNumber, // phoneNumber, // token // } = data // if (isRelatedPhoneNumber == 0) { // wx.hideLoading() // wx.reLaunch({ // url: '/pages/login/login?sourceType=prize' // }); // return // } // if (isRelatedPhoneNumber == 1) { // wx.hideLoading() // wx.setStorageSync('token', token) // that.checkAttestation() // return // } // }) // }) // }, checkAttestation() { api.get('/main-service/pregnant-certification/status').then(({ data }) => { wx.hideLoading() const { isWhite, isSellOut, status, identityType, isSyncTaoBao } = data if (isWhite == 0) { if (status == 0) { // 跳转认证页面 wx.navigateTo({ url: '/pages/authentication/authentication' }) } if (status == 1) { // 跳转认证中 wx.navigateTo({ url: '/pages/AddCustomer/AddCustomer' }) } if (status == 2) { // 打开领取链接 if (isSellOut) { // 礼品售罄 // "identityType": 1:孕妈 2:宝妈 if (!isSyncTaoBao) { wx.navigateTo({ url: '/pages/sellOut/sellOut' }) // if (identityType == 1) { // wx.navigateTo({ // url: '/pages/sellOut/sellOut' // }) // } // if (identityType == 2) { // wx.navigateTo({ // url: `/pages/certificationPassed/certificationPassed` // }) // } } else { // 修改之后的逻辑 wx.navigateTo({ url: `/pages/giftGuide/giftGuide?status=${status}` }) } } else { wx.navigateTo({ url: `/pages/giftGuide/giftGuide?status=${status}` }) // if (identityType == 1) { // wx.navigateTo({ // url: `/pages/giftGuide/giftGuide?status=${status}` // }) // } // if (identityType == 2) { // wx.navigateTo({ // url: `/pages/certificationPassed/certificationPassed` // }) // } } } if (status == 3) { // 跳转拒绝页面 wx.navigateTo({ url: '/pages/certificationReject/certificationReject' }) } if (status == 4) { // 跳转退回页面重新编辑 wx.navigateTo({ url: `/pages/authentication/authentication?status=${status}` }) } } if (isWhite == 1) { if (isSellOut) { wx.navigateTo({ url: '/pages/sellOut/sellOut' }) } else { wx.navigateTo({ url: `/pages/giftGuide/giftGuide?status=${status}` }) } } }) }, handleClickBanner() { wx.navigateTo({ url: '/addressManagement/pages/bannerDetail/bannerDetail', }) }, // 跳转会场 handleToShare() { wx.navigateTo({ url: `/addressManagement/pages/taobaoVenue/taobaoVenue?type=home`, }); }, // 开启分享 onShareAppMessage() {}, // 判断是否展示该 item shouldDisplayItem(item) { if (item.type >= 5 && item.showSwitch !== 1) return false; return !!item.url || item.type <= 4; // 当 type 小于等于 4 时总是展示 }, // 根据 type 返回对应的类名 getClassByType(type) { switch (type) { case 1: return 'new-mom-gift'; case 2: return 'xhs-volunteer'; case 3: return 'douyin-volunteer'; case 4: return 'invitation-gift'; case 5: return 'advertising-space-one'; case 6: return 'advertising-space-two'; case 7: return 'advertising-space-three'; default: return ''; } }, // 根据 type 返回图片的 mode getImageMode(type) { return type >= 5 ? 'widthFix' : 'scaleToFill'; }, // 获取默认图片 URL getDefaultImage(type) { return 'https://yizhen-mamapai-dev.oss-cn-zhangjiakou.aliyuncs.com/certification/2024-06-13/3cb773c6e3614c389619a24d55f868d4.png'; }, onPullDownRefresh() { Promise.all([this.getHomeConfigPage()]).then(res => { this.stopPullDownRefresh(); }); }, onUnload() { this.jumpFn() },})
复制代码 到此这篇关于微信/支付宝小程序实现弹窗动画缩放到某个位置的文章就介绍到这了,更多相关弹窗动画缩放到某个位置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
来源:https://www.jb51.net/javascript/328938mcf.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|