├── .gitignore ├── README.md ├── babel.config.js ├── lib ├── canvas-player.common.js ├── canvas-player.common.js.map ├── canvas-player.umd.js ├── canvas-player.umd.js.map ├── canvas-player.umd.min.js ├── canvas-player.umd.min.js.map └── demo.html ├── package-lock.json ├── package.json ├── src ├── canvasPlayer.vue ├── data.js ├── index.js └── style │ └── style.css ├── vue.config.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 使用canvas渲染的视频混剪播放器,无缝拼接不同的视频源 2 | 3 | ## ![说明文档](https://img.shields.io/badge/说明文档-v1.0.3-brightgreen.svg) 4 | 5 | 预览地址:http://canvas-v.epochy.cn/ 6 | 7 | ![说明文档](http://canvas-v.epochy.cn/img/preview.png) 8 | ## 安装canvas-video-player 9 | ``` 10 | npm i canvas-video-player 11 | //or 12 | yarn add canvas-video-player 13 | ``` 14 | 15 | ## 使用方式 16 | 17 | 在Vue2.x项目中使用,首先需要在main.js中引入、全局注册 18 | ``` 19 | import canvasPlayer from "canvas-video-player" 20 | 21 | Vue.use(canvasPlayer) 22 | ``` 23 | 在要使用的组件中,采用API的方式调用 24 | 例如: 25 | ``` 26 | 31 | 32 | 83 | ``` 84 | 85 | >喜欢点个小星星 (*^▽^*) 86 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /lib/canvas-player.umd.min.js: -------------------------------------------------------------------------------- 1 | (function(t,e){"object"===typeof exports&&"object"===typeof module?module.exports=e(require("vue")):"function"===typeof define&&define.amd?define("canvas-player",[],e):"object"===typeof exports?exports["canvas-player"]=e(require("vue")):t["canvas-player"]=e(t["Vue"])})("undefined"!==typeof self?self:this,(function(t){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"===typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t["default"]}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s="fb15")}({"00ee":function(t,e,n){var r=n("b622"),o=r("toStringTag"),i={};i[o]="z",t.exports="[object z]"===String(i)},"0366":function(t,e,n){var r=n("1c0b");t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 0:return function(){return t.call(e)};case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,o){return t.call(e,n,r,o)}}return function(){return t.apply(e,arguments)}}},"06cf":function(t,e,n){var r=n("83ab"),o=n("d1e7"),i=n("5c6c"),a=n("fc6a"),s=n("c04e"),c=n("5135"),u=n("0cfb"),f=Object.getOwnPropertyDescriptor;e.f=r?f:function(t,e){if(t=a(t),e=s(e,!0),u)try{return f(t,e)}catch(n){}if(c(t,e))return i(!o.f.call(t,e),t[e])}},"0cfb":function(t,e,n){var r=n("83ab"),o=n("d039"),i=n("cc12");t.exports=!r&&!o((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},1148:function(t,e,n){"use strict";var r=n("a691"),o=n("1d80");t.exports=function(t){var e=String(o(this)),n="",i=r(t);if(i<0||i==1/0)throw RangeError("Wrong number of repetitions");for(;i>0;(i>>>=1)&&(e+=e))1&i&&(n+=e);return n}},"19aa":function(t,e){t.exports=function(t,e,n){if(!(t instanceof e))throw TypeError("Incorrect "+(n?n+" ":"")+"invocation");return t}},"1b7f":function(t,e,n){"use strict";n("e79a")},"1be4":function(t,e,n){var r=n("d066");t.exports=r("document","documentElement")},"1c0b":function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(String(t)+" is not a function");return t}},"1c7e":function(t,e,n){var r=n("b622"),o=r("iterator"),i=!1;try{var a=0,s={next:function(){return{done:!!a++}},return:function(){i=!0}};s[o]=function(){return this},Array.from(s,(function(){throw 2}))}catch(c){}t.exports=function(t,e){if(!e&&!i)return!1;var n=!1;try{var r={};r[o]=function(){return{next:function(){return{done:n=!0}}}},t(r)}catch(c){}return n}},"1cdc":function(t,e,n){var r=n("342f");t.exports=/(?:iphone|ipod|ipad).*applewebkit/i.test(r)},"1d80":function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},"1dde":function(t,e,n){var r=n("d039"),o=n("b622"),i=n("2d00"),a=o("species");t.exports=function(t){return i>=51||!r((function(){var e=[],n=e.constructor={};return n[a]=function(){return{foo:1}},1!==e[t](Boolean).foo}))}},2150:function(t,e,n){var r=n("24fb"),o=n("f7bc");e=r(!1),e.i(o),e.push([t.i,"",""]),t.exports=e},2266:function(t,e,n){var r=n("825a"),o=n("e95a"),i=n("50c4"),a=n("0366"),s=n("35a1"),c=n("2a62"),u=function(t,e){this.stopped=t,this.result=e};t.exports=function(t,e,n){var f,p,d,l,h,v,m,y=n&&n.that,g=!(!n||!n.AS_ENTRIES),x=!(!n||!n.IS_ITERATOR),b=!(!n||!n.INTERRUPTED),w=a(e,y,1+g+b),k=function(t){return f&&c(f),new u(!0,t)},j=function(t){return g?(r(t),b?w(t[0],t[1],k):w(t[0],t[1])):b?w(t,k):w(t)};if(x)f=t;else{if(p=s(t),"function"!=typeof p)throw TypeError("Target is not iterable");if(o(p)){for(d=0,l=i(t.length);l>d;d++)if(h=j(t[d]),h&&h instanceof u)return h;return new u(!1)}f=p.call(t)}v=f.next;while(!(m=v.call(f)).done){try{h=j(m.value)}catch(E){throw c(f),E}if("object"==typeof h&&h&&h instanceof u)return h}return new u(!1)}},"23cb":function(t,e,n){var r=n("a691"),o=Math.max,i=Math.min;t.exports=function(t,e){var n=r(t);return n<0?o(n+e,0):i(n,e)}},"23e7":function(t,e,n){var r=n("da84"),o=n("06cf").f,i=n("9112"),a=n("6eeb"),s=n("ce4e"),c=n("e893"),u=n("94ca");t.exports=function(t,e){var n,f,p,d,l,h,v=t.target,m=t.global,y=t.stat;if(f=m?r:y?r[v]||s(v,{}):(r[v]||{}).prototype,f)for(p in e){if(l=e[p],t.noTargetGet?(h=o(f,p),d=h&&h.value):d=f[p],n=u(m?p:v+(y?".":"#")+p,t.forced),!n&&void 0!==d){if(typeof l===typeof d)continue;c(l,d)}(t.sham||d&&d.sham)&&i(l,"sham",!0),a(f,p,l,t)}}},"241c":function(t,e,n){var r=n("ca84"),o=n("7839"),i=o.concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return r(t,i)}},"24fb":function(t,e,n){"use strict";function r(t,e){var n=t[1]||"",r=t[3];if(!r)return n;if(e&&"function"===typeof btoa){var i=o(r),a=r.sources.map((function(t){return"/*# sourceURL=".concat(r.sourceRoot||"").concat(t," */")}));return[n].concat(a).concat([i]).join("\n")}return[n].join("\n")}function o(t){var e=btoa(unescape(encodeURIComponent(JSON.stringify(t)))),n="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(e);return"/*# ".concat(n," */")}t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var n=r(e,t);return e[2]?"@media ".concat(e[2]," {").concat(n,"}"):n})).join("")},e.i=function(t,n,r){"string"===typeof t&&(t=[[null,t,""]]);var o={};if(r)for(var i=0;in)e.push(arguments[n++]);return b[++x]=function(){("function"==typeof t?t:Function(t)).apply(void 0,e)},r(x),x},v=function(t){delete b[t]},d?r=function(t){m.nextTick(j(t))}:g&&g.now?r=function(t){g.now(j(t))}:y&&!p?(o=new y,i=o.port2,o.port1.onmessage=E,r=c(i.postMessage,i,1)):a.addEventListener&&"function"==typeof postMessage&&!a.importScripts&&l&&"file:"!==l.protocol&&!s(S)?(r=S,a.addEventListener("message",E,!1)):r=w in f("script")?function(t){u.appendChild(f("script"))[w]=function(){u.removeChild(this),k(t)}}:function(t){setTimeout(j(t),0)}),t.exports={set:h,clear:v}},"2d00":function(t,e,n){var r,o,i=n("da84"),a=n("342f"),s=i.process,c=s&&s.versions,u=c&&c.v8;u?(r=u.split("."),o=r[0]<4?1:r[0]+r[1]):a&&(r=a.match(/Edge\/(\d+)/),(!r||r[1]>=74)&&(r=a.match(/Chrome\/(\d+)/),r&&(o=r[1]))),t.exports=o&&+o},"342f":function(t,e,n){var r=n("d066");t.exports=r("navigator","userAgent")||""},"35a1":function(t,e,n){var r=n("f5df"),o=n("3f8c"),i=n("b622"),a=i("iterator");t.exports=function(t){if(void 0!=t)return t[a]||t["@@iterator"]||o[r(t)]}},"3bbe":function(t,e,n){var r=n("861d");t.exports=function(t){if(!r(t)&&null!==t)throw TypeError("Can't set "+String(t)+" as a prototype");return t}},"3f8c":function(t,e){t.exports={}},"408a":function(t,e,n){var r=n("c6b6");t.exports=function(t){if("number"!=typeof t&&"Number"!=r(t))throw TypeError("Incorrect invocation");return+t}},"428f":function(t,e,n){var r=n("da84");t.exports=r},"44ad":function(t,e,n){var r=n("d039"),o=n("c6b6"),i="".split;t.exports=r((function(){return!Object("z").propertyIsEnumerable(0)}))?function(t){return"String"==o(t)?i.call(t,""):Object(t)}:Object},"44de":function(t,e,n){var r=n("da84");t.exports=function(t,e){var n=r.console;n&&n.error&&(1===arguments.length?n.error(t):n.error(t,e))}},4840:function(t,e,n){var r=n("825a"),o=n("1c0b"),i=n("b622"),a=i("species");t.exports=function(t,e){var n,i=r(t).constructor;return void 0===i||void 0==(n=r(i)[a])?e:o(n)}},4930:function(t,e,n){var r=n("2d00"),o=n("d039");t.exports=!!Object.getOwnPropertySymbols&&!o((function(){var t=Symbol();return!String(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&r&&r<41}))},"499e":function(t,e,n){"use strict";function r(t,e){for(var n=[],r={},o=0;on.parts.length&&(r.parts.length=n.parts.length)}else{var a=[];for(o=0;of)if(s=c[f++],s!=s)return!0}else for(;u>f;f++)if((t||f in c)&&c[f]===n)return t||f||0;return!t&&-1}};t.exports={includes:a(!0),indexOf:a(!1)}},"50c4":function(t,e,n){var r=n("a691"),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},5135:function(t,e,n){var r=n("7b0b"),o={}.hasOwnProperty;t.exports=Object.hasOwn||function(t,e){return o.call(r(t),e)}},5692:function(t,e,n){var r=n("c430"),o=n("c6cd");(t.exports=function(t,e){return o[t]||(o[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.15.2",mode:r?"pure":"global",copyright:"© 2021 Denis Pushkarev (zloirock.ru)"})},"56ef":function(t,e,n){var r=n("d066"),o=n("241c"),i=n("7418"),a=n("825a");t.exports=r("Reflect","ownKeys")||function(t){var e=o.f(a(t)),n=i.f;return n?e.concat(n(t)):e}},"5c6c":function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},"605d":function(t,e,n){var r=n("c6b6"),o=n("da84");t.exports="process"==r(o.process)},6069:function(t,e){t.exports="object"==typeof window},"65f0":function(t,e,n){var r=n("861d"),o=n("e8b5"),i=n("b622"),a=i("species");t.exports=function(t,e){var n;return o(t)&&(n=t.constructor,"function"!=typeof n||n!==Array&&!o(n.prototype)?r(n)&&(n=n[a],null===n&&(n=void 0)):n=void 0),new(void 0===n?Array:n)(0===e?0:e)}},"69f3":function(t,e,n){var r,o,i,a=n("7f9a"),s=n("da84"),c=n("861d"),u=n("9112"),f=n("5135"),p=n("c6cd"),d=n("f772"),l=n("d012"),h="Object already initialized",v=s.WeakMap,m=function(t){return i(t)?o(t):r(t,{})},y=function(t){return function(e){var n;if(!c(e)||(n=o(e)).type!==t)throw TypeError("Incompatible receiver, "+t+" required");return n}};if(a||p.state){var g=p.state||(p.state=new v),x=g.get,b=g.has,w=g.set;r=function(t,e){if(b.call(g,t))throw new TypeError(h);return e.facade=t,w.call(g,t,e),e},o=function(t){return x.call(g,t)||{}},i=function(t){return b.call(g,t)}}else{var k=d("state");l[k]=!0,r=function(t,e){if(f(t,k))throw new TypeError(h);return e.facade=t,u(t,k,e),e},o=function(t){return f(t,k)?t[k]:{}},i=function(t){return f(t,k)}}t.exports={set:r,get:o,has:i,enforce:m,getterFor:y}},"6eeb":function(t,e,n){var r=n("da84"),o=n("9112"),i=n("5135"),a=n("ce4e"),s=n("8925"),c=n("69f3"),u=c.get,f=c.enforce,p=String(String).split("String");(t.exports=function(t,e,n,s){var c,u=!!s&&!!s.unsafe,d=!!s&&!!s.enumerable,l=!!s&&!!s.noTargetGet;"function"==typeof n&&("string"!=typeof e||i(n,"name")||o(n,"name",e),c=f(n),c.source||(c.source=p.join("string"==typeof e?e:""))),t!==r?(u?!l&&t[e]&&(d=!0):delete t[e],d?t[e]=n:o(t,e,n)):d?t[e]=n:a(e,n)})(Function.prototype,"toString",(function(){return"function"==typeof this&&u(this).source||s(this)}))},7418:function(t,e){e.f=Object.getOwnPropertySymbols},7839:function(t,e){t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},"7b0b":function(t,e,n){var r=n("1d80");t.exports=function(t){return Object(r(t))}},"7f9a":function(t,e,n){var r=n("da84"),o=n("8925"),i=r.WeakMap;t.exports="function"===typeof i&&/native code/.test(o(i))},"825a":function(t,e,n){var r=n("861d");t.exports=function(t){if(!r(t))throw TypeError(String(t)+" is not an object");return t}},"83ab":function(t,e,n){var r=n("d039");t.exports=!r((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},"861d":function(t,e){t.exports=function(t){return"object"===typeof t?null!==t:"function"===typeof t}},8875:function(t,e,n){var r,o,i;(function(n,a){o=[],r=a,i="function"===typeof r?r.apply(e,o):r,void 0===i||(t.exports=i)})("undefined"!==typeof self&&self,(function(){function t(){var e=Object.getOwnPropertyDescriptor(document,"currentScript");if(!e&&"currentScript"in document&&document.currentScript)return document.currentScript;if(e&&e.get!==t&&document.currentScript)return document.currentScript;try{throw new Error}catch(l){var n,r,o,i=/.*at [^(]*\((.*):(.+):(.+)\)$/gi,a=/@([^@]*):(\d+):(\d+)\s*$/gi,s=i.exec(l.stack)||a.exec(l.stack),c=s&&s[1]||!1,u=s&&s[2]||!1,f=document.location.href.replace(document.location.hash,""),p=document.getElementsByTagName("script");c===f&&(n=document.documentElement.outerHTML,r=new RegExp("(?:[^\\n]+?\\n){0,"+(u-2)+"}[^<]* 4 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "canvas-video-player", 3 | "version": "1.0.4", 4 | "private": false, 5 | "description": "使用canvas渲染的视频混剪播放器,无缝拼接不同的视频源", 6 | "author": "magicscript@163.com|ledtwo", 7 | "main": "lib/canvas-player.umd.min.js", 8 | "scripts": { 9 | "serve": "vue-cli-service serve", 10 | "build": "vue-cli-service build --target lib --name canvas-player --dest lib ./src/index.js", 11 | "lint": "vue-cli-service lint" 12 | }, 13 | "keywords": [ 14 | "video", 15 | "video-player", 16 | "canvas", 17 | "canvas-player" 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "git@github.com:ledtwo/canvas-video-player.git" 22 | }, 23 | "dependencies": {}, 24 | "devDependencies": {}, 25 | "eslintConfig": { 26 | "root": true, 27 | "env": { 28 | "node": true 29 | }, 30 | "extends": [ 31 | "plugin:vue/essential", 32 | "eslint:recommended" 33 | ], 34 | "parserOptions": { 35 | "parser": "babel-eslint" 36 | }, 37 | "rules": {} 38 | }, 39 | "browserslist": [ 40 | "> 1%", 41 | "last 2 versions", 42 | "not dead" 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /src/canvasPlayer.vue: -------------------------------------------------------------------------------- 1 | 63 | 64 | 522 | 525 | 697 | -------------------------------------------------------------------------------- /src/data.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @description: 3 | * @Author: ljc 4 | * @Date: 2021-07-13 12:01:04 5 | * @LastEditors: ljc 6 | * @LastEditTime: 2021-07-13 14:28:20 7 | */ 8 | const videoObj = { 9 | logo: "//cms-static.pengwin.com/data/product_logo/20210713/2671411626148786627659.png", 10 | thumb: 11 | "//cms-static.pengwin.com/data/thumb/20210709/6300931625796768500909.jpg", 12 | list: [ 13 | { 14 | id: 352, 15 | name: "简单充充_衻_1038", 16 | url: "//cms-static.pengwin.com/data/ingredient/20210709/9974121625796764465380.mp4", 17 | thumb: 18 | "//cms-static.pengwin.com/data/thumb/20210709/6300931625796768500909.jpg", 19 | width: 1080, 20 | height: 1920, 21 | logoPosition: { 22 | x: "left", 23 | y: "top", 24 | }, 25 | playPoint: { 26 | end: "3.120000", 27 | start: "0", 28 | }, 29 | index: 0, 30 | }, 31 | { 32 | id: 352, 33 | name: "简单充充_衻_1038", 34 | url: "//cms-static.pengwin.com/data/ingredient/20210709/9974121625796764465380.mp4", 35 | thumb: 36 | "//cms-static.pengwin.com/data/thumb/20210709/6300931625796768500909.jpg", 37 | width: 1080, 38 | height: 1920, 39 | logoPosition: { 40 | x: "right", 41 | y: "top", 42 | }, 43 | playPoint: { 44 | end: "10.200000", 45 | start: "4.320000", 46 | }, 47 | index: 1, 48 | }, 49 | { 50 | id: 352, 51 | name: "简单充充_衻_1038", 52 | url: "//cms-static.pengwin.com/data/ingredient/20210709/9974121625796764465380.mp4", 53 | thumb: 54 | "//cms-static.pengwin.com/data/thumb/20210709/6300931625796768500909.jpg", 55 | width: 1080, 56 | height: 1920, 57 | logoPosition: { 58 | x: "left", 59 | y: "bottom", 60 | }, 61 | playPoint: { 62 | end: "20.320000", 63 | start: "11.400000", 64 | }, 65 | index: 2, 66 | }, 67 | { 68 | id: 352, 69 | name: "简单充充_衻_1038", 70 | url: "//cms-static.pengwin.com/data/ingredient/20210709/9974121625796764465380.mp4", 71 | thumb: 72 | "//cms-static.pengwin.com/data/thumb/20210709/6300931625796768500909.jpg", 73 | width: 1080, 74 | height: 1920, 75 | logoPosition: { 76 | x: "right", 77 | y: "bottom", 78 | }, 79 | playPoint: { 80 | end: "24.72", 81 | start: "21.520000", 82 | }, 83 | index: 3, 84 | }, 85 | ], 86 | duration: 21.12, 87 | common: 1, 88 | name: "简单充充_01_0713", 89 | }; 90 | 91 | export default videoObj; 92 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @description: 3 | * @Author: ljc 4 | * @Date: 2021-07-13 14:22:35 5 | * @LastEditors: ljc 6 | * @LastEditTime: 2021-07-30 11:07:31 7 | */ 8 | import Vue from "vue"; 9 | import Play from "./canvasPlayer.vue"; 10 | import videoObj from "./data"; 11 | let Player = Vue.extend(Play); 12 | let instance; 13 | let seed = 1; 14 | 15 | const component = (options) => { 16 | if (Vue.prototype.$isServer || seed !== 1) return; 17 | options = options || videoObj; 18 | instance = new Player({ 19 | data: options, 20 | }); 21 | instance.id = "player_" + seed++; 22 | instance.vm = instance.$mount(); 23 | instance.dom = instance.vm.$el; 24 | document.body.appendChild(instance.dom); 25 | instance.vm.init(); 26 | instance.dom.style.zIndex = seed + 1001; 27 | seed = 2; 28 | instance.vm.setFree = function () { 29 | seed = 1; 30 | }; 31 | return instance.vm; 32 | }; 33 | 34 | export default { 35 | install: (Vue) => { 36 | Vue.prototype.$canvasVideoPlayer = component; 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /src/style/style.css: -------------------------------------------------------------------------------- 1 | .volume { 2 | margin-right: 10px; 3 | --line: #fff; 4 | --line-width: 6px; 5 | --duration: .5s; 6 | position: relative; 7 | cursor: pointer; 8 | -webkit-tap-highlight-color: transparent; 9 | } 10 | 11 | .volume input { 12 | position: absolute; 13 | width: 100%; 14 | height: 100%; 15 | opacity: 0; 16 | } 17 | 18 | .volume input+svg { 19 | display: block; 20 | fill: none; 21 | stroke: var(--line); 22 | stroke-linecap: round; 23 | stroke-linejoin: round; 24 | stroke-width: var(--line-width); 25 | width: 25px; 26 | height: 20px; 27 | } 28 | 29 | .volume input+svg path { 30 | -webkit-animation: var(--name) var(--duration) ease forwards; 31 | animation: var(--name) var(--duration) ease forwards; 32 | } 33 | 34 | .volume input+svg path:nth-child(2) { 35 | stroke-dashoffset: 1px; 36 | } 37 | 38 | .volume input+svg path:nth-child(3) { 39 | stroke-dashoffset: 1px; 40 | } 41 | 42 | .volume input:checked+svg path:nth-child(1) { 43 | --name: shape; 44 | } 45 | 46 | .volume input:checked+svg path:nth-child(2) { 47 | --name: small; 48 | } 49 | 50 | .volume input:checked+svg path:nth-child(3) { 51 | --name: large; 52 | } 53 | 54 | .volume input:not(:checked)+svg path:nth-child(1) { 55 | --name: shape-r; 56 | } 57 | 58 | .volume input:not(:checked)+svg path:nth-child(2) { 59 | --name: small-r; 60 | } 61 | 62 | .volume input:not(:checked)+svg path:nth-child(3) { 63 | --name: large-r; 64 | } 65 | 66 | @-webkit-keyframes small { 67 | 68 | 0%, 69 | 30% { 70 | stroke-dasharray: 0 0 30px 64px; 71 | } 72 | 73 | 40% { 74 | stroke-dashoffset: 16px; 75 | } 76 | 77 | 80%, 78 | 100% { 79 | stroke-dashoffset: 1px; 80 | } 81 | 82 | 70% { 83 | stroke-dasharray: 0 43px 30px 64px; 84 | } 85 | 86 | 100% { 87 | stroke-dasharray: 0 39px 30px 64px; 88 | } 89 | } 90 | 91 | @keyframes small { 92 | 93 | 0%, 94 | 30% { 95 | stroke-dasharray: 0 0 30px 64px; 96 | } 97 | 98 | 40% { 99 | stroke-dashoffset: 16px; 100 | } 101 | 102 | 80%, 103 | 100% { 104 | stroke-dashoffset: 1px; 105 | } 106 | 107 | 70% { 108 | stroke-dasharray: 0 43px 30px 64px; 109 | } 110 | 111 | 100% { 112 | stroke-dasharray: 0 39px 30px 64px; 113 | } 114 | } 115 | 116 | @-webkit-keyframes small-r { 117 | 0% { 118 | stroke-dasharray: 0 39px 30px 64px; 119 | } 120 | 121 | 0%, 122 | 40% { 123 | stroke-dashoffset: 1px; 124 | } 125 | 126 | 70% { 127 | stroke-dashoffset: 16px; 128 | } 129 | 130 | 70%, 131 | 100% { 132 | stroke-dasharray: 0 0 30px 64px; 133 | } 134 | } 135 | 136 | @keyframes small-r { 137 | 0% { 138 | stroke-dasharray: 0 39px 30px 64px; 139 | } 140 | 141 | 0%, 142 | 40% { 143 | stroke-dashoffset: 1px; 144 | } 145 | 146 | 70% { 147 | stroke-dashoffset: 16px; 148 | } 149 | 150 | 70%, 151 | 100% { 152 | stroke-dasharray: 0 0 30px 64px; 153 | } 154 | } 155 | 156 | @-webkit-keyframes large { 157 | 158 | 0%, 159 | 30% { 160 | stroke-dasharray: 0 0 50px 84px; 161 | } 162 | 163 | 40% { 164 | stroke-dashoffset: 16px; 165 | } 166 | 167 | 80%, 168 | 100% { 169 | stroke-dashoffset: 1px; 170 | } 171 | 172 | 70% { 173 | stroke-dasharray: 0 82px 32px 84px; 174 | } 175 | 176 | 100% { 177 | stroke-dasharray: 0 78px 32px 84px; 178 | } 179 | } 180 | 181 | @keyframes large { 182 | 183 | 0%, 184 | 30% { 185 | stroke-dasharray: 0 0 50px 84px; 186 | } 187 | 188 | 40% { 189 | stroke-dashoffset: 16px; 190 | } 191 | 192 | 80%, 193 | 100% { 194 | stroke-dashoffset: 1px; 195 | } 196 | 197 | 70% { 198 | stroke-dasharray: 0 82px 32px 84px; 199 | } 200 | 201 | 100% { 202 | stroke-dasharray: 0 78px 32px 84px; 203 | } 204 | } 205 | 206 | @-webkit-keyframes large-r { 207 | 0% { 208 | stroke-dasharray: 0 78px 32px 84px; 209 | } 210 | 211 | 0%, 212 | 40% { 213 | stroke-dashoffset: 1px; 214 | } 215 | 216 | 70% { 217 | stroke-dashoffset: 16px; 218 | } 219 | 220 | 70%, 221 | 100% { 222 | stroke-dasharray: 0 0 50px 84px; 223 | } 224 | } 225 | 226 | @keyframes large-r { 227 | 0% { 228 | stroke-dasharray: 0 78px 32px 84px; 229 | } 230 | 231 | 0%, 232 | 40% { 233 | stroke-dashoffset: 1px; 234 | } 235 | 236 | 70% { 237 | stroke-dashoffset: 16px; 238 | } 239 | 240 | 70%, 241 | 100% { 242 | stroke-dasharray: 0 0 50px 84px; 243 | } 244 | } 245 | 246 | @-webkit-keyframes shape { 247 | 0% { 248 | stroke-dasharray: 60px 0 184px; 249 | stroke-dashoffset: 0; 250 | } 251 | 252 | 70% { 253 | stroke-dasharray: 63px 51px 184px; 254 | stroke-dashoffset: 21px; 255 | } 256 | 257 | 100% { 258 | stroke-dasharray: 59px 47px 184px; 259 | stroke-dashoffset: 17px; 260 | } 261 | } 262 | 263 | @keyframes shape { 264 | 0% { 265 | stroke-dasharray: 60px 0 184px; 266 | stroke-dashoffset: 0; 267 | } 268 | 269 | 70% { 270 | stroke-dasharray: 63px 51px 184px; 271 | stroke-dashoffset: 21px; 272 | } 273 | 274 | 100% { 275 | stroke-dasharray: 59px 47px 184px; 276 | stroke-dashoffset: 17px; 277 | } 278 | } 279 | 280 | @-webkit-keyframes shape-r { 281 | 0% { 282 | stroke-dasharray: 59px 47px 184px; 283 | stroke-dashoffset: 17px; 284 | } 285 | 286 | 100% { 287 | stroke-dasharray: 60px 0 184px; 288 | stroke-dashoffset: 0; 289 | } 290 | } 291 | 292 | @keyframes shape-r { 293 | 0% { 294 | stroke-dasharray: 59px 47px 184px; 295 | stroke-dashoffset: 17px; 296 | } 297 | 298 | 100% { 299 | stroke-dasharray: 60px 0 184px; 300 | stroke-dashoffset: 0; 301 | } 302 | } 303 | /* // 定义进度条动画 */ 304 | @keyframes play1 { 305 | 0% { 306 | width: 0; 307 | } 308 | 309 | 100% { 310 | width: 100%; 311 | } 312 | } 313 | 314 | @keyframes replay1 { 315 | to { 316 | width: 100%; 317 | } 318 | } 319 | 320 | .loadEffect { 321 | position: absolute; 322 | top: 30%; 323 | width: 100px; 324 | height: 100px; 325 | position: relative; 326 | margin: 0 auto; 327 | margin-top: 100px; 328 | } 329 | 330 | .loadEffect span { 331 | display: inline-block; 332 | width: 16px; 333 | height: 16px; 334 | border-radius: 50%; 335 | background: #00a1d6; 336 | position: absolute; 337 | -webkit-animation: load 1.04s ease infinite; 338 | } 339 | 340 | @keyframes load { 341 | 0% { 342 | opacity: 1; 343 | } 344 | 345 | 100% { 346 | opacity: 0.2; 347 | } 348 | } 349 | 350 | .loadEffect span:nth-child(1) { 351 | left: 0; 352 | top: 50%; 353 | margin-top: -8px; 354 | -webkit-animation-delay: 0.13s; 355 | } 356 | 357 | .loadEffect span:nth-child(2) { 358 | left: 14px; 359 | top: 14px; 360 | -webkit-animation-delay: 0.26s; 361 | } 362 | 363 | .loadEffect span:nth-child(3) { 364 | left: 50%; 365 | top: 0; 366 | margin-left: -8px; 367 | -webkit-animation-delay: 0.39s; 368 | } 369 | 370 | .loadEffect span:nth-child(4) { 371 | top: 14px; 372 | right: 14px; 373 | -webkit-animation-delay: 0.52s; 374 | } 375 | 376 | .loadEffect span:nth-child(5) { 377 | right: 0; 378 | top: 50%; 379 | margin-top: -8px; 380 | -webkit-animation-delay: 0.65s; 381 | } 382 | 383 | .loadEffect span:nth-child(6) { 384 | right: 14px; 385 | bottom: 14px; 386 | -webkit-animation-delay: 0.78s; 387 | } 388 | 389 | .loadEffect span:nth-child(7) { 390 | bottom: 0; 391 | left: 50%; 392 | margin-left: -8px; 393 | -webkit-animation-delay: 0.91s; 394 | } 395 | 396 | .loadEffect span:nth-child(8) { 397 | bottom: 14px; 398 | left: 14px; 399 | -webkit-animation-delay: 1.04s; 400 | } 401 | 402 | .playContainer { 403 | position: absolute; 404 | left: 50%; 405 | top: 50%; 406 | transform: translate(-50%,-50%); 407 | float: left; 408 | padding: 20px; 409 | transition: all 0.5s; 410 | } 411 | 412 | .playContainer li { 413 | position: relative; 414 | float: left; 415 | border: 40px solid #404040; 416 | color: #404040; 417 | height: 0; 418 | width: 0; 419 | -webkit-border-radius: 100%; 420 | -moz-border-radius: 100%; 421 | -o-border-radius: 100%; 422 | border-radius: 100%; 423 | margin: 0 20px; 424 | } 425 | 426 | .playContainer a { 427 | border-style: solid; 428 | text-indent: -9999px; 429 | position: absolute; 430 | top: -16px; 431 | left: -6px; 432 | } 433 | 434 | .playBtn a { 435 | border-color: transparent transparent transparent #fff; 436 | border-width: 16px 0 16px 24px; 437 | width: 0; 438 | height: 0; 439 | } 440 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @description: 3 | * @Author: ljc 4 | * @Date: 2021-07-29 12:05:42 5 | * @LastEditors: ljc 6 | * @LastEditTime: 2021-07-29 12:06:33 7 | */ 8 | const path = require('path') 9 | // const webpack = require('webpack') 10 | module.exports = { 11 | publicPath: '/dist/', 12 | css: { 13 | extract: false, 14 | }, 15 | outputDir: path.resolve(__dirname, './dist'), 16 | configureWebpack: { 17 | output: { 18 | filename: 'canvas-player.min.js', 19 | library: 'canvas-player', 20 | libraryTarget: 'umd', 21 | umdNamedDefine: true, 22 | }, 23 | }, 24 | } 25 | --------------------------------------------------------------------------------