js 圖片檢視器
阿新 • • 發佈:2022-05-28
1 /* ImageViewer 圖片檢視器 2 3 parameter: 4 option: Object; 5 6 attribute: 7 image: CanvasImage; 8 scale: Number; //小於1縮小, 大於1放大 9 10 method: 11 center(): this; //圖片在視口居中 12 setViewportScale: this; //將圖片按比例縮放至視口大小 13 setScale(v): this; //設定.scale 14 setImage(image): this; //設定.image部分程式碼 parameter: option: Object; //繼承父的引數15 drawImage(): this; //更新影象 (之後需要.redraw()更新畫布) 16 17 demo: 18 const imageViewer = new ImageViewer({ 19 width: this.width, 20 height: this.width, 21 className: 'shadow-convex', 22 }); 23 24 imageViewer.domElement.style = ` 25 background-color: rgb(127,127,127);26 border-radius: 4px; 27 z-index: 99999; 28 position: absolute; 29 `; 30 31 imageViewer.pos(100, 100).setImage(image) 32 .setViewportScale().center() 33 .drawImage().render(); 34 35 */ 36 class ImageViewer extends CanvasAnimateRender{ 37 38 //允許圖片的最大寬高 (min 不能小於1)39 #min = 1; 40 #max = 4096; 41 42 constructor(option){ 43 super(option); 44 45 this.eventDispatcher = new CanvasAnimateEvent(this); 46 this.target = this.add(new CanvasAnimateCustom()).size(this.box.w, this.box.h); 47 48 this.image = null; 49 this.scale = 1; 50 51 this._rangeMin = 0; 52 this._rangeMax = 0; 53 this._box = new Box(); 54 55 //拖拽事件 56 var tzX = 0, tzY = 0; 57 const onMove = event => { 58 this._box.pos(event.pageX - this.domElementRect.x - tzX, event.pageY - this.domElementRect.y - tzY); 59 this.drawImage().redraw(); 60 61 }, 62 63 onUp = () => { 64 document.body.removeEventListener("pointerup", onUp); 65 document.body.removeEventListener("pointermove", onMove); 66 67 this.eventDispatcher.remove(this.target, 'up', onUp); 68 this.eventDispatcher.remove(this.target, 'move', onMove); 69 70 } 71 72 this.eventDispatcher.add(this.target, "down", event =>{ 73 onUp(); 74 75 if(this.image === null) return; 76 77 tzX = event.offsetX - this._box.x; 78 tzY = event.offsetY - this._box.y; 79 80 this.eventDispatcher.add(this.target, 'up', onUp); 81 this.eventDispatcher.add(this.target, 'move', onMove); 82 83 document.body.addEventListener("pointerup", onUp); 84 document.body.addEventListener("pointermove", onMove); 85 86 }); 87 88 //縮放事件 (以滑鼠為中心點縮放) 89 this.eventDispatcher.add(this.target, "wheel", event =>{ 90 91 const oldWidth = this._box.w; 92 this.setScale(event.wheelDelta === 120 ? this.scale - this.scale * 0.5 : this.scale + this.scale * 0.5); 93 94 const ratio = this._box.w / oldWidth, 95 nx = event.offsetX - ((event.offsetX - this._box.x) * ratio + this._box.x) + this._box.x, 96 ny = event.offsetY - ((event.offsetY - this._box.y) * ratio + this._box.y) + this._box.y; 97 98 this._box.pos(nx, ny); 99 this.drawImage().redraw(); 100 101 }); 102 103 //旋轉事件 104 105 106 this._onUp = onUp; 107 108 } 109 110 exit(){ 111 this._onUp(); 112 if(this.domElement.parentElement) this.domElement.parentElement.removeChild(this.domElement); 113 114 } 115 116 size(w, h, setElem){ 117 super.size(w, h, setElem); 118 this.target.size(this.box.w, this.box.h); 119 120 return this; 121 } 122 123 center(){ 124 this._box.pos((this.box.w - this._box.w)/2, (this.box.h - this._box.h)/2); 125 126 return this; 127 128 } 129 130 setViewportScale(){ 131 if(this.image === null) return this; 132 const width = this.image.width, ratio = width / this.image.height; 133 134 return this.setScale(ratio < 1 ? ratio * this.box.w / width : this.box.w / width); 135 } 136 137 setScale(v){ 138 if(v === Infinity || isNaN(v) === true || typeof v !== "number") return this; 139 this.scale = v < this._rangeMin ? this._rangeMin : v > this._rangeMax ? this._rangeMax : v; 140 if(this.image !== null) this._box.size(this.image.width * this.scale, this.image.height * this.scale); 141 return this; 142 } 143 144 setImage(image){ 145 146 if(this.isCanvasImage(image) === true){ 147 148 if(image.width > image.height){ 149 this._rangeMin = this.#min / image.width; 150 this._rangeMax = this.#max / image.width; 151 152 } 153 154 else{ 155 this._rangeMin = this.#min / image.height; 156 this._rangeMax = this.#max / image.height; 157 158 } 159 160 this.image = image; 161 162 } 163 164 else if(this.image !== null){ 165 166 this.image = null; 167 this.target.clear(); 168 this.redraw(); 169 170 } 171 172 return this; 173 } 174 175 drawImage(){ 176 177 if(this.image !== null) this.target.clear().context.drawImage(this.image, this._box.x, this._box.y, this._box.w, this._box.h); 178 179 return this; 180 } 181 182 }
attribute: image: CanvasImage; // scale: Number; //小於1縮小, 大於1放大
method: center(): this; //圖片在視口居中 setViewportScale: this; //將圖片按比例縮放至視口大小 setScale(v): this; //設定.scale setImage(image): this; //設定.image drawImage(): this; //更新影象 (注意: 之後需要.redraw()更新畫布)
demo:
支援 圖片縮放, 圖片拖拽
1 document.body.style = ` 2 margin: 0; 3 width: ${window.innerWidth}px; 4 height: ${window.innerHeight}px; 5 background-color: #000; 6 `; 7 8 //圖片檢視器 9 const image = new CanvasAnimateCustom().size(100, 100).rect().fill('#54facf').image, 10 11 imageViewer = new ImageViewer({ 12 width: 300, 13 height: 300, 14 }); 15 16 imageViewer.domElement.style.background = '#fff'; 17 18 imageViewer.pos(100, 100).setImage(image) 19 .setViewportScale().center() 20 .drawImage().render();
提取地址: https://pan.baidu.com/s/1TV1j5BeZ7ZhidCq7aQXePA
提取碼: 1111