安装  npm install weixin-js-sdk

引入

import wx from 'weixin-js-sdk'

<template>

<div class="circle_box">

<div id="content"></div>

<img class="img_0" src="https://img.yzcdn.cn/vant/cat.jpeg" alt="">

<img @click="changeType" class="img_1" v-show="playbool" src="@/assets/decompression/pressure_audio_play.png" alt="">

<img @click="changeType" class="img_1" v-show="!playbool" src="@/assets/decompression/pressure_audio_pause.png" alt="">

<div v-show="false">

<audio ref="audio" controls @timeupdate="updateTime">

<source src="@/assets/decompression/tiankong.mp3" type="audio/mpeg">

</audio>

</div>

</div>

</template>

<script>

import wx from "weixin-js-sdk";

export default {

data(){

return{

value:'',

outColor:'',

playbool:true,

second:0,

than:''

}

},

mounted(){

this.init()

this.main()

},

methods:{

init(){

let that = this

let u = navigator.userAgent;

//ios手机

var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);

if(isIOS){

this.$nextTick(() => {

this.autoPlayAudio();

})

}else{

this.$nextTick(() => {

let time = setTimeout(function () {

let audio = that.$refs.audio;

//音频总时长 秒

that.second = audio.duration;

that.than = 100/audio.duration;

that.$parent.calculationTime(audio.duration);

clearInterval(time);

}, 500)

})

}

},

autoPlayAudio() {

let ua = window.navigator.userAgent.toLowerCase();

let that = this;

let audio = this.$refs.audio;

if(ua.match(/MicroMessenger/i) == 'micromessenger'){

//微信浏览器

wx.config({

debug: false,

appId: '',

timestamp: 1,

nonceStr: '',

signature: '',

jsApiList: []

});

wx.ready(function() {

audio.play();

audio.pause();

let time = setTimeout(function () {

if(audio.duration>0){

//音频总时长 秒

that.second = audio.duration;

that.than = 100/audio.duration;

that.$parent.calculationTime(audio.duration);

}else{

that.autoPlayAudio();

}

clearInterval(time);

}, 500)

});

}else{

let time = setTimeout(function () {

if(audio.duration>0){

//音频总时长 秒

that.second = audio.duration;

that.than = 100/audio.duration;

that.$parent.calculationTime(audio.duration);

}else{

that.autoPlayAudio();

}

clearInterval(time);

}, 500)

}

},

//监测播放进度

updateTime(){

let audio = this.$refs.audio;

let time = Number(this.second)-Number(audio.currentTime);

this.$parent.calculationTime(time);

this.draw(this.than*audio.currentTime);

},

changeType(){

this.playbool = !this.playbool;

let audio = this.$refs.audio;

if(this.playbool){

//暂停

audio.pause()

}else{

audio.play()

}

},

event(dom) {  //事件绑定

if(this.isMobile){

dom.addEventListener("touchstart", this.OnMouseDown.bind(this), false);

dom.addEventListener("touchmove", this.throttle(this.OnMouseMove.bind(this)), false);

dom.addEventListener("touchend", this.OnMouseUp.bind(this), false);

return

}

dom.addEventListener("mousedown", this.OnMouseDown.bind(this), false);

dom.addEventListener("mousemove", this.throttle(this.OnMouseMove.bind(this)), false);

dom.addEventListener("mouseup", this.OnMouseUp.bind(this), false);

},

OnMouseDown(evt) {

let audio = this.$refs.audio;

//暂停音频

audio.pause()

this.clearLocation(evt);

let range = 10;

let X = this.getx(evt);

let Y = this.gety(evt);

let P = this.P

let minX = P.x - this.slider - range;

let maxX = P.x + this.slider + range;

let minY = P.y - this.slider - range;

let maxY = P.y + this.slider + range;

if (minX < X && X < maxX && minY < Y && Y < maxY) {   //判断鼠标是否在滑块上

this.isDown = true;

} else {

this.isDown = false;

}

},

main(){

const dom = document.getElementById("content")

const obj = {

el: dom,

startDeg:1.5    ,

endDeg: 3.5,

outColor: 'rgba(50, 50, 70, .2)',

counterclockwise: false

}

this.constructor(obj)

},

constructor(param) {

this.initParam(param)

this.draw(this.value)

},

initParam(param) {

const {

el,

startDeg = 1.5,

endDeg = 3.5,

outColor = "rgba(50, 50, 70, .2)",

innerLineWidth = 1,

outLineWidth = 5,

counterclockwise = true,

slider = 8,

color = ["#ffffff", "#ffffff"],

sliderColor = "#fff",

sliderBorderColor = "#33aaff",

value = 0,

change = (v)=> {  },

textShow = true

} = param;

this.el = el;

this.width = el.offsetWidth;

this.height = el.offsetHeight;

this.center = this.width / 2

this.radius = this.width / 2 - 30; //滑动路径半径

this.initCanvas(el);

this.startDeg = startDeg;

this.endDeg = endDeg;

this.outColor = outColor;

this.innerLineWidth = innerLineWidth;

this.outLineWidth = outLineWidth;

this.counterclockwise = counterclockwise;

this.slider = slider;

this.color = color;

this.sliderColor = sliderColor;

this.sliderBorderColor = sliderBorderColor;

this.value = value;

this.textShow = textShow;

this.change = change;

this.isDown = false;

this.event(el)

},

OnMouseMove(evt) {

if (!this.isDown) return;

let evpoint = {};

evpoint.x = this.getx(evt);

evpoint.y = this.gety(evt);

let point = this.spotchangeXY(evpoint);

let deg = this.XYToDeg(point.x, point.y);

deg = this.counterclockwise ? deg : Math.PI * 2 - deg;

let val = (deg/ Math.PI - this.startDeg) / (this.endDeg - this.startDeg)  * 100

if(val<0) val = 100 + val;

if(val >= 100) val = 100;

if(val <= 0) val = 0;

if(Math.abs (val - this.value) > 10) return;

//音频定位播放

let time = val/this.than;

let audio = this.$refs.audio;

audio.currentTime = time

this.animate = requestAnimationFrame(this.draw.bind(this,val));

if(this.value != Math.round(val)){

this.value = Math.round(val);

this.change(this.value)

}

},

OnMouseUp(evt) {  //鼠标释放

const _this = this

cancelAnimationFrame(_this.animate);

this.isDown = false;

if(this.distance(evt)){

this.playbool = false;

let audio = this.$refs.audio;

//播放音频

audio.play()

}

},

distance(evt){

let x = this.getx(evt);

let y = this.gety(evt);

let distance = Math.abs(Math.sqrt(Math.pow(x - 135, 2) + Math.pow(y - 135, 2)));

if(0<distance && distance<130){

return true

}else{

return false

}

},

//点击定位

clearLocation(evt){

let evpoint = {};

evpoint.x = this.getx(evt);

evpoint.y = this.gety(evt);

let point = this.spotchangeXY(evpoint);

let deg = this.XYToDeg(point.x, point.y);

deg = this.counterclockwise ? deg : Math.PI * 2 - deg;

let val = (deg/ Math.PI - this.startDeg) / (this.endDeg - this.startDeg)  * 100

if(val<0) val = 100 + val;

if(val >= 100) val = 100;

if(val <= 0) val = 0;

if(this.distance(evt)){

this.animate = requestAnimationFrame(this.draw.bind(this,val));

//音频定位播放

let time = val/this.than;

let audio = this.$refs.audio;

audio.currentTime = time

audio.play()

audio.pause()

if(this.value != Math.round(val)){

this.value = Math.round(val);

this.change(this.value)

}

}

},

//绘图

draw(value) {

this.ctx.clearRect(0, 0, this.width, this.width);

this.ctx.save();

let startDeg = this.counterclockwise ? Math.PI * (2 - this.startDeg) : Math.PI * this.startDeg

let endDeg = this.counterclockwise ? Math.PI * (2 - this.endDeg) : Math.PI * this.endDeg

// 绘制外侧圆弧

this.ctx.beginPath();

this.ctx.arc(this.center, this.center, this.radius, startDeg, endDeg, this.counterclockwise); // 绘制外侧圆弧

this.ctx.strokeStyle = this.outColor;

this.ctx.lineCap = "round";

this.ctx.lineWidth = this.outLineWidth;

this.ctx.stroke();

let Deg = this.valToDeg(value)

// 绘制可变圆弧

let themeColor = (typeof this.color == 'String') ? this.color : this.setLinearGradient()

this.ctx.beginPath();

this.ctx.arc(this.center, this.center, this.radius, startDeg, Deg, this.counterclockwise); // 可变圆弧

this.ctx.strokeStyle =  themeColor;

this.ctx.lineCap = "round";

this.ctx.lineWidth = this.outLineWidth;

this.ctx.stroke();

// 绘制滑块

this.P = this.DegToXY(Deg)

this.ctx.beginPath();

this.ctx.moveTo(this.center, this.center);

this.ctx.arc(this.P.x, this.P.y, this.slider, 0, Math.PI * 2, false); // 绘制滑块

this.ctx.fillStyle = this.sliderColor;;

this.ctx.fill();

},

initCanvas(dom) {

this.canvas = document.createElement("canvas");

this.canvas.setAttribute("id", "dragArc");

this.canvas.setAttribute("width", this.width);

this.canvas.setAttribute("height", this.width);

dom.appendChild(this.canvas);

this.ctx = this.canvas.getContext("2d");

this.isMobile = /Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent);

},

//将值转化为弧度

valToDeg(v) {

let range = this.endDeg - this.startDeg;

let val = range / 100 * v;

if(this.counterclockwise && (val !=0) ) val = 2 -val;

let startDeg = this.counterclockwise ? (2 - this.startDeg) : this.startDeg;

return (startDeg + val) * Math.PI;

},

// 弧度转化为对应坐标值

DegToXY(deg) {

let d = 2 * Math.PI - deg;

return this.respotchangeXY({

x: this.radius * Math.cos(d),

y: this.radius * Math.sin(d)

})

},

//canvas坐标转化为中心坐标

spotchangeXY(point) {

const spotchangeX = (i) => {

return i - this.center

}

const spotchangeY = (i) => {

return this.center - i

}

return {

x: spotchangeX(point.x),

y: spotchangeY(point.y)

}

},

//中心坐标转化为canvas坐标

respotchangeXY(point) {

const spotchangeX = (i) => {

return i + this.center

}

const spotchangeY = (i) => {

return this.center - i

}

return {

x: spotchangeX(point.x),

y: spotchangeY(point.y)

}

},

setLinearGradient(){

const grad  = this.ctx.createLinearGradient(0,0, 0,this.width);

this.color.forEach((e, i) => {

if(i == 0){

grad.addColorStop(0, e)

}else  if(i == this.color.length - 1){

grad.addColorStop(1, e)

}else{

grad.addColorStop(1/this.color.length * (i+1), e);

}

});

return grad;

},

// 将坐标点转化为弧度

XYToDeg(lx, ly) {

let adeg = Math.atan(ly / lx)

let deg;

if (lx >= 0 && ly >= 0) {

deg = adeg ;

}

if (lx <= 0 && ly >= 0) {

deg = adeg + Math.PI;

}

if (lx <= 0 && ly <= 0) {

deg = adeg + Math.PI;

}

if (lx > 0 && ly < 0) {

deg = adeg + Math.PI * 2;

}

return deg

},

//获取鼠标在canvas内坐标x

getx(ev) {

if(!this.isMobile) return ev.clientX - this.el.getBoundingClientRect().left;

if(ev.touches.length){

return ev.touches[0].pageX - this.el.getBoundingClientRect().left;

}else{

return ev.changedTouches[0].pageX - this.el.getBoundingClientRect().left;

}

},

//获取鼠标在canvas内坐标y

gety(ev) {

if(!this.isMobile) return ev.clientY - this.el.getBoundingClientRect().top;

if(ev.touches.length){

return ev.touches[0].pageY - this.el.getBoundingClientRect().top;

}else{

return ev.changedTouches[0].pageY - this.el.getBoundingClientRect().top;

}

},

//节流

throttle(func) {

let previous = 0;

return function() {

let now = Date.now();

let context = this;

let args = arguments;

if (now - previous > 10) {

func.apply(context, args);

previous = now;

}

}

},

}

}

</script>

<style scoped>

.circle_box{

position: relative;

padding-top: 130px;

top: 0;

left: 0;

width: 100%;

height: 245px;

}

#content{

position: absolute;

left: 50%;

transform: translateX(-50%);

height: 240px;

width: 270px;

}

.img_0{

position: absolute;

top: 175px;

left: 50%;

transform: translateX(-50%);

width: 180px;

height: 180px;

border-radius: 50%;

z-index: 5;

}

.img_1{

position: absolute;

left: 50%;

transform: translateX(-50%);

top: 243px;

width: 34px;

height: 46px;

z-index: 10;

}

.posi{

position: absolute;

left: 0;

top: 10px;

z-index: 1000;

}

</style>

vue3.0 安卓和ios h5 移动端音频自定义圆环可拖拽播放(兼容微信浏览器)相关推荐

  1. 精品手游小精灵大作战源码 安卓+IOS+H5三端Cocos Creator 客户端 JAVA服务端

    小精灵大作战 数据库说明 数据库使用MySQL,推荐管理软件Navicat For MySQL. 创建数据库命名为pet_battle,字符集选用utf8 -- UTF-8 Unicode,排序规则选 ...

  2. pc 端与移动端区分点击与拖拽事件

    pc 端与移动端区分点击与拖拽事件 PC 端 移动端 在 html 的应用中,拖拽事件为 mousedown -> mousemove -> mouseup 三个事件组成,在一个有拖拽事件 ...

  3. ios keychain 不被清理_卧槽牛弊了,已完美破姐!支持 安卓、ios、PC端,爽....

    感谢您抽出 . . 阅读本文 谢谢您的关注写在前面 点击上方 " 老鬼黑科技 " 选择 " 置顶公众号 " 关键时刻,第一时间送达 老鬼会把全网最好的软件分享给 ...

  4. H5进入页面音乐播放兼容微信,浏览器,APP内嵌

    最近公司接到要做个活动页,需要背景音乐要进入页面就播放,H5与浏览器都要兼容,但看了浏览器好像禁止页面进入播放音乐,然后就找各种文档.废话不多说上代码... HTML代码 <input type ...

  5. 安卓开发仿微信图片拖拽_Android 仿微信朋友圈图片拖拽返回

    目前的app的动画效果是越来越炫了,很多主流app的图片预览返回都有类似功能,比较常见的是ios自带相册,微信朋友圈等等.自己项目中也有类似功能,最近整理了一下这个功能的代码,做个笔记记录,有兴趣的朋 ...

  6. iOS开发——仿微信图片浏览交互的实现(向下拖拽图片退出图片浏览器)

    点击上方"iOS开发",选择"置顶公众号" 关键时刻,第一时间送达! DEMO的github地址:https://github.com/YYProgrammer ...

  7. 点击图片放大,实现移动端双指缩放,单指拖拽功能

    记录一下最近项目中用到的点击图片出现一个遮罩层,同时放大图片显示,移动端可双指缩放图片并单指拖拽图片.再次点击遮罩层透明区域,遮罩层消失 一.实现效果: 页面原图展示: 点击图片后: 二.代码实现: ...

  8. 安卓开发仿微信图片拖拽_Android 仿微信朋友圈发表图片拖拽和删除功能

    朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...

  9. 安卓开发仿微信图片拖拽_仿微信朋友圈发表图片拖拽和删除功能

    原标题:仿微信朋友圈发表图片拖拽和删除功能 中国联通在香港公布了上市公司2017年中期业绩.2017年上半年,公司主要业绩指标持续向好,收入稳步回升,服务收入达到人民币1,241.1亿元,同比增长3. ...

最新文章

  1. ucint核心边缘分析_5G、云计算、物联网与边缘计算的相辅相承
  2. 如何批量给数字前面加半角单引号[转]
  3. Split in Java
  4. 深度学习(七十四)半监督Mean teachers
  5. 过年了,就别再背电脑回家。
  6. 【编译原理笔记09】语法制导翻译:语法制导翻译方案,在非递归的预测分析过程中进行翻译
  7. NLP︱LDA主题模型的应用难题、使用心得及从多元统计角度剖析
  8. DirectX修复工具 4.0 标准版
  9. 走全渠道电商O2O模式的优势体现在哪些地方?
  10. 时光轴一之listView实现时光轴效果
  11. 【coq】函数语言设计 笔记 06 -logic
  12. ValueError: Weights for model sequential have not yet been created. Weights are created when the Mod
  13. 嘉曼服饰上市破发,大跌16%:公司市值37亿 刘溦家族色彩浓厚
  14. 【考研经验】一个苍山的不入流的学生的考研之路
  15. ibatis中resultMap和resultClass的区别 以及parameterClass 的取值
  16. html中onfocus和onblur的使用
  17. JAVA面试题100道
  18. FL Studio教程之如何外接设备
  19. Unity内实现MMD
  20. 互联网、因特网、万维网的区别

热门文章

  1. Iintel CPU 漏洞科普和分析
  2. UG NX二次开发(C#)-建模-图层操作
  3. LittleVGL 学习笔记1-标签,风格,字体
  4. 知识点记录-abase是什么
  5. 男人二十 二十的男人
  6. 2022年全国大学生广告创意大赛
  7. 电商大热,新手无货源小白为什么更要选择抖音小店平台?
  8. Android搜索框输入内容点击键盘的搜索按钮进行搜索
  9. C语言 五子棋 图形界面 人机对战
  10. fast marching matlab,Fast Marching method