■ はじめに
JavaScriptで、画像の切り取りについて調べていたら、 Cropper.js ってのを見つけて、思いのほかハマったので、メモ。
■ 公式サイト
https://fengyuanchen.github.io/cropperjs/GitHub
https://github.com/fengyuanchen/cropperjsサンプル
https://github.com/fengyuanchen/cropperjs/tree/master/examples
■ 設定
[[https://github.com/fengyuanchen/cropperjs#getting-started]]CDN
https://cdnjs.com/libraries/cropperjs<link rel="stylesheet" href="">https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.3/cropper.css"> <script src="">https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.3/cropper.js">
■ サンプル
【例1】Hello World
https://github.com/fengyuanchen/cropperjs/blob/master/examples/customize-preview.htmlhttps://codepen.io/blackjacques/pen/YZmvjw
<!DOCTYPE html> <html lang="jp"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <link rel="stylesheet" href="">https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.3/cropper.css"> <style> .container { max-width: 960px; margin: 20px auto; } img { max-width: 100%; } .row, .preview { overflow: hidden; } .col { float: left; } .col-1 { width: 50%; } .col-2 { width: 25%; } </style> <title>Demo</title> </head> <body> <div class="container"> <h1>Hello World for Cropper</h1> <div class="row"> <div class="col col-1"> <img id="image" src="https://raw.githubusercontent.com/fengyuanchen/cropperjs/master/docs/images/picture.jpg" alt="Picture"> </div> <div class="col col-2"> <div class="preview"></div> </div> </div> </div> <script src="">https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.3/cropper.js"> <script type="text/javascript"> function each(arr, callback) { var length = arr.length; var i; for (i = 0; i < length; i++) { callback.call(arr, arr[i], i, arr); } return arr; } window.addEventListener('DOMContentLoaded', function () { init(); }); function init() { var image = document.querySelector('#image'); var previews = document.querySelectorAll('.preview'); var cropper = new Cropper(image, { ready: function () { var clone = this.cloneNode(); clone.className = ''; clone.style.cssText = ( 'display: block;' + 'width: 100%;' + 'min-width: 0;' + 'min-height: 0;' + 'max-width: none;' + 'max-height: none;' ); each(previews, function (elem) { elem.appendChild(clone.cloneNode()); }); }, crop: function (event) { var data = event.detail; var cropper = this.cropper; var imageData = cropper.getImageData(); var previewAspectRatio = data.width / data.height; each(previews, function (elem) { var previewImage = elem.getElementsByTagName('img').item(0); var previewWidth = elem.offsetWidth; var previewHeight = previewWidth / previewAspectRatio; var imageScaledRatio = data.width / previewWidth; elem.style.height = previewHeight + 'px'; if (previewImage) { previewImage.style.width = imageData.naturalWidth / imageScaledRatio + 'px'; previewImage.style.height = imageData.naturalHeight / imageScaledRatio + 'px'; previewImage.style.marginLeft = -data.x / imageScaledRatio + 'px'; previewImage.style.marginTop = -data.y / imageScaledRatio + 'px'; } }); }, }); } </script> </body> </html>
【例2】回転などメソッド
<!DOCTYPE html> <html lang="jp"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <link rel="stylesheet" href="">https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.3/cropper.css"> <style> .container { max-width: 960px; margin: 20px auto; } img { max-width: 100%; } .row, .preview { overflow: hidden; } .col { float: left; } .col-1 { width: 50%; } .col-2 { width: 25%; } </style> <title>Demo</title> </head> <body> <div class="container"> <h1>Hello World for Cropper</h1> <div class="row"> <div class="col col-1"> <img id="image" src="https://raw.githubusercontent.com/fengyuanchen/cropperjs/master/docs/images/picture.jpg" alt="Picture"> </div> <div class="col col-2"> <div class="preview"></div> </div> </div> <button onclick="rotate()">rotate</button> <button onclick="resetCropper()">reset</button> <button onclick="clearCropper()">clear</button> <button onclick="enable()">enable</button> <button onclick="destroy()">destroy</button> </div> <script src="">https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.3/cropper.js"> <script type="text/javascript"> function each(arr, callback) { var length = arr.length; var i; for (i = 0; i < length; i++) { callback.call(arr, arr[i], i, arr); } return arr; } var cropper = null; window.addEventListener('DOMContentLoaded', function () { init(); }); function init() { var image = document.querySelector('#image'); var previews = document.querySelectorAll('.preview'); cropper = new Cropper(image, { ready: function () { var clone = this.cloneNode(); clone.className = ''; clone.style.cssText = ( 'display: block;' + 'width: 100%;' + 'min-width: 0;' + 'min-height: 0;' + 'max-width: none;' + 'max-height: none;' ); each(previews, function (elem) { elem.appendChild(clone.cloneNode()); }); }, crop: function (event) { var data = event.detail; var cropper = this.cropper; var imageData = cropper.getImageData(); var previewAspectRatio = data.width / data.height; each(previews, function (elem) { var previewImage = elem.getElementsByTagName('img').item(0); var previewWidth = elem.offsetWidth; var previewHeight = previewWidth / previewAspectRatio; var imageScaledRatio = data.width / previewWidth; elem.style.height = previewHeight + 'px'; if (previewImage) { previewImage.style.width = imageData.naturalWidth / imageScaledRatio + 'px'; previewImage.style.height = imageData.naturalHeight / imageScaledRatio + 'px'; previewImage.style.marginLeft = -data.x / imageScaledRatio + 'px'; previewImage.style.marginTop = -data.y / imageScaledRatio + 'px'; } }); }, }); } function rotate() { if (cropper) { cropper.rotate(45); } } function resetCropper() { if (cropper) { cropper.reset(); } } function clearCropper() { if (cropper) { cropper.clear(); } } function enable() { if (!cropper) { init(); } cropper.enable(); } function destroy() { if (cropper) { cropper.destroy(); } cropper = null; } </script> </body> </html>