Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mayi-mp-shop
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
程默
mayi-mp-shop
Commits
be7aa12c
Commit
be7aa12c
authored
Mar 10, 2021
by
李嘉林
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
拼团组件
parent
168e2e23
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1313 additions
and
4 deletions
+1313
-4
src/components/activity/spellGroup/goodsItem.vue
+0
-0
src/components/activity/spellGroup/index.vue
+0
-0
src/components/activity/spellGroup/mixin/computed.js
+153
-0
src/components/content/information/articleItem.vue
+2
-2
src/pages/home/index.vue
+7
-1
src/pages/home/main.json
+2
-1
static/nativeComponents/spellGroup/GoodsItem/index.js
+140
-0
static/nativeComponents/spellGroup/GoodsItem/index.json
+6
-0
static/nativeComponents/spellGroup/GoodsItem/index.wxml
+164
-0
static/nativeComponents/spellGroup/GoodsItem/index.wxss
+364
-0
static/nativeComponents/spellGroup/heapItem/index.js
+107
-0
static/nativeComponents/spellGroup/heapItem/index.json
+6
-0
static/nativeComponents/spellGroup/heapItem/index.wxml
+22
-0
static/nativeComponents/spellGroup/heapItem/index.wxss
+79
-0
static/nativeComponents/spellGroup/heapItem/utils/touchEvent.js
+261
-0
No files found.
src/components/activity/spellGroup/goodsItem.vue
0 → 100644
View file @
be7aa12c
This diff is collapsed.
Click to expand it.
src/components/activity/spellGroup/index.vue
0 → 100644
View file @
be7aa12c
This diff is collapsed.
Click to expand it.
src/components/activity/spellGroup/mixin/computed.js
0 → 100644
View file @
be7aa12c
const
app
=
getApp
();
export
default
{
computed
:
{
getBorderRadius
()
{
return
this
.
datas
.
componentData
.
borderRadius
==
undefined
?
0.625
:
this
.
datas
.
componentData
.
borderRadius
;
},
goodsSort
()
{
return
this
.
datas
.
componentData
.
goodsSort
||
0
;
},
// 会员价
vipPrice
()
{
return
this
.
datas
.
componentData
.
vipPrice
||
false
;
},
whetherFindDistributionCommission
()
{
return
this
.
datas
.
componentData
.
whetherFindDistributionCommission
?
1
:
0
;
},
categoryId
()
{
return
this
.
datas
.
componentData
.
categoryId
?
this
.
datas
.
componentData
.
categoryId
:
""
;
},
// 关注人数样式
followerColor
()
{
return
this
.
datas
.
componentData
.
followerColor
?
this
.
datas
.
componentData
.
followerColor
:
"#ff9933"
;
},
// 佣金文字颜色
commissionColor
()
{
return
this
.
datas
.
componentData
.
commissionColor
?
this
.
datas
.
componentData
.
commissionColor
:
"#ff9051"
;
},
//佣金背景颜色
commissionBgColor
()
{
return
this
.
datas
.
componentData
.
commissionBgColor
?
this
.
datas
.
componentData
.
commissionBgColor
:
""
;
},
// 按钮图标
btnIcon
()
{
return
this
.
datas
.
componentData
.
btnIcon
?
this
.
datas
.
componentData
.
btnIcon
:
""
;
},
// 按钮类型
btnType
()
{
return
this
.
datas
.
componentData
.
btnType
?
this
.
datas
.
componentData
.
btnType
:
6
;
},
// 按钮颜色
btnColor
()
{
return
this
.
datas
.
componentData
.
btnColor
?
this
.
datas
.
componentData
.
btnColor
:
"var(--main-color)"
;
},
// 按钮文案
btnTest
()
{
return
this
.
datas
.
componentData
.
btnTest
?
this
.
datas
.
componentData
.
btnTest
:
"立即购买"
;
},
getItemNum
()
{
return
this
.
datas
.
componentData
.
goodsList
;
},
getPaddingList
()
{
return
this
.
datas
.
componentData
.
paddingList
;
},
getColumnWidth
()
{
if
(
this
.
datas
.
componentData
.
columnNum
==
1
)
{
return
"100%"
;
}
else
if
(
this
.
datas
.
componentData
.
columnNum
==
2
)
{
return
"50%"
;
}
else
{
return
"33.3%"
;
}
},
getPayFontSize
()
{
if
(
this
.
datas
.
componentData
.
columnNum
==
1
)
{
return
"12px"
;
}
else
if
(
this
.
datas
.
componentData
.
columnNum
==
2
)
{
return
"10px"
;
}
else
{
return
"8px"
;
}
},
getListPadding
()
{
if
(
this
.
datas
.
componentData
.
columnNum
==
1
)
{
return
""
;
}
else
if
(
this
.
datas
.
componentData
.
columnNum
==
2
)
{
return
(
"0 "
+
this
.
datas
.
componentData
.
proGap
/
2
+
"px"
+
" 0 "
+
this
.
datas
.
componentData
.
proGap
/
2
+
"px"
);
}
else
{
return
"33.3%"
;
}
},
whetherShowSoldOutGoods
()
{
// 商城端接口的获取商城配置信息
// if (this.render) {
// return this.$store.state.setShopConfig.whetherShowSoldOutGoods || 1;
// } else {
// return 1;
// }
return
1
;
},
goodsType
()
{
return
this
.
datas
.
componentData
.
goodsType
||
0
;
},
// 展示标题图片
titleIcon
()
{
return
app
.
DFSImg
(
this
.
datas
.
componentData
.
titleIcon
,
400
,
400
)
||
""
;
},
// 展示角标
angleSign
()
{
return
this
.
datas
.
componentData
.
angleSign
||
false
;
},
// 角标尺寸
angleSignSize
()
{
return
this
.
datas
.
componentData
.
angleSignSize
||
25
;
},
// 展示角标图片
angleSignImg
()
{
return
this
.
datas
.
componentData
.
angleSignImg
||
""
;
},
// 展示营销标签
marketingTag
()
{
return
this
.
datas
.
componentData
.
marketingTag
||
false
;
},
// 展示营销标签类型
marketingStyle
()
{
return
this
.
datas
.
componentData
.
marketingStyle
||
0
;
},
// 营销标签列表
marketingTagList
()
{
return
this
.
datas
.
componentData
.
marketingTagList
||
[];
},
cardShadowSize
()
{
return
this
.
datas
.
componentData
.
cardShadowSize
?
this
.
datas
.
componentData
.
cardShadowSize
:
3
;
}
}
};
\ No newline at end of file
src/components/content/information/articleItem.vue
View file @
be7aa12c
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
<span
class=
"tagName"
>
{{
item
.
tagName
}}
</span>
<span
class=
"tagName"
>
{{
item
.
tagName
}}
</span>
</div>
</div>
</div>
</div>
<image
:src=
"info.coverUrl"
mode=
"widthFix"
></image>
<image
:src=
"info.coverUrl"
mode=
"widthFix"
lazy-load
></image>
</div>
</div>
<div
class=
"infoText"
>
<div
class=
"infoText"
>
<p
<p
...
@@ -70,7 +70,7 @@
...
@@ -70,7 +70,7 @@
<span
class=
"tagName"
>
{{
item
.
tagName
}}
</span>
<span
class=
"tagName"
>
{{
item
.
tagName
}}
</span>
</div>
</div>
</div>
</div>
<image
:src=
"info.coverUrl"
mode=
"widthFix"
></image>
<image
:src=
"info.coverUrl"
lazy-load
mode=
"widthFix"
></image>
</div>
</div>
</div>
</div>
</
template
>
</
template
>
...
...
src/pages/home/index.vue
View file @
be7aa12c
...
@@ -84,6 +84,10 @@
...
@@ -84,6 +84,10 @@
<div
v-if=
"item.componentCode == 'merchants-list' && item.componentInfo.visible == 1"
>
<div
v-if=
"item.componentCode == 'merchants-list' && item.componentInfo.visible == 1"
>
<merchants-list
class=
"goodsListItem"
:datas=
"item"
></merchants-list>
<merchants-list
class=
"goodsListItem"
:datas=
"item"
></merchants-list>
</div>
</div>
<div
v-if=
"item.componentCode == 'spell-group' && item.componentInfo.visible == 1"
>
<spell-group
:datas=
"item"
></spell-group>
</div>
</div>
</div>
<bottomCont></bottomCont>
<bottomCont></bottomCont>
</div>
</div>
...
@@ -105,6 +109,7 @@ import text from '@/components/content/text'
...
@@ -105,6 +109,7 @@ import text from '@/components/content/text'
import
imgText
from
'@/components/content/imgText'
import
imgText
from
'@/components/content/imgText'
import
coupon
from
'@/components/activity/coupon'
import
coupon
from
'@/components/activity/coupon'
import
integralTurntable
from
'@/components/activity/integralTurntable'
import
integralTurntable
from
'@/components/activity/integralTurntable'
import
spellGroup
from
'@/components/activity/spellGroup'
import
{
setTabBarActive
,
checkTabbarPage
,
themeColor
}
from
"../../utils/mayi.js"
;
import
{
setTabBarActive
,
checkTabbarPage
,
themeColor
}
from
"../../utils/mayi.js"
;
import
{
throttle
}
from
"../../utils/index.js"
import
{
throttle
}
from
"../../utils/index.js"
const
app
=
getApp
();
const
app
=
getApp
();
...
@@ -134,7 +139,8 @@ export default {
...
@@ -134,7 +139,8 @@ export default {
coupon
,
coupon
,
integralTurntable
,
integralTurntable
,
transverseLabel
,
transverseLabel
,
information
information
,
spellGroup
},
},
onShareAppMessage
(
res
)
{
onShareAppMessage
(
res
)
{
let
shareVal
=
{};
let
shareVal
=
{};
...
...
src/pages/home/main.json
View file @
be7aa12c
...
@@ -19,7 +19,8 @@
...
@@ -19,7 +19,8 @@
"photo-gallery"
:
"/static/nativeComponents/PhotoGallery/index"
,
"photo-gallery"
:
"/static/nativeComponents/PhotoGallery/index"
,
"live-broadcast"
:
"/static/nativeComponents/LiveBroadcast/index"
,
"live-broadcast"
:
"/static/nativeComponents/LiveBroadcast/index"
,
"share-picture"
:
"/static/nativeComponents/SharePicture/index"
,
"share-picture"
:
"/static/nativeComponents/SharePicture/index"
,
"merchants-list"
:
"/static/nativeComponents/MerchantsList/index"
"merchants-list"
:
"/static/nativeComponents/MerchantsList/index"
,
"spell-group-heap-item"
:
"/static/nativeComponents/spellGroup/heapItem/index"
},
},
"enablePullDownRefresh"
:
true
,
"enablePullDownRefresh"
:
true
,
"backgroundColor"
:
"#f5f5f5"
"backgroundColor"
:
"#f5f5f5"
...
...
static/nativeComponents/spellGroup/GoodsItem/index.js
0 → 100644
View file @
be7aa12c
const
app
=
getApp
();
const
{
goodsApi
,
DFSImg
,
$themeToLink
,
$themeAddToCard
}
=
app
;
const
componentOptions
=
{
// 组件选项
options
:
{
multipleSlots
:
true
},
behaviors
:
[],
properties
:
{
datas
:
{
type
:
Object
},
items
:
{
type
:
Object
},
indexs
:
{
type
:
Number
}
},
// 组件数据
data
:
{
isPageHidden
:
false
,
// 页面是否处于隐藏状态
timeData
:
{}
},
// 数据监听器
observers
:
{},
// 组件方法
methods
:
{
init
()
{},
getSaleTime
(
val
)
{
return
new
Date
(
val
.
replace
(
/-/g
,
"/"
)).
getTime
()
-
new
Date
().
getTime
();
},
showVipPrice
(
index
)
{
// 索引 0 显示价格 1显示名称
let
showFlag
=
false
;
let
vipPrice
=
this
.
items
[
"minPriceAfterRecommendedCardPriceTable"
];
if
(
vipPrice
&&
Number
(
vipPrice
)
<
Number
(
this
.
items
[
"minPrice"
]))
{
showFlag
=
true
;
}
console
.
log
(
showFlag
,
"------------760"
);
return
showFlag
;
},
showVipTag
(
index
)
{
// 索引 0 显示价格 1显示名称
let
showFlag
=
false
;
let
vipPrice
=
this
.
items
[
"minPriceAfterRecommendedCardPriceTable"
];
let
showTag
=
this
.
items
[
"recommendedCardMinPricePriceTableName"
];
if
(
vipPrice
&&
showTag
&&
Number
(
vipPrice
)
<=
Number
(
this
.
items
[
"minPrice"
])
)
{
showFlag
=
true
;
}
return
showFlag
;
},
onChange
(
e
)
{
this
.
setData
({
timeData
:
e
.
detail
});
},
onclickProduct
()
{
let
{
goodsType
}
=
this
.
data
.
datas
.
componentData
;
let
{
productId
,
terminalProductId
,
terminalGoodsMixId
}
=
this
.
data
.
items
;
let
linkVal
=
""
;
if
(
goodsType
==
0
)
{
linkVal
=
`/goods/
${
productId
}
?terminalProductId=
${
terminalProductId
}
`
;
}
else
if
(
goodsType
==
1
)
{
linkVal
=
`/pointShop/goodsDetail?productId
${
productId
}
&terminalProductId=
${
terminalProductId
}
&terminalGoodsMixId=
${
terminalGoodsMixId
}
`
;
}
$themeToLink
({
type
:
1
,
link
:
linkVal
});
},
onclickBuynow
()
{
let
{
btnType
}
=
this
.
data
.
datas
.
componentData
;
let
{
minProductGoodsMixid
,
minProductGoodsId
,
minGoodsId
}
=
this
.
data
.
items
;
let
linkVal
=
""
;
if
(
btnType
<
6
)
{
// 加入购物车
console
.
log
(
"加入购物车"
);
$themeAddToCard
(
this
.
data
.
items
);
}
else
{
// 进入确认订单
linkVal
=
`/order/orderConfirm?productGoodsMixId=
${
minProductGoodsMixid
}
&productGoodsId=
${
minProductGoodsId
}
&goodsId=
${
minGoodsId
}
&qty=1&goodsString=null&source=3`
;
}
console
.
log
(
linkVal
,
"-------90"
);
$themeToLink
({
type
:
1
,
link
:
linkVal
});
},
toMerchants
()
{
let
{
orgId
}
=
this
.
data
.
items
;
$themeToLink
({
type
:
1
,
link
:
`/merchantsDetail/
${
orgId
}
`
});
},
},
// 组件生命周期
lifetimes
:
{
created
()
{},
attached
()
{
this
.
init
();
},
ready
()
{},
moved
()
{},
detached
()
{}
},
definitionFilter
()
{},
// 页面生命周期
pageLifetimes
:
{
// 页面被展示
show
()
{
const
{
isPageHidden
}
=
this
.
data
;
// show事件发生前,页面不是处于隐藏状态时
if
(
!
isPageHidden
)
{
return
;
}
// 重新执行定时器等操作
},
// 页面被隐藏
hide
()
{
this
.
setData
({
isPageHidden
:
true
});
// 清除定时器等操作
},
// 页面尺寸变化时
resize
()
{}
}
};
Component
(
componentOptions
)
static/nativeComponents/spellGroup/GoodsItem/index.json
0 → 100644
View file @
be7aa12c
{
"component"
:
true
,
"usingComponents"
:
{
"van-count-down"
:
"/static/vant/count-down/index"
}
}
static/nativeComponents/spellGroup/GoodsItem/index.wxml
0 → 100644
View file @
be7aa12c
<!-- 商品列表item -->
<view
class="goodsItem {{datas.componentData.style==='rowList'?'goodsRowList':''}} {{datas.componentData.style==='heap'?'goodsRowList goodsHeapItem':''}}"
style="--proGap2:{{datas.componentData.proGap*2}}rpx;"
bindtap="onclickProduct"
>
<view class="goods-item-child {{datas.componentData['borderColorShow']?'goods-item-child-bd':''}}" style="border-radius:{{datas.componentData.borderRadius}}em;--border_color:{{datas.componentData['borderColor']}};box-shadow:{{datas.componentData['cardShadow']?'0rpx 0rpx 10rpx '+datas.componentData['cardShadowSize']*2+'rpx #ccc':''}};">
<!-- 商品图片 -->
<view class="imgBox" style="background-color:{{datas.componentData['backgroundColorShow']?datas.componentData['backgroundColor']:''}}">
<view
class="goodsPicture"
wx:if="{{items!=null}}"
style="padding:{{datas.componentData.imgSize}}"
>
<!-- 显示拼团数 -->
<view class="have-group" wx:if="{{datas.componentData['haveGroupShow']&& (items && items['groupBuyFlag'] == '1')}}">{{items.haveGroupNum?items.haveGroupNum:0}}人已团</view>
<!-- 商品角标 -->
<view
class="angleSign"
style="width:{{datas.componentData.angleSignSize}}%;height:{{datas.componentData.angleSignSize}}%;"
wx:if="{{datas.componentData['angleSign'] && datas.componentData['angleSignImg']}}"
>
<image mode="widthFix" src="{{datas.componentData['angleSignImg']}}" />
</view>
<!-- 商品主图 -->
<image
lazy-load
mode="{{datas.componentData.style==='rowList' || datas.componentData.style==='heap'?'aspectFit':'widthFix'}}"
class="productImgUrl"
wx:if="{{datas.componentData.goodsImgType == 1}}"
src="{{items.productImgUrl}}"
/>
<image
lazy-load
mode="{{datas.componentData.style==='rowList' || datas.componentData.style==='heap'?'aspectFit':'widthFix'}}"
class="productImgUrl"
wx:else
src="{{items.coverImage}}"
/>
<!-- 售罄遮罩 -->
<view class="whiteBg" wx:if="{{items&&items.oversoldFlag==0&&items.totalQty-0<=0}}">
<view class="cover">
<image mode="aspectFit" src="http://mayi-newshop.oss-cn-shanghai.aliyuncs.com/public/png/f254fe62-6dda-46f6-a2f4-a7b2aa0474df.png" />
</view>
</view>
</view>
</view>
<!-- 商品详情 -->
<view class="info" style="text-align:{{datas.componentData['initcharAlign']}};">
<view class="info-top flex">
<view
class="name"
wx:if="{{datas.componentData['nameShow']}}"
style="color:{{datas.componentData['nameColor']}};font-weight:{{datas.componentData['nameFontWeight']}};font-size:{{datas.componentData['nameFontSize']}}em;height:2.8em;"
>
{{items!=null?items['productName']:'名称'}}
</view>
<view
class="follower-wrap"
wx:if="{{datas.componentData['followerShow']}}"
style="padding-left:{{datas.componentData.columnNum == 3 ? '0' : '20rpx'}}"
>
<view class="follower-num" style="color:{{datas.componentData['followerColor']?datas.componentData['followerColor']:'#ff9933'}};">
{{items!=null? items['totalCollectionCount']:0}}
</view>
<view class="follower-text">关注人数</view>
</view>
</view>
<!-- 已售 -->
<view class="Sold">
<text wx:if="{{datas.componentData['alSaleShow']}}">已售{{items!=null ? items['totalSalesCount'] :0}}件</text>
<text wx:if="{{datas.componentData['alSaleShow'] && datas.componentData['collectShow']}}">/</text>
<text wx:if="{{datas.componentData['collectShow']}}">剩余{{items!=null && items['qty']!=undefined ? (items['qty'] > 0 ? items['qty']: items.oversoldFlag==1?'数量充足':'数量不足') : ''}}<text wx:if="{{items!=null && (items['qty'] ? items['qty'] >= 0 : items['saleQty'] >= 0) && items.oversoldFlag!=1}}">件</text>
</text>
</view>
<!-- 标签 -->
<view class="marketing flex" wx:if="{{datas.componentData['marketingTag']&&datas.componentData['marketingStyle']==0&&items.marketingTag}}">
<view
class="item"
wx:for="{{items.marketingTag}}"
wx:key="index"
>
{{item.label}}
</view>
</view>
<!-- 底部 -->
<view class="bottom" wx:if="{{datas.componentData['goodsType'] !=1}}">
<!-- 价格 -->
<view class="priceItem flex">
<view
class="price flex"
style="color:{{datas.componentData['priceColor']}};font-size:{{datas.componentData['priceFontSize']}}em;"
wx:if="{{datas.componentData['priceShow']}}"
>
<text wx:if="{{items!=null && (items['groupBuyFlag'] == '0' ||items['groupBuyFlag'] == '1')}}">
¥{{items!=null ? items['goodsMinPrice']:0}}
</text>
<text style="font-size:24rpx;color:#999;text-decoration:line-through;" wx:if="{{items!=null&&datas.componentData['priceMarking']&&items['minGoodsSuggestedRetailPrice']&&(items['goodsMinPrice']-0<items['minGoodsSuggestedRetailPrice']-0)&&datas.componentData['columnNum']<3}}">
¥{{items['minGoodsSuggestedRetailPrice']}}
</text>
</view>
<view class="vipPrice2 flex" wx:if="{{datas.componentData.vipPrice}}">
<view class="left" wx:if="{{items.showVipPrice==true}}">
¥{{items['minPriceAfterRecommendedCardPriceTable']}}
</view>
<view class="vipIcon line-clamp1" wx:if="{{items.showVipTag==true}}">
{{items["recommendedCardMinPricePriceTableName"]}}
</view>
</view>
</view>
<!-- 收益样式一 -->
<block wx:if="{{items!=null&&items['minProductGoodsCommission']&&items['minProductGoodsCommission']-0>0.01}}">
<view
class="showCommission"
style="color:{{datas.componentData.commissionColor}};border-color:{{datas.componentData.commissionColor}};"
wx:if="{{datas.componentData.commissionStyle==0}}"
>
<view class="commission-box" style="background-color:{{datas.componentData.commissionBgColor}}">
<text>收益</text>
<text>¥{{items['minProductGoodsCommission']}}</text>
</view>
</view>
</block>
<view wx:if="{{(items&&items.totalQty-0>0||items&&items.oversoldFlag==1)&& datas.componentData['paynow']}}" catchtap="onclickBuynow">
<text wx:if="{{datas.componentData.btnType<6}}" style="color:{{datas.componentData.btnColor}}" class="buy-now-icon iconfont-common {{datas.componentData.btnIcon}}"></text>
<view
wx:else
class="buy-now"
style="background-color:{{datas.componentData.btnColor}};font-size:24rpx;"
>
{{datas.componentData.btnTest}}
</view>
</view>
</view>
<!-- 底部展示标签列表 -->
<block wx:if="{{items!=null}}">
<view class="marketing flex" wx:if="{{datas.componentData.marketingTag&&datas.componentData.marketingStyle==1&&items.marketingTag}}">
<view
class="item"
wx:for="{{items.marketingTag}}"
wx:key="index"
>
{{item.label}}
</view>
</view>
</block>
<!-- 收益样式二 -->
<block wx:if="{{items!=null&&items['minProductGoodsCommission']&&items['minProductGoodsCommission']-0>0.01}}">
<view
class="showCommissionTwo flex"
wx:if="{{datas.componentData.commissionStyle==1}}"
style="color:{{datas.componentData.commissionColor}};border-color:{{datas.componentData.commissionColor}};"
>
<view class="commission-box" style="background-color:{{datas.componentData.commissionBgColor}}">
<text class="iconfont-common common-iconfenxiang"></text>
<text style="padding:0 8rpx;">赚¥</text>
<text style="font-size:32rpx;">{{items['minProductGoodsCommission']}}</text>
</view>
</view>
</block>
</view>
</view>
</view>
static/nativeComponents/spellGroup/GoodsItem/index.wxss
0 → 100644
View file @
be7aa12c
@import "/static/font/common_icon.wxss";
.flex{
display: flex;
}
.goods-item-child-bd{
border: 1px solid var(--border_color);
}
image{
width: 100%;
display: block;
}
.goodsItem{
margin-bottom: var(--proGap2);
white-space: initial;
}
.goods-item-child {
position: relative;
overflow: hidden;
background: #fff;
}
.goodsRowList .goods-item-child{
display: flex;
align-items: flex-start;
}
.goodsRowList .goods-item-child .imgBox{
width: auto;
width: 180rpx;
height: 180rpx;
margin: 20rpx;
overflow: hidden;
border-radius: 12rpx;
-webkit-border-radius: 12rpx;
-moz-border-radius: 12rpx;
-ms-border-radius: 12rpx;
-o-border-radius: 12rpx;
}
.goodsRowList .goods-item-child .info{
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.goodsHeapItem{
width: 100%;
}
.merchantsEntrance{
padding: 8rpx 20rpx;
}
.merchantsEntrance .left{
align-items: center;
}
.merchantsEntrance .left .logo{
width: 52rpx;
height: 52rpx;
border-radius: 8rpx;
-webkit-border-radius: 8rpx;
-moz-border-radius: 8rpx;
-ms-border-radius: 8rpx;
-o-border-radius: 8rpx;
overflow: hidden;
background: #f5f5f5;
margin-right: 20rpx;
}
.imgBox{
position: relative;
overflow: hidden;
width: 100%;
margin: 0 auto;
}
.goodsPicture{
width: 100%;
height: 100%;
position: relative;
box-sizing: border-box;
}
.goodsPicture .have-group{
position: absolute;
bottom: 20rpx;
left: 12rpx;
padding: 8rpx 16rpx;
background-color: rgba(0,0,0,.6);
color: white;
font-size: 24rpx;
border-radius: 8rpx;
-webkit-border-radius: 8rpx;
-moz-border-radius: 8rpx;
-ms-border-radius: 8rpx;
-o-border-radius: 8rpx;
}
.goodsPicture .productImgUrl{
width: 100%;
height: 100%;
}
.goodsPicture .saleWay{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
display: flex;
justify-content: center;
z-index: 2;
color: #fff;
}
.goodsPicture .saleWay .saleWayBg{
background: var(--main-color);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0.5;
}
.goodsPicture .saleWay .saleTime{
position: relative;
z-index: 2;
padding: 4rpx 0;
}
.goodsPicture .saleWay .saleTime text{
color: #fff;
}
.goodsPicture .angleSign{
position: absolute;
top: 0;
left: 0;
}
.whiteBg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(#fff, 0.7);
}
.whiteBg .cover {
position: absolute;
top: 20px;
left: 20px;
right: 20px;
bottom: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 50%;
background-size: cover;
}
.whiteBg .cover img {
width: 100%;
height: 100%;
object-fit: contain;
}
.info{
padding: 10rpx 20rpx 24rpx;
position: relative;
background-color: white;
}
.info .info-top{
overflow: hidden;
justify-content: space-between;
}
.info .name{
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 1.4em;
position: relative;
}
.info .follower-wrap{
position: relative;
font-size: 0.8em;
color: #999;
text-align: center;
height: 70rpx;
border-left: 1px solid #999;
}
.info .follower-wrap .follower-num{
text-align: center;
font-size: 1em;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.info .follower-wrap .follower-text{
color: #999;
font-size: 0.7em;
text-align: center;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.vipPrice1{
align-items: flex-end;
margin-top: 12rpx;
font-size: 24rpx;
}
.vipPrice1 .vipIcon{
min-width: 64rpx;
padding: 2rpx 4rpx;
height: 28rpx;
background: #333;
font-size: 20rpx;
line-height: 28rpx;
text-align: center;
color: #d7c7a1;
border-top-left-radius: 4rpx;
border-bottom-left-radius: 12rpx;
}
.vipPrice1 .right{
height: 28rpx;
color: #333;
font-weight: bold;
background: linear-gradient( 227deg, rgba(212, 195, 142, 1), rgba(252, 232, 162, 1) );
border-radius: 0rpx 12rpx 12rpx 0rpx;
font-size: 20rpx;
text-align: center;
padding: 0 8rpx 0 4rpx;
-webkit-border-radius: 0rpx 12rpx 12rpx 0rpx;
-moz-border-radius: 0rpx 12rpx 12rpx 0rpx;
-ms-border-radius: 0rpx 12rpx 12rpx 0rpx;
-o-border-radius: 0rpx 12rpx 12rpx 0rpx;
}
.priceItem {
align-items: flex-end;
}
.priceItem .price{
align-items: center;
}
.vipPrice2{
align-items: flex-end;
margin-top: 12rpx;
font-size: 24rpx;
}
.vipPrice2 .left{
color: #333;
font-weight: bold;
margin-left: 8rpx;
}
.vipPrice2 .vipIcon{
margin-left: 8rpx;
min-width: 64rpx;
padding: 2rpx 8rpx;
height: 28rpx;
background: #333;
font-size: 20rpx;
line-height: 28rpx;
text-align: center;
color: #d7c7a1;
border-radius: 12rpx;
border-top-left-radius: 2rpx;
-webkit-border-radius: 12rpx;
-moz-border-radius: 12rpx;
-ms-border-radius: 12rpx;
-o-border-radius: 12rpx;
}
.Sold{
overflow: hidden;
color: #999;
}
.Sold text{
font-size: 24rpx;
}
.buy-now-icon{
color: var(--main-color);
}
.buy-now {
color: #ffffff;
position: absolute;
right: 0;
bottom: 0;
border-radius: 30rpx;
background-color: var(--main-color);
width: 140rpx;
white-space: nowrap;
padding: 8rpx 20rpx;
display: flex;
justify-content: center;
align-items: center;
-webkit-border-radius: 30rpx;
-moz-border-radius: 30rpx;
-ms-border-radius: 30rpx;
-o-border-radius: 30rpx;
}
.buy-now-icon {
position: absolute;
right: 0;
bottom: 0;
font-size: 36rpx;
}
.showCommission {
width: auto;
display: inline-block;
margin-top: 8rpx;
border: 1px solid transparent;
border-radius: 12rpx;
font-size: 10px;
overflow: hidden;
-webkit-border-radius: 12rpx;
-moz-border-radius: 12rpx;
-ms-border-radius: 12rpx;
-o-border-radius: 12rpx;
}
.showCommission .commission-box {
box-sizing: border-box;
padding: 0 10rpx;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.showCommissionTwo {
align-items: center;
justify-content: center;
margin-top: 16rpx;
width: 100%;
height: 52rpx;
font-size: 24rpx;
border: 1px solid transparent;
border-radius: 26px;
overflow: hidden;
}
.showCommissionTwo .commission-box {
width: 100%;
height: 100%;
padding-left: 20rpx;
display: flex;
justify-content: center;
align-items: center;
}
.showCommissionTwo i {
font-size: 28rpx;
margin-right: 8rpx;
}
.marketing {
align-items: center;
flex-wrap: wrap;
}
.marketing .item {
margin-top: 8rpx;
margin-right: 8rpx;
font-size: 20rpx;
padding: 0 12rpx;
border: 2rpx solid #ff5500;
color: #ff5500;
border-radius: 40rpx;
-webkit-border-radius: 40rpx;
-moz-border-radius: 40rpx;
-ms-border-radius: 40rpx;
-o-border-radius: 40rpx;
}
.bottom {
position: relative;
}
.price {
font-weight: 600;
margin-top: 12rpx;
}
\ No newline at end of file
static/nativeComponents/spellGroup/heapItem/index.js
0 → 100644
View file @
be7aa12c
import
TouchEvent
from
"./utils/touchEvent"
;
const
componentOptions
=
{
// 组件选项
options
:
{
multipleSlots
:
true
},
behaviors
:
[],
properties
:
{
datas
:
{
type
:
Object
},
goodsList
:
{
type
:
Array
}
},
// 组件数据
data
:
{
isPageHidden
:
false
,
// 页面是否处于隐藏状态
isLoading
:
false
,
swiperCurIndex
:
0
,
slideClass
:
""
,
lockSwipe
:
false
},
// 数据监听器
observers
:
{},
// 组件生命周期
lifetimes
:
{
created
()
{
new
TouchEvent
(
this
,
"touchCard"
,
{
swipe
:
evt
=>
{
//在touch结束触发,evt.direction代表滑动的方向 ['Up','Right','Down','Left']
if
(
evt
.
direction
===
"Left"
)
this
.
next
(
evt
);
if
(
evt
.
direction
===
"Right"
)
this
.
prev
(
evt
);
}
});
},
attached
()
{}
},
// 组件方法
methods
:
{
next
(
e
)
{
if
(
this
.
data
.
lockSwipe
)
return
;
this
.
data
.
lockSwipe
=
true
;
if
(
-
this
.
data
.
swiperCurIndex
>=
this
.
data
.
goodsList
.
length
-
1
)
{
return
(
this
.
data
.
lockSwipe
=
false
);
}
const
index
=
e
.
currentTarget
.
dataset
[
"index"
];
this
.
setData
(
{
[
"goodsList["
+
index
+
"].slideClass"
]:
" ani-slide-up"
},
()
=>
{
this
.
setData
({
swiperCurIndex
:
--
this
.
data
.
swiperCurIndex
});
}
);
setTimeout
(()
=>
{
this
.
data
.
lockSwipe
=
false
;
this
.
setData
({
[
"goodsList["
+
index
+
"].slideClass"
]:
""
});
},
590
);
},
prev
(
e
)
{
const
index
=
e
.
currentTarget
.
dataset
[
"index"
]
-
1
;
if
(
this
.
data
.
lockSwipe
||
index
<
0
)
return
;
this
.
data
.
lockSwipe
=
true
;
this
.
setData
({
[
"goodsList["
+
index
+
"].slideClass"
]:
" ani-slide-down"
,
swiperCurIndex
:
++
this
.
data
.
swiperCurIndex
});
setTimeout
(()
=>
{
this
.
data
.
lockSwipe
=
false
;
this
.
setData
({
[
"goodsList["
+
index
+
"].slideClass"
]:
""
});
},
590
);
}
},
definitionFilter
()
{},
// 页面生命周期
pageLifetimes
:
{
// 页面被展示
show
()
{
const
{
isPageHidden
}
=
this
.
data
;
// show事件发生前,页面不是处于隐藏状态时
if
(
!
isPageHidden
)
{
return
;
}
// 重新执行定时器等操作
},
// 页面被隐藏
hide
()
{
this
.
setData
({
isPageHidden
:
true
});
// 清除定时器等操作
},
// 页面尺寸变化时
resize
()
{}
}
};
Component
(
componentOptions
);
static/nativeComponents/spellGroup/heapItem/index.json
0 → 100644
View file @
be7aa12c
{
"component"
:
true
,
"usingComponents"
:
{
"goods-item"
:
"../GoodsItem/index"
}
}
static/nativeComponents/spellGroup/heapItem/index.wxml
0 → 100644
View file @
be7aa12c
<view class="container center">
<view class="card-swiper">
<view
wx:for="{{goodsList}}"
wx:key="index"
data-index="{{index}}"
class="{{'card-swiper-item curdistance' + (swiperCurIndex + index) + (!!item.slideClass? item.slideClass: '')}}"
bindtouchstart="touchCard.start"
bindtouchmove="touchCard.move"
bindtouchend="touchCard.end"
bindtouchcancel="touchCard.cancel"
>
<goods-item
style="width:100%"
datas="{{datas}}"
items="{{goodsList[index]}}"
indexs="{{index}}"
></goods-item>
</view>
</view>
</view>
static/nativeComponents/spellGroup/heapItem/index.wxss
0 → 100644
View file @
be7aa12c
.container{
width: 100%;
height: 200rpx;
padding: 0 0 20rpx;
}
/**index.wxss**/
.card-swiper{
position: relative;
width: 100%;
height: 100%;
color: #666;
font-size: 28rpx;
}
.card-swiper-item{
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 92%;
transition: all .3s ease-out;
z-index: 0;
display: none;
overflow: hidden;
}
.card-swiper .card-swiper-item.curdistance0{
z-index: 10;
display: flex;
}
.card-swiper .card-swiper-item.curdistance1{
display: flex;
z-index: 9;
transform: scale(.95);
opacity: .7;
left: 40rpx;
}
.card-swiper .card-swiper-item.curdistance2{
display: flex;
z-index: 8;
transform: scale(.9);
opacity: .4;
left: 80rpx;
}
.ani-slide-up{
display: flex;
animation: slideUp .6s ease-out;
z-index: 11;
/* transform: rotate(25deg); */
}
.ani-slide-down{
display: flex;
animation: slideUp .6s ease-in;
animation-direction: reverse;
}
@keyframes slideUp{
0% {
}
70% {
opacity: 1;
}
100% {
transform: translateX(-1000rpx);
opacity: 0;
-webkit-transform: translateX(-1000rpx);
-moz-transform: translateX(-1000rpx);
-ms-transform: translateX(-1000rpx);
-o-transform: translateX(-1000rpx);
}
}
\ No newline at end of file
static/nativeComponents/spellGroup/heapItem/utils/touchEvent.js
0 → 100644
View file @
be7aa12c
var
defaultOption
=
{
touchStart
:
function
()
{
},
touchMove
:
function
()
{
},
touchEnd
:
function
()
{
},
touchCancel
:
function
()
{
},
multipointStart
:
function
()
{
},
multipointEnd
:
function
()
{
},
tap
:
function
()
{
},
doubleTap
:
function
()
{
},
longTap
:
function
()
{
},
singleTap
:
function
()
{
},
rotate
:
function
()
{
},
pinch
:
function
()
{
},
pressMove
:
function
()
{
},
swipe
:
function
()
{
}
}
export
default
class
YrobotTouch
{
constructor
(
pageOBJ
,
name
,
option
=
{})
{
this
.
preV
=
{
x
:
null
,
y
:
null
};
this
.
pinchStartLen
=
null
;
this
.
scale
=
1
;
this
.
isDoubleTap
=
false
;
this
.
delta
=
null
;
this
.
last
=
null
;
this
.
now
=
null
;
this
.
tapTimeout
=
null
;
this
.
singleTapTimeout
=
null
;
this
.
longTapTimeout
=
null
;
this
.
swipeTimeout
=
null
;
this
.
x1
=
this
.
x2
=
this
.
y1
=
this
.
y2
=
null
;
this
.
preTapPosition
=
{
x
:
null
,
y
:
null
};
this
.
lastZoom
=
1
;
this
.
tempZoom
=
1
;
try
{
if
(
this
.
_checkBeforeCreate
(
pageOBJ
,
name
))
{
this
.
_name
=
name
this
.
_option
=
{
...
defaultOption
,
...
option
}
pageOBJ
[
name
]
=
this
this
.
_bindFunc
(
pageOBJ
)
}
}
catch
(
error
)
{
console
.
error
(
error
)
}
}
_checkBeforeCreate
(
pageOBJ
,
name
)
{
if
(
!
pageOBJ
||
!
name
)
{
throw
new
Error
(
'YrobotTouch实例化时,必须传入page对象和引用名'
)
return
false
}
if
(
pageOBJ
[
name
])
{
throw
new
Error
(
'YrobotTouch实例化error: '
+
name
+
' 已经存在page中'
)
return
false
}
return
true
}
_bindFunc
(
pageOBJ
)
{
let
funcNames
=
[
'start'
,
'move'
,
'end'
,
'cancel'
]
for
(
let
funcName
of
funcNames
)
pageOBJ
[
this
.
_name
+
'.'
+
funcName
]
=
this
[
funcName
].
bind
(
this
)
}
start
(
evt
)
{
if
(
!
evt
.
touches
)
return
;
this
.
now
=
Date
.
now
();
this
.
x1
=
evt
.
touches
[
0
].
pageX
==
null
?
evt
.
touches
[
0
].
x
:
evt
.
touches
[
0
].
pageX
;
this
.
y1
=
evt
.
touches
[
0
].
pageY
==
null
?
evt
.
touches
[
0
].
y
:
evt
.
touches
[
0
].
pageY
;
this
.
delta
=
this
.
now
-
(
this
.
last
||
this
.
now
);
this
.
_option
.
touchStart
(
evt
);
if
(
this
.
preTapPosition
.
x
!==
null
)
{
this
.
isDoubleTap
=
(
this
.
delta
>
0
&&
this
.
delta
<=
250
&&
Math
.
abs
(
this
.
preTapPosition
.
x
-
this
.
x1
)
<
30
&&
Math
.
abs
(
this
.
preTapPosition
.
y
-
this
.
y1
)
<
30
);
}
this
.
preTapPosition
.
x
=
this
.
x1
;
this
.
preTapPosition
.
y
=
this
.
y1
;
this
.
last
=
this
.
now
;
let
preV
=
this
.
preV
,
len
=
evt
.
touches
.
length
;
if
(
len
>
1
)
{
this
.
_cancelLongTap
();
this
.
_cancelSingleTap
();
let
otx
=
evt
.
touches
[
1
].
pageX
==
null
?
evt
.
touches
[
1
].
x
:
evt
.
touches
[
1
].
pageX
;
let
oty
=
evt
.
touches
[
1
].
pageY
==
null
?
evt
.
touches
[
1
].
y
:
evt
.
touches
[
1
].
pageY
;
let
v
=
{
x
:
otx
-
this
.
x1
,
y
:
oty
-
this
.
y1
};
preV
.
x
=
v
.
x
;
preV
.
y
=
v
.
y
;
this
.
pinchStartLen
=
getLen
(
preV
);
this
.
_option
.
multipointStart
(
evt
);
}
this
.
longTapTimeout
=
setTimeout
(
function
()
{
evt
.
type
=
"longTap"
;
this
.
_option
.
longTap
(
evt
);
}.
bind
(
this
),
750
);
}
move
(
evt
)
{
if
(
!
evt
.
touches
)
return
;
let
preV
=
this
.
preV
,
len
=
evt
.
touches
.
length
,
currentX
=
evt
.
touches
[
0
].
pageX
==
null
?
evt
.
touches
[
0
].
x
:
evt
.
touches
[
0
].
pageX
,
currentY
=
evt
.
touches
[
0
].
pageY
==
null
?
evt
.
touches
[
0
].
y
:
evt
.
touches
[
0
].
pageY
;
this
.
isDoubleTap
=
false
;
if
(
len
>
1
)
{
let
otx
=
evt
.
touches
[
1
].
pageX
==
null
?
evt
.
touches
[
1
].
x
:
evt
.
touches
[
1
].
pageX
;
let
oty
=
evt
.
touches
[
1
].
pageY
==
null
?
evt
.
touches
[
1
].
y
:
evt
.
touches
[
1
].
pageY
;
let
v
=
{
x
:
otx
-
currentX
,
y
:
oty
-
currentY
};
if
(
preV
.
x
!==
null
)
{
if
(
this
.
pinchStartLen
>
0
)
{
evt
.
singleZoom
=
getLen
(
v
)
/
this
.
pinchStartLen
;
evt
.
zoom
=
evt
.
singleZoom
*
this
.
lastZoom
;
this
.
tempZoom
=
evt
.
zoom
;
evt
.
type
=
"pinch"
;
this
.
_option
.
pinch
(
evt
);
}
evt
.
angle
=
getRotateAngle
(
v
,
preV
);
evt
.
type
=
"rotate"
;
this
.
_option
.
rotate
(
evt
);
}
preV
.
x
=
v
.
x
;
preV
.
y
=
v
.
y
;
}
else
{
if
(
this
.
x2
!==
null
)
{
evt
.
deltaX
=
currentX
-
this
.
x2
;
evt
.
deltaY
=
currentY
-
this
.
y2
;
}
else
{
evt
.
deltaX
=
0
;
evt
.
deltaY
=
0
;
}
this
.
_option
.
pressMove
(
evt
);
}
this
.
_option
.
touchMove
(
evt
);
this
.
_cancelLongTap
();
this
.
x2
=
currentX
;
this
.
y2
=
currentY
;
if
(
len
>
1
)
{
// evt.preventDefault();
}
}
end
(
evt
)
{
if
(
!
evt
.
changedTouches
)
return
;
this
.
_cancelLongTap
();
let
self
=
this
;
evt
.
direction
=
this
.
_swipeDirection
(
this
.
x1
,
this
.
x2
,
this
.
y1
,
this
.
y2
);
//在结束钩子都加入方向判断,但触发swipe瞬时必须位移大于30
if
(
evt
.
touches
.
length
<
2
)
{
this
.
lastZoom
=
this
.
tempZoom
;
this
.
_option
.
multipointEnd
(
evt
);
}
this
.
_option
.
touchEnd
(
evt
);
//swipe
if
((
this
.
x2
&&
Math
.
abs
(
this
.
x1
-
this
.
x2
)
>
30
)
||
(
this
.
y2
&&
Math
.
abs
(
this
.
y1
-
this
.
y2
)
>
30
))
{
// evt.direction = this._swipeDirection(this.x1, this.x2, this.y1, this.y2);
this
.
swipeTimeout
=
setTimeout
(
function
()
{
evt
.
type
=
"swipe"
;
self
.
_option
.
swipe
(
evt
);
},
0
)
}
else
{
this
.
tapTimeout
=
setTimeout
(
function
()
{
evt
.
type
=
"tap"
;
self
.
_option
.
tap
(
evt
);
// trigger double tap immediately
if
(
self
.
isDoubleTap
)
{
evt
.
type
=
"doubleTap"
;
self
.
_option
.
doubleTap
(
evt
);
clearTimeout
(
self
.
singleTapTimeout
);
self
.
isDoubleTap
=
false
;
}
},
0
)
if
(
!
self
.
isDoubleTap
)
{
self
.
singleTapTimeout
=
setTimeout
(
function
()
{
self
.
_option
.
singleTap
(
evt
);
},
250
);
}
}
this
.
preV
.
x
=
0
;
this
.
preV
.
y
=
0
;
this
.
scale
=
1
;
this
.
pinchStartLen
=
null
;
this
.
x1
=
this
.
x2
=
this
.
y1
=
this
.
y2
=
null
;
}
cancel
(
evt
)
{
clearTimeout
(
this
.
singleTapTimeout
);
clearTimeout
(
this
.
tapTimeout
);
clearTimeout
(
this
.
longTapTimeout
);
clearTimeout
(
this
.
swipeTimeout
);
this
.
_option
.
touchCancel
(
evt
);
}
_cancelLongTap
()
{
clearTimeout
(
this
.
longTapTimeout
);
}
_cancelSingleTap
()
{
clearTimeout
(
this
.
singleTapTimeout
);
}
_swipeDirection
(
x1
,
x2
,
y1
,
y2
)
{
return
Math
.
abs
(
x1
-
x2
)
>=
Math
.
abs
(
y1
-
y2
)
?
(
x1
-
x2
>
0
?
'Left'
:
'Right'
)
:
(
y1
-
y2
>
0
?
'Up'
:
'Down'
)
}
destroy
()
{
if
(
this
.
singleTapTimeout
)
clearTimeout
(
this
.
singleTapTimeout
);
if
(
this
.
tapTimeout
)
clearTimeout
(
this
.
tapTimeout
);
if
(
this
.
longTapTimeout
)
clearTimeout
(
this
.
longTapTimeout
);
if
(
this
.
swipeTimeout
)
clearTimeout
(
this
.
swipeTimeout
);
this
.
_option
.
rotate
=
null
;
this
.
_option
.
touchStart
=
null
;
this
.
_option
.
multipointStart
=
null
;
this
.
_option
.
multipointEnd
=
null
;
this
.
_option
.
pinch
=
null
;
this
.
_option
.
swipe
=
null
;
this
.
_option
.
tap
=
null
;
this
.
_option
.
doubleTap
=
null
;
this
.
_option
.
longTap
=
null
;
this
.
_option
.
singleTap
=
null
;
this
.
_option
.
pressMove
=
null
;
this
.
_option
.
touchMove
=
null
;
this
.
_option
.
touchEnd
=
null
;
this
.
_option
.
touchCancel
=
null
;
this
.
preV
=
this
.
pinchStartLen
=
this
.
scale
=
this
.
isDoubleTap
=
this
.
delta
=
this
.
last
=
this
.
now
=
this
.
tapTimeout
=
this
.
singleTapTimeout
=
this
.
longTapTimeout
=
this
.
swipeTimeout
=
this
.
x1
=
this
.
x2
=
this
.
y1
=
this
.
y2
=
this
.
preTapPosition
=
this
.
rotate
=
this
.
touchStart
=
this
.
multipointStart
=
this
.
multipointEnd
=
this
.
pinch
=
this
.
swipe
=
this
.
tap
=
this
.
doubleTap
=
this
.
longTap
=
this
.
singleTap
=
this
.
pressMove
=
this
.
touchMove
=
this
.
touchEnd
=
this
.
touchCancel
=
null
;
return
null
;
}
}
function
getLen
(
v
)
{
return
Math
.
sqrt
(
v
.
x
*
v
.
x
+
v
.
y
*
v
.
y
);
}
function
dot
(
v1
,
v2
)
{
return
v1
.
x
*
v2
.
x
+
v1
.
y
*
v2
.
y
;
}
function
getAngle
(
v1
,
v2
)
{
let
mr
=
getLen
(
v1
)
*
getLen
(
v2
);
if
(
mr
===
0
)
return
0
;
let
r
=
dot
(
v1
,
v2
)
/
mr
;
if
(
r
>
1
)
r
=
1
;
return
Math
.
acos
(
r
);
}
function
cross
(
v1
,
v2
)
{
return
v1
.
x
*
v2
.
y
-
v2
.
x
*
v1
.
y
;
}
function
getRotateAngle
(
v1
,
v2
)
{
let
angle
=
getAngle
(
v1
,
v2
);
if
(
cross
(
v1
,
v2
)
>
0
)
{
angle
*=
-
1
;
}
return
angle
*
180
/
Math
.
PI
;
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment