@theonlyducks/videojs-zoom
Version:
Simple plugin to zoom in video.js player
2 lines (1 loc) • 12 kB
JavaScript
!function(t,s){"object"==typeof exports&&"undefined"!=typeof module?module.exports=s(require("video.js")):"function"==typeof define&&define.amd?define(["video.js"],s):(t="undefined"!=typeof globalThis?globalThis:t||self)["@theonlyducks/videojs-zoom"]=s(t.videojs)}(this,(function(t){"use strict";var s={name:"@theonlyducks/videojs-zoom",title:"Video.js Zoom",version:"1.3.6",private:!1,description:"Simple plugin to zoom in video.js player",author:"Giovane Santos <giovanesantos1999@gmail.com>",license:"MIT",main:"./dist/videojs-zoom.cjs.js",module:"./dist/videojs-zoom.es.js",browser:"./dist/videojs-zoom.js",exports:{".":{import:"./dist/videojs-zoom.es.js",require:"./dist/videojs-zoom.cjs.js"},"./styles":{import:"./dist/videojs-zoom.css",require:"./dist/videojs-zoom.css"}},scripts:{build:"yarn clean && yarn build:js && yarn build:css","build:js":"rollup -c","build:css":"mv dist/plugin.css dist/videojs-zoom.css ",clean:"rm -rf ./dist",start:"webpack serve --progress"},engines:{node:">=16.0"},repository:{type:"git",url:"git+https://github.com/theonlyducks/videojs-zoom-duck.git"},bugs:{url:"https://github.com/theonlyducks/videojs-zoom-duck/issues"},files:["dist","LICENSE","README.md"],keywords:["videojs","video-zoom","videojs-zoom","videojs-zoom-duck","videojs-plugin","videojs-plugin-zoom"],browserslist:["defaults"],peerDependencies:{"video.js":">= ^7 || >= ^8"},devDependencies:{"@babel/cli":"^7.19.3","@babel/core":"^7.19.6","@babel/preset-env":"^7.19.4","@rollup/plugin-babel":"^6.0.3","@rollup/plugin-commonjs":"^24.0.0","@rollup/plugin-json":"^6.0.0","@rollup/plugin-node-resolve":"^15.0.1","babel-loader":"^9.0.1","css-loader":"^6.7.1","html-webpack-plugin":"^5.5.0",rollup:"^3.3.0","rollup-plugin-copy":"^3.4.0","rollup-plugin-terser":"^7.0.2","style-loader":"^3.3.1","video.js":"^8.6.1",webpack:"^5.76.0","webpack-cli":"^4.10.0","webpack-dev-server":"^4.11.1"},dependencies:{}};class e{static _instance=null;constructor(){this._listeners=[]}static getInstance(){return e._instance||(e._instance=new e),e._instance}subscribe(t,s){this._listeners.push({event:t,callback:s})}notify(t,s){this._listeners.forEach((e=>{if(e.event===t)return e.callback(s)}))}}const o=.2;class i{constructor(t,s){this.player=t.el(),this.plugin=s.plugin,this.observer=e.getInstance(),t.on("loadeddata",(()=>{this._updateSalt()})),t.on("playerresize",(()=>{this._updateSalt()})),this.observer.subscribe("change",(t=>{this.state={...t,saltMoveX:70,saltMoveY:70},this._updateSalt()}))}_updateSalt(){this.state.saltMoveX=this.player.offsetWidth*o/2,this.state.saltMoveY=this.player.offsetHeight*o/2}_zoom(t){this.state.zoom=t,this.plugin.zoom(this.state.zoom),this.plugin.listeners.change(this.state)}zoomIn(){const t=Math.max(1,Math.min(9.8,this.state.zoom+o));this._zoom(Number(t.toFixed(1)))}zoomOut(){const t=Math.max(1,this.state.zoom-o);this._zoom(Number(t.toFixed(1))),1===Math.sign(this.state.moveY)?this.moveUp():this.moveDown(),1===Math.sign(this.state.moveX)?this.moveLeft():this.moveRight()}zoomHandler(t){1===Math.sign(t)?this.zoomIn():this.zoomOut()}_move(){this.plugin.move(this.state.moveX,this.state.moveY),this.plugin.listeners.change(this.state)}moveUp(){const t=this._getMoveYAvailable();this.state.moveY=Math.max(-t,Math.min(t,this.state.moveY+this.state.saltMoveY)),this._move()}moveDown(){const t=this._getMoveYAvailable();this.state.moveY=Math.max(-t,Math.min(t,this.state.moveY-this.state.saltMoveY)),this._move()}moveX(t){const s=this._getMoveYAvailable();this.state.moveY=Math.max(-s,Math.min(s,this.state.moveY+t)),this._move()}_getMoveYAvailable(){return this.state.saltMoveY*((this.state.zoom-1)/o)}moveLeft(){const t=this._getMoveXAvailable();this.state.moveX=Math.max(-t,Math.min(t,this.state.moveX+this.state.saltMoveX)),this._move()}moveRight(){const t=this._getMoveXAvailable();this.state.moveX=Math.max(-t,this.state.moveX-this.state.saltMoveX),this._move()}moveY(t){const s=this._getMoveXAvailable();this.state.moveX=Math.max(-s,Math.min(s,this.state.moveX+t)),this._move()}_getMoveXAvailable(){return this.state.saltMoveX*((this.state.zoom-1)/o)}_rotate(){this.plugin.rotate(this.state.rotate),this.plugin.listeners.change(this.state)}rotate(){this.state.rotate-=180,-360===this.state.rotate&&(this.state.rotate=0),this._rotate()}_flip(){this.plugin.flip(this.state.flip),this.plugin.listeners.change(this.state)}flip(){this.state.flip="+"===this.state.flip?"-":"+",this._flip()}reset(){this.state.zoom=1,this.state.moveX=0,this.state.moveY=0,this.state.rotate=0,this.plugin.zoom(1),this.plugin.flip("+"),this.plugin.rotate(0),this.plugin.move(0,0),this.plugin.listeners.change(this.state)}}class n{constructor(t){this.content=null,this.state=t.state,this._createContent()}getContent(){return this.content}_createContent(){this.content="",this.state.showZoom&&(this.content+='\n\t\t\t<div class="vjs-zoom-duck__container--row">\n\t\t\t\t<button id="vjs-zoom-duck__zoomIn" class="vjs-zoom-duck__button">\n\t\t\t\t\t<span class="vjs-zoom-icons">add</span>\n\t\t\t\t</button>\n\t\t\t\t<span class="vjs-zoom-duck__space"></span>\n\t\t\t\t<button id="vjs-zoom-duck__zoomOut" class="vjs-zoom-duck__button">\n\t\t\t\t\t<span class="vjs-zoom-icons">remove</span>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t'),this.state.showMove&&(this.content+='\n\t\t\t<div class="vjs-zoom-duck__container--row">\n\t\t\t\t<span class="vjs-zoom-duck__space"></span>\n\t\t\t\t<button id="vjs-zoom-duck__moveUp" class="vjs-zoom-duck__button">\n\t\t\t\t\t<span class="vjs-zoom-icons">arrow_drop_up</span>\n\t\t\t\t</button>\n\t\t\t\t<span class="vjs-zoom-duck__space"></span>\n\t\t\t</div>\n\t\t\t<div class="vjs-zoom-duck__container--row">\n\t\t\t\t<button id="vjs-zoom-duck__moveLeft" class="vjs-zoom-duck__button">\n\t\t\t\t\t<span class="vjs-zoom-icons">arrow_left</span>\n\t\t\t\t</button>\n\t\t\t\t<button id="vjs-zoom-duck__reset" class="vjs-zoom-duck__button">\n\t\t\t\t\t<span class="vjs-zoom-icons">fiber_manual_record</span>\n\t\t\t\t</button>\n\t\t\t\t<button id="vjs-zoom-duck__moveRight" class="vjs-zoom-duck__button">\n\t\t\t\t\t<span class="vjs-zoom-icons">arrow_right</span>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div class="vjs-zoom-duck__container--row">\n\t\t\t\t<span class="vjs-zoom-duck__space"></span>\n\t\t\t\t<button id="vjs-zoom-duck__moveDown" class="vjs-zoom-duck__button">\n\t\t\t\t\t<span class="vjs-zoom-icons">arrow_drop_down</span>\n\t\t\t\t</button>\n\t\t\t\t<span class="vjs-zoom-duck__space"></span>\n\t\t\t</div>\n\t\t'),this.state.showRotate&&(this.content+='\n\t\t\t<div class="vjs-zoom-duck__container--row">\n\t\t\t\t<button id="vjs-zoom-duck__rotate" class="vjs-zoom-duck__button">\n\t\t\t\t\t<span class="vjs-zoom-icons">rotate_left</span>\n\t\t\t\t</button>\n\t\t\t\t<span class="vjs-zoom-duck__space"></span>\n\t\t\t\t<button id="vjs-zoom-duck__flip" class="vjs-zoom-duck__button">\n\t\t\t\t\t<span class="vjs-zoom-icons">swap_horiz</span>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t')}}const a=t.getComponent("Component");const l=t.getComponent("Component");const r=t.getComponent("Button");const{version:h}=s,c=t.getPlugin("plugin"),d={zoom:1,moveX:0,moveY:0,flip:"+",rotate:0,showZoom:!0,showMove:!0,showRotate:!0,gestureHandler:!1};class m extends c{constructor(s){let o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(s),t.log("[~Zoom Plugin] start ",o),this._enabled=!0,this.player=s,this.playerEl=s.el(),this.listeners={click:()=>{},change:()=>{}},this.playerEl.style.overflow="hidden",this.state=Object.assign(d,o),this.state.flip="+",(this.state.showZoom||this.state.showMove||this.state.showRotate)&&(this.player.getChild("ControlBar").addChild("ZoomButton"),this.player.addChild("ZoomModal",{plugin:this,state:this.state})),this.state.gestureHandler&&this.player.addChild("ZoomGesture",{plugin:this,state:this.state}),this._observer=e.getInstance(),this._observer.notify("plugin",{enabled:this._enabled}),this._setTransform()}zoom(t){if(t<=0)throw new Error("Zoom value invalid");this.state.zoom=t,this._setTransform()}rotate(t){this.state.rotate=t,this._setTransform()}move(t,s){this.state.moveX=t,this.state.moveY=s,this._setTransform()}flip(t){this.state.flip=t,this._setTransform()}toggle(){const[t]=this.playerEl.getElementsByClassName("vjs-zoom-duck__container");t.classList.toggle("open")}listen(t,s){this.listeners[t]=s}_setTransform(){const[t]=this.playerEl.getElementsByTagName("video");t.style.transform=`\n\t\t\ttranslate(${this.state.moveX}px, ${this.state.moveY}px) \n\t\t\tscale(${this.state.flip}${this.state.zoom}, ${this.state.zoom}) \n\t\t\trotate(${this.state.rotate}deg)\n\t\t`,this._notify()}_notify(){this._observer.notify("change",this.state)}enablePlugin(){if(this._enabled)return;this._enabled=!this._enabled,this.player.getChild("ControlBar").addChild("ZoomButton");e.getInstance().notify("plugin",{enabled:this._enabled})}disablePlugin(){if(!this._enabled)return;this._enabled=!this._enabled,this.player.getChild("ControlBar").removeChild("ZoomButton");const[t]=this.playerEl.getElementsByClassName("vjs-zoom-duck__container");t.classList.remove("open");e.getInstance().notify("plugin",{enabled:this._enabled})}handleStateChanged(t){}}return m.defaultState={},m.VERSION=h,t.registerComponent("ZoomModal",class extends a{constructor(t,s){super(t,s),this._enabled=!1,this._observer=e.getInstance(),this.player=t.el(),this.plugin=s.plugin,this.function=new i(t,s),t.on("playing",(()=>{this.listeners()})),this._observer.subscribe("plugin",(t=>{this._enabled=t.enabled}))}createEl(){const s=t.dom.createEl("div",{className:"vjs-zoom-duck__container"}),e=new n(this.options_);return s.innerHTML=e.getContent(),s}listeners(){let t=this.player.getElementsByClassName("vjs-zoom-duck__button");t=Array.from(t),t.map((t=>{const[,s]=t.id.split("__");t.onclick=()=>this.function[s](),t.title=s.charAt(0).toUpperCase()+s.slice(1)}))}toggle(){if(!this._enabled)return;const[t]=this.player.getElementsByClassName("vjs-zoom-duck__container");t.classList.toggle("open"),this.plugin.listeners.click()}open(){if(!this._enabled)return;const[t]=this.player.getElementsByClassName("vjs-zoom-duck__container");t.classList.add("open"),this.plugin.listeners.click()}close(){if(!this._enabled)return;const[t]=this.player.getElementsByClassName("vjs-zoom-duck__container");t.classList.remove("open"),this.plugin.listeners.click()}}),t.registerComponent("ZoomGesture",class extends l{constructor(t,s){super(t,s),this._enabled=!1,this._observer=e.getInstance(),this.pointers={},this.player=t.el(),this.state=s.state,this.function=new i(t,s),t.on("loadstart",(()=>{this.gesture()})),this._observer.subscribe("plugin",(t=>{this._enabled=t.enabled}))}gesture(){this.player.addEventListener("pointerdown",(t=>{this.pointers[t.pointerId]=t})),this.player.addEventListener("pointerup",(t=>{delete this.pointers[t.pointerId],this.player.firstChild.style.pointerEvents=""})),this.player.addEventListener("pointerleave",(t=>{delete this.pointers[t.pointerId]})),this.player.addEventListener("pointermove",(t=>{if(!this._enabled)return;if(!Object.keys(this.pointers).length)return;this.player.firstChild.style.pointerEvents="none";const s=this.pointers[t.pointerId],e=t.clientX-s.clientX,o=t.clientY-s.clientY;this.pointers[t.pointerId]=t,this.function.moveY(e),this.function.moveX(o)})),this.player.addEventListener("wheel",(t=>{t.preventDefault(),t.stopPropagation(),this._enabled&&(this.function.zoomHandler(-.01*t.deltaY),this.function.moveY(0),this.function.moveX(0))}))}}),t.registerComponent("ZoomButton",class extends r{constructor(t,s){super(t,s),this.isOpen=!1,t.on("useractive",(()=>{if(!this.isOpen)return;this.player().getChild("ZoomModal").open()})),t.on("userinactive",(()=>{if(!this.isOpen)return;this.player().getChild("ZoomModal").close()}))}buildCSSClass(){const[s]=t.VERSION.split(".");return`vjs-zoom-duck vjs-zoom-duck-${s} ${super.buildCSSClass()}`}handleClick(){const s=this.player().getChild("ZoomModal");t.log("[~Zoom Plugin] button handleClick"),this.isOpen=!this.isOpen,s.toggle()}}),t.registerPlugin("zoomPlugin",m),m}));