VueJS рдкрд░ рд╕рд░рд▓ рдЫрд╡рд┐ рд╕рдВрдкрд╛рджрдХ

рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдореБрдЭреЗ рдПрдХ рдСрдирд▓рд╛рдЗрди рд╕реНрдЯреЛрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реЗрд╡рд╛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдорд┐рд▓рд╛ рдЬреЛ рдореЗрд░реА рддрд╕реНрд╡реАрд░реЛрдВ рдХреЛ рдкреНрд░рд┐рдВрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрджреЗрд╢ рджреЗрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред

рд╕реЗрд╡рд╛ рдиреЗ рдПрдХ "рд╕рд░рд▓" рдЫрд╡рд┐ рд╕рдВрдкрд╛рджрдХ рдХреА рд░рдЪрдирд╛ рдХреА, рдЬрд┐рд╕рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдореИрдВ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рдФрд░ рд╕рднреА рдХреНрдпреЛрдВрдХрд┐ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреА рдкреНрд░рдЪреБрд░рддрд╛ рдХреЗ рдмреАрдЪ рдореБрдЭреЗ рдЙрдкрдпреБрдХреНрдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдирд╣реАрдВ рдорд┐рд▓реА, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕реАрдПрд╕рдПрд╕ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рдмрд╛рд░реАрдХрд┐рдпрд╛рдВ, рдЕрдЪрд╛рдирдХ рдореЗрд░реЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБрдд рд╣реА рдЧреИрд░-рддреБрдЪреНрдЫ рдХрд╛рд░реНрдп рдмрди рдЧрдИрдВред

рдЫрд╡рд┐

рдореБрдЦреНрдп рдХрд╛рд░реНрдп:


  1. рдЕрдкрдиреЗ рдбрд┐рд╡рд╛рдЗрд╕, Google рдбреНрд░рд╛рдЗрд╡ рдФрд░ рдЗрдВрд╕реНрдЯрд╛рдЧреНрд░рд╛рдо рд╕реЗ рдЪрд┐рддреНрд░ рдЕрдкрд▓реЛрдб рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ред
  2. рдЫрд╡рд┐ рд╕рдВрдкрд╛рджрди: рдлрд╕рд▓ рдХреНрд╖реЗрддреНрд░ рдХреЛ рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдШреВрдордирд╛, рдШреВрдордирд╛, рдХреНрд╖реИрддрд┐рдЬ рдФрд░ рдКрд░реНрдзреНрд╡рд╛рдзрд░ рдкреНрд░рддрд┐рдмрд┐рдВрдм, рдЬрд╝реВрдорд┐рдВрдЧ, рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдЫрд╡рд┐ рд╕рдВрд░реЗрдЦрдгред

рдпрджрд┐ рд╡рд┐рд╖рдп рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЕрдЧрд▓реЗ рдкреНрд░рдХрд╛рд╢рди рдореЗрдВ рдореИрдВ рдЖрд╡реЗрджрди рдХреЗ рдмреИрдХреЗрдВрдб рднрд╛рдЧ рдореЗрдВ Google рдбреНрд░рд╛рдЗрд╡ рдФрд░ рдЗрдВрд╕реНрдЯрд╛рдЧреНрд░рд╛рдо рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛, рдЬрд╣рд╛рдВ рд▓реЛрдХрдкреНрд░рд┐рдп NodeJS + рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдмрдВрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдлрд╝реНрд░рдВрдЯреЗрдВрдб рдХреЗ рд╕рдВрдЧрдарди рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдЕрджреНрднреБрдд Vue рдлреНрд░реЗрдорд╡рд░реНрдХ рдЪреБрдирд╛ред рд╕рд┐рд░реНрдл рдЗрд╕рд▓рд┐рдП рдХрд┐ рдпрд╣ рдореБрдЭреЗ рдХрдард┐рди рдХреЛрдгреАрдп рдФрд░ рдХрд╖реНрдЯрдкреНрд░рдж рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рдмрд╛рдж рдкреНрд░реЗрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛, рдорд╛рд░реНрдЧреЛрдВ рдФрд░ рдЕрдиреНрдп рдШрдЯрдХреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдЪрд▓реЛ рд╕реАрдзреЗ рд╕рдВрдкрд╛рджрдХ рдкрд░ рдЬрд╛рдПрдВред

рд╡реИрд╕реЗ, рд╕рдВрдкрд╛рджрдХ рдХреЗ рдбреЗрдореЛ рдХреЛ рдпрд╣рд╛рдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

рд╣рдореЗрдВ рджреЛ рдШрдЯрдХреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ - рдореЗрдВ рдореБрдЦреНрдп рддрд░реНрдХ рдФрд░ рдирд┐рдпрдВрддреНрд░рдг рд╢рд╛рдорд┐рд▓ рд╣реЛрдВрдЧреЗ
рдкреВрд░реНрд╡рд╛рд╡рд▓реЛрдХрди - рдЫрд╡рд┐ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрдЧрд╛

рдШрдЯрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ:
<Edit> <Preview v-if="image" ref="preview" :matrix="matrix" :image="image" :transform="transform" @resized="areaResized" @loaded="imageLoaded" @moved="imageMoved" /> <input type="range" :min="minZoom" :max="maxZoom" step="any" @change="onZoomEnd" v-model.number="transform.zoom" :disabled="!imageReady" /> <button @click="rotateMinus" :disabled="!imageReady">Rotate left</button> <button @click="rotatePlus" :disabled="!imageReady">Rotate right</button> <button @click="flipY" :disabled="!imageReady">Flip horizontal</button> <button @click="flipX" :disabled="!imageReady">Flip vertical</button> </Edit> 


рдкреВрд░реНрд╡рд╛рд╡рд▓реЛрдХрди рдШрдЯрдХ 3 рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

рднрд░реА рд╣реБрдИ - рдЫрд╡рд┐ рд▓реЛрдб рдШрдЯрдирд╛
рдЖрдХрд╛рд░ рдкрд░рд┐рд╡рд░реНрддрди - рд╡рд┐рдВрдбреЛ рдЖрдХрд╛рд░ рдШрдЯрдирд╛
рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд - рдЪрд┐рддреНрд░ рдЪрд▓рддреА рдШрдЯрдирд╛

рд╡рд┐рдХрд▓реНрдк:

рдЫрд╡рд┐ - рдЫрд╡рд┐ рд▓рд┐рдВрдХ
рдореИрдЯреНрд░рд┐рдХреНрд╕ - рд╕реАрдПрд╕рдПрд╕ рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрди рдореИрдЯреНрд░рд┐рдХреНрд╕
рдкрд░рд┐рд╡рд░реНрддрди - рдПрдХ рд╡рд╕реНрддреБ рдЬреЛ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреА рд╣реИ

рдЫрд╡рд┐ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмреЗрд╣рддрд░ рдврдВрдЧ рд╕реЗ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, img рдХреА рдкреВрд░реНрдг рд╕реНрдерд┐рддрд┐ рд╣реИ, рдФрд░ рдкрд░рд┐рд╡рд░реНрддрди-рдореВрд▓ рдЧреБрдг, рдкрд░рд┐рд╡рд░реНрддрди рд╕рдВрджрд░реНрдн рдмрд┐рдВрджреБ, рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдорд╛рди "0 0" рдкрд░ рд╕реЗрдЯ рд╣реИ, рдЬреЛ рдореВрд▓ рдХреЗ рдКрдкрд░реА рдмрд╛рдПрдВ рдХреЛрдиреЗ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ (рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рдкрд╣рд▓реЗ!) рдЫрд╡рд┐ред

рдореЗрд░реЗ рд╕рд╛рдордиреЗ рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдкрд░рд┐рд╡рд░реНрддрди-рдореВрд▓ рдмрд┐рдВрджреБ рд╣рдореЗрд╢рд╛ рд╕рдВрдкрд╛рджрди рдХреНрд╖реЗрддреНрд░ рдХреЗ рдХреЗрдВрджреНрд░ рдореЗрдВ рд╣реИ, рдЕрдиреНрдпрдерд╛, рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рджреМрд░рд╛рди, рдЫрд╡рд┐ рдХрд╛ рдЪрдпрдирд┐рдд рднрд╛рдЧ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓рддреА рд╣реИред

рдШрдЯрдХ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ


рдШрдЯрдХ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ:
 export default { components: { Preview }, data () { return { image: null, imageReady: false, imageRect: {}, //   areaRect: {}, //   minZoom: 1, //   maxZoom: 1, //   //   transform: { center: { x: 0, y: 0, }, zoom: 1, rotate: 0, flip: false, flop: false, x: 0, y: 0 } } }, computed: { matrix() { let scaleX = this.transform.flop ? -this.transform.zoom : this.transform.zoom; let scaleY = this.transform.flip ? -this.transform.zoom : this.transform.zoom; let tx = this.transform.x; let ty = this.transform.y; const cos = Math.cos(this.transform.rotate * Math.PI / 180); const sin = Math.sin(this.transform.rotate * Math.PI / 180); let a = Math.round(cos)*scaleX; let b = Math.round(sin)*scaleX; let c = -Math.round(sin)*scaleY; let d = Math.round(cos)*scaleY; return { a, b, c, d, tx, ty }; } }, ... } 


ImageRect рдФрд░ areaRect рдХрд╛ рдорд╛рди рдкреВрд░реНрд╡рд╛рд╡рд▓реЛрдХрди рдШрдЯрдХ рджреНрд╡рд╛рд░рд╛ рд╣рдореЗрдВ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрд░рдорд╢рдГ imageLoaded рдФрд░ areaResized рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реБрдП, рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рд╕рдВрд░рдЪрдирд╛ рд╣реЛрддреА рд╣реИ:

 { size: { width: 100, height: 100 }, center: { x: 50, y: 50 } } 

рдХреЗрдВрджреНрд░ рдорд╛рдиреЛрдВ рдХреА рдЧрдгрдирд╛ рд╣рд░ рдмрд╛рд░ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ рдПрдХ рдмрд╛рд░ рд▓рд┐рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реЛрддрд╛ рд╣реИред

рдЧрдгрдирд╛ рдХреА рдЧрдИ рдореИрдЯреНрд░рд┐рдХреНрд╕ рд╕рдВрдкрддреНрддрд┐ рдкрд░рд┐рд╡рд░реНрддрди рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЗ рд╕рдорд╛рди рдЧреБрдгрд╛рдВрдХ рд╣реИред

рдкрд╣рд▓рд╛ рдХрд╛рдо рдЬрд┐рд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╡рд╣ рдЫрд╡рд┐ рдХреЛ рдлрд╕рд▓ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдПрдХ рдордирдорд╛рдирд╛ рдкрд╣рд▓реВ рдЕрдиреБрдкрд╛рдд рдХреЗ рд╕рд╛рде рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдирд╛ рд╣реИ, рдЬрдмрдХрд┐ рдЫрд╡рд┐ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ, рдХреЗрд╡рд▓ рдКрдкрд░ рдФрд░ рдиреАрдЪреЗ рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ, рдпрд╛ рдХреЗрд╡рд▓ (рдХреЗрд╡рд▓) рдмрд╛рдПрдБ рдФрд░ рджрд╛рдПрдБ рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдХрд┐рд╕реА рднреА рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд╕рд╛рде, рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрдирд╛рдП рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЬрд╝реВрдорд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕реАрдорд┐рдд рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо рдЫрд╡рд┐ рдХреЗ рдЙрдиреНрдореБрдЦреАрдХрд░рдг рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдкрд╣рд▓реВ рдЕрдиреБрдкрд╛рдд рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВрдЧреЗред

рдШрдЯрдХ рд╡рд┐рдзрд┐рдпрд╛рдБ:
  _setMinZoom(){ let rotate = this.matrix.c !== 0; let horizontal = this.imageRect.size.height < this.imageRect.size.width; let areaSize = (horizontal && !rotate || !horizontal && rotate) ? this.areaRect.size.width : this.areaRect.size.height; let imageSize = horizontal ? this.imageRect.size.width : this.imageRect.size.height; this.minZoom = areaSize/imageSize; if(this.transform.zoom < this.minZoom) this.transform.zoom = this.minZoom; }, _setMaxZoom(){ this.maxZoom = this.areaRect.size.width/config.image.minResolution; if(this.transform.zoom > this.maxZoom) this.transform.zoom = this.maxZoom; }, 


рдЕрдм рд╣рдо рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВред рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреНрд░рддрд┐рдмрд┐рдВрдмреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЫрд╡рд┐ рдХреЗ рджреГрд╢реНрдп рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред

рдШрдЯрдХ рд╡рд┐рдзрд┐рдпрд╛рдБ:
 flipX(){ this.matrix.b == 0 && this.matrix.c == 0 ? this.transform.flip = !this.transform.flip : this.transform.flop = !this.transform.flop; }, flipY(){ this.matrix.b == 0 && this.matrix.c == 0 ? this.transform.flop = !this.transform.flop : this.transform.flip = !this.transform.flip; }, 


рдЬрд╝реВрдорд┐рдВрдЧ, рд░реЛрдЯреЗрд╢рди рдФрд░ рд╡рд┐рд╕реНрдерд╛рдкрди рдХреЗ рд░реВрдкрд╛рдВрддрд░рдг рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдо-рдореВрд▓ рд╕рдорд╛рдпреЛрдЬрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рдШрдЯрдХ рд╡рд┐рдзрд┐рдпрд╛рдБ:
 onZoomEnd(){ this._translate(); }, rotatePlus(){ this.transform.rotate += 90; this._setMinZoom(); this._translate(); }, rotateMinus(){ this.transform.rotate -= 90; this._setMinZoom(); this._translate(); }, imageMoved(translate){ this._translate(); }, 


рдпрд╣ _translate рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рд╕рднреА рд╕реВрдХреНрд╖реНрдорддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рджреЛ рд╕рдВрджрд░реНрдн рдкреНрд░рдгрд╛рд▓реА рд╢реБрд░реВ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред рдкрд╣рд▓рд╛, рдЪрд▓реЛ рдЗрд╕реЗ рд╢реВрдиреНрдп рдХрд╣рддреЗ рд╣реИрдВ, рдЫрд╡рд┐ рдХреЗ рдКрдкрд░реА рдмрд╛рдПрдВ рдХреЛрдиреЗ рдореЗрдВ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдЬрдм рд╣рдо рдкрд░рд┐рд╡рд░реНрддрди рдореИрдЯреНрд░рд┐рдХреНрд╕ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЛ рдЧреБрдгрд╛ рдХрд░рддреЗ рд╣реИрдВ, рд╣рдо рдПрдХ рдЕрдиреНрдп рд╕рдордиреНрд╡рдп рдкреНрд░рдгрд╛рд▓реА рдореЗрдВ рдЬрд╛рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рд╕реНрдерд╛рдиреАрдп рдХрд╣рддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рд╡реНрдпреБрддреНрдХреНрд░рдо рдкрд░рд┐рд╡рд░реНрддрди рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЛ рдЦреЛрдЬрдХрд░ рд╕реНрдерд╛рдиреАрдп рд╕реЗ рд╢реВрдиреНрдп рдореЗрдВ рд╕рдВрдХреНрд░рдордг рдХреЛ рдЙрд▓рдЯ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рджреЛ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рд╢реВрдиреНрдп рд╕реЗ рд╕реНрдерд╛рдиреАрдп рд╕рд┐рд╕реНрдЯрдо рдкрд░ рдЬрд╛рдирд╛ рд╣реИ, рдЬрдм рд╣рдо css рдЯреНрд░рд╛рдВрд╕реНрдлрд╝реЙрд░реНрдо рдкреНрд░реЙрдкрд░реНрдЯреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╡рд╣реА рд░реВрдкрд╛рдВрддрд░рдг рдХрд░рддрд╛ рд╣реИред

 img { transform: matrix(a, b, c, d, tx, ty); } 

рджреВрд╕рд░рд╛ - рдЫрд╡рд┐ рдХреЗ рдореВрд▓ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдордиреНрд╡рд┐рдд рд░реВрдкрд╛рдВрддрд░ред

рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдХреЗ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд┐рдЦрдирд╛ рд╕рдмрд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред

рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдо рдХреНрд▓рд╛рд╕:
 class Transform { constructor(center, matrix){ this.init(center, matrix); } init(center, matrix){ if(center) this.center = Object.assign({},center); if(matrix) this.matrix = Object.assign({},matrix); } getOrigins(current){ //     let tr = {x: current.x - this.center.x, y: current.y - this.center.y}; //         const det = 1/(this.matrix.a*this.matrix.d - this.matrix.c*this.matrix.b); const x = ( this.matrix.d*(tr.x - this.matrix.tx) - this.matrix.c*(tr.y - this.matrix.ty) ) * det + this.center.x; const y = (-this.matrix.b*(tr.x - this.matrix.tx) + this.matrix.a*(tr.y - this.matrix.ty) ) * det + this.center.y; return {x, y}; } translate(current){ //     const origin = {x: current.x - this.center.x, y: current.y - this.center.y}; //        let x = this.matrix.a*origin.x + this.matrix.c*origin.y + this.matrix.tx + this.center.x; let y = this.matrix.b*origin.x + this.matrix.d*origin.y + this.matrix.ty + this.center.y; return {x, y}; } } 


рд╡рд┐рд╕реНрддреГрдд рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде _Translate рд╡рд┐рдзрд┐:
 _translate(checkAlign = true){ const tr = new Transform(this.transform.center, this.matrix); // , ,  ,       const newCenter = tr.getOrigins(this.areaRect.center); this.transform.center = newCenter; //      this.transform.x = this.areaRect.center.x - newCenter.x; this.transform.y = this.areaRect.center.y - newCenter.y; //   tr.init(this.transform.center, this.matrix); //        ,      let x0y0 = tr.translate({x: 0, y: 0}); let x1y1 = tr.translate({x: this.imageRect.size.width, y: this.imageRect.size.height}); //  (  )       let result = { left: x1y1.x - x0y0.x > 0 ? x0y0.x : x1y1.x, top: x1y1.y - x0y0.y > 0 ? x0y0.y : x1y1.y, width: Math.abs(x1y1.x - x0y0.x), height: Math.abs(x1y1.y - x0y0.y) }; //       ,   "" let rightOffset = this.areaRect.size.width - (result.left + result.width); let bottomOffset = this.areaRect.size.height - (result.top + result.height); let alignedCenter; //   if(this.areaRect.size.width - result.width > 1){ //align center X alignedCenter = tr.getOrigins({x: result.left + result.width/2, y: this.areaRect.center.y}); }else{ //align left if(result.left > 0){ alignedCenter = tr.getOrigins({x: result.left + this.areaRect.center.x, y: this.areaRect.center.y}); //align right }else if(rightOffset > 0){ alignedCenter = tr.getOrigins({x: this.areaRect.center.x - rightOffset, y: this.areaRect.center.y}); } } if(alignedCenter){ this.transform.center = alignedCenter; this.transform.x = this.areaRect.center.x - alignedCenter.x; this.transform.y = this.areaRect.center.y - alignedCenter.y; tr.init(this.transform.center, this.matrix); } //   if(this.areaRect.size.height - result.height > 1){ //align center Y alignedCenter = tr.getOrigins({x: this.areaRect.center.x, y: result.top + result.height/2}); }else{ //align top if(result.top > 0){ alignedCenter = tr.getOrigins({x: this.areaRect.center.x, y: result.top + this.areaRect.center.y}); //align bottom }else if(bottomOffset > 0){ alignedCenter = tr.getOrigins({x: this.areaRect.center.x, y: this.areaRect.center.y - bottomOffset}); } } if(alignedCenter){ this.transform.center = alignedCenter; this.transform.x = this.areaRect.center.x - alignedCenter.x; this.transform.y = this.areaRect.center.y - alignedCenter.y; tr.init(this.transform.center, this.matrix); } }, 


рд╕рдВрд░реЗрдЦрдг рдлрд╕рд▓ рдХреЗ рдХрд┐рдирд╛рд░реЛрдВ рдкрд░ "рдЪрд┐рдкрдХреЗ" рдЫрд╡рд┐ рдХрд╛ рдкреНрд░рднрд╛рд╡ рдкреИрджрд╛ рдХрд░рддрд╛ рд╣реИ, рдЦрд╛рд▓реА рдЦреЗрддреЛрдВ рд╕реЗ рдмрдЪрддрд╛ рд╣реИред

рдШрдЯрдХ рдХрд╛ рдкреВрд░реНрд╡рд╛рд╡рд▓реЛрдХрди рдХрд░реЗрдВ


рдЗрд╕ рдШрдЯрдХ рдХрд╛ рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдЫрд╡рд┐ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рд╣реИ, рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реИ рдФрд░ рдЫрд╡рд┐ рдкрд░ рд▓рдЧрд╛рдП рдЧрдП рдорд╛рдЙрд╕ рдмрдЯрди рдХреЗ рдЖрдВрджреЛрд▓рди рдХрд╛ рдЬрд╡рд╛рдм рджреЗрдирд╛ рд╣реИред рдСрдлрд╕реЗрдЯ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВред x рдФрд░ transform.y , рдЖрдВрджреЛрд▓рди рдХреЗ рдЕрдВрдд рдореЗрдВ рд╣рдо рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдП рдЧрдП рдИрд╡реЗрдВрдЯ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ, рдПрдбрд┐рдЯ рдШрдЯрдХ рдХреЛ рдмрддрд╛рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗрдВрджреНрд░ рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдлрд┐рд░ рд╕реЗ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдФрд░ рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдо.x рдФрд░ рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдо рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдШрдЯрдХ рдШрдЯрдХ рдХрд╛ рдкреВрд░реНрд╡рд╛рд╡рд▓реЛрдХрди рдХрд░реЗрдВ:
<div ref = "рдХреНрд╖реЗрддреНрд░" рд╡рд░реНрдЧ = "рд╕рдВрдкрд╛рджрди-рдХреНрд╖реЗрддреНрд░"
@ mousedown = "onMoveStart"
@ рдЯрдЪрд╕реНрдЯрд╛рд░реНрдЯ = "рдСрдирдореЛрд╕реНрдЯрд╕реНрдЯрд╛рд░реНрдЯ"
рдорд╛рдЙрд╕рдЕрдк = "рдСрдирдореЛрд╡ рдПрдВрдб"
@ рд╕реНрдкрд░реНрд╢ = "onMoveEnd"
@ рдореВрд╕рдореЛрд╡ = "рдСрдирдореЛрд╡"
@ рдЯрдЪрдореЛрд╡ = "рдСрдирдореЛрд╡">
<img
v-if = "рдЫрд╡рд┐"
рд░реЗрдл = "рдЫрд╡рд┐"
рд▓реЛрдб = "рдЗрдореЗрдЬрд▓реЛрдбреЗрдб"
: src = "рдЫрд╡рд┐"
: рд╢реИрд▓реА = "{'рд░реВрдкрд╛рдВрддрд░": рд░реВрдкрд╛рдВрддрд░,' рдкрд░рд┐рд╡рд░реНрддрди-рдЙрддреНрдкрддреНрддрд┐ ': рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдордСрд░реНрдЧрд┐рди} ">

рд╕рдВрдкрд╛рджрдХ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдореБрдЦреНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рдмрдбрд╝реЗ рдХрд░реАрдиреЗ рд╕реЗ рдЕрд▓рдЧ рд╣реИ рдФрд░ рдпрд╣рд╛рдБ рдирд┐рд╣рд┐рдд рд╣реИ ред

рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рд╕рд╛рдордЧреНрд░реА рдЖрдкрдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧреАред рдзрдиреНрдпрд╡рд╛рдж!

Source: https://habr.com/ru/post/hi417697/


All Articles