0. はじめに
CodeSandboxとvue-cropperjsを使用してVue.jsで簡単なトリミング機能を作成しました。
トリミングの比率を入力することで、様々なサイズにトリミングをすることができます。
- デモページはこちら
1. 実行環境
エディタ : CodeSandbox
CodeSandbox
- https://codesandbox.io/
- オンラインコードエディター
- Vue.jsのフレームワークを簡単に使える
- ライブラリやコンポーネントの追加も簡単に行える
2. vue-cropperjsとは
- https://github.com/Agontuk/vue-cropperjs
- 公式デモページ
- Cropper.jsというJavaScriptの画像トリミング用のライブラリをラッパーして、Vue.js用にコンポーネントしたもの
3. 準備
- CodeSandboxを開く
- 右上の Create Sandbox をクリック





4. プロジェクト作成
- Cropper.vueの作成
- src/components の中にある HelloWorld.vue の名前を Cropper.vue に変更
- 比率入力フォーム
<template>
<h3>比率を入力</h3>
横:
<input v-model="yoko">
<br>
縦:
<input v-model="tate">
<br>
</template>
<script>
export default {
data() {
return {
yoko: 2, //横の初期値2
tate: 1, //縦の初期値1
};
}
}
</script>
- vue-cropperの実装
<template>
<h3>画像を選択</h3>
<input type="file" name="image" accept="image/*" @change="setImage">
<br>
<div
v-if="imgSrc != ''"
style="width: 200px; height:200px; border: 1px solid gray; display: inline-block;"
>
<vue-cropper
ref="cropper"
:guides="true"
:view-mode="2"
drag-mode="crop"
:auto-crop-area="0.5"
:min-container-width="200"
:min-container-height="200"
:background="true"
:rotatable="false"
:src="imgSrc"
:img-style="{ 'width': '200px', 'height': '200px' }"
:aspect-ratio="yoko / tate"
>
<!-- :img-styleで読み込んだ画像の大きさを指定
:aspect-ratioで比率を指定 -->
</vue-cropper>
<br>
<button @click="cropImage" v-if="imgSrc != ''">トリミングする</button>
</template>
<script>
import VueCropper from "vue-cropperjs"; //ダウンロードしたコンポーネントのインポート
import "cropperjs/dist/cropper.css";
export default {
components: {
VueCropper
},
data() {
return {
imgSrc: "", //トリミング前の画像のソース
filename: "" //画像の名前
};
},
methods: {
setImage(e) {
const file = e.target.files[0];
this.filename = file.name;
if (!file.type.includes("image/")) { //選択されたものが画像ではなかった場合の処理
alert("Please select an image file");
return;
}
if (typeof FileReader === "function") {
const reader = new FileReader();
reader.onload = event => {
this.imgSrc = event.target.result;
this.$refs.cropper.replace(event.target.result);
};
reader.readAsDataURL(file);
} else {
alert("Sorry, FileReader API not supported");
}
}
}
};
</script>
- トリミングされた画像の表示
<template>
<div v-if="cropImg != ''">
<img
:src="cropImg"
style="width: yoko; height: tate; border: 1px solid gray;"
alt="Cropped Image"
>
</template>
<script>
export default {
data() {
return {
cropImg: "" //トリミング後の画像のソース
};
},
methods: {
cropImage() {
this.cropImg = this.$refs.cropper.getCroppedCanvas().toDataURL();
}
}
};
</script>
- ダウンロード
<template>
<p>
<a :href="cropImg" :download="filename">画像を保存</a>
</p>
</template>
Cropper.vue
Cropper.vue
<template>
<div style="font-size: 14px; text-align: center; width: 100vw;">
<h2>画像のトリミング</h2>
<hr>
<h3>比率を入力</h3>
横:
<input v-model="yoko">
<br>
縦:
<input v-model="tate">
<br>
<h3>画像を選択</h3>
<input type="file" name="image" accept="image/*" @change="setImage">
<br>
<div
v-if="imgSrc != ''"
style="width: 200px; height:200px; border: 1px solid gray; display: inline-block;"
>
<vue-cropper
ref="cropper"
:guides="true"
:view-mode="2"
drag-mode="crop"
:auto-crop-area="0.5"
:min-container-width="200"
:min-container-height="200"
:background="true"
:rotatable="false"
:src="imgSrc"
:img-style="{ 'width': '200px', 'height': '200px' }"
:aspect-ratio="yoko / tate"
></vue-cropper>
<br>
<button @click="cropImage" v-if="imgSrc != ''">トリミングする</button>
</div>
<br>
<br>
<br>
<div v-if="cropImg != ''">
<img
:src="cropImg"
style="width: yoko; height: tate; border: 1px solid gray;"
alt="Cropped Image"
>
<p>
<a :href="cropImg" :download="filename">画像を保存</a>
</p>
<br>
</div>
</div>
</template>
<script>
import VueCropper from "vue-cropperjs";
import "cropperjs/dist/cropper.css";
export default {
components: {
VueCropper
},
data() {
return {
yoko: 2,
tate: 1,
imgSrc: "",
cropImg: "",
filename: ""
};
},
methods: {
setImage(e) {
const file = e.target.files[0];
this.filename = file.name;
if (!file.type.includes("image/")) {
alert("Please select an image file");
return;
}
if (typeof FileReader === "function") {
const reader = new FileReader();
reader.onload = event => {
this.imgSrc = event.target.result;
this.$refs.cropper.replace(event.target.result);
};
reader.readAsDataURL(file);
} else {
alert("Sorry, FileReader API not supported");
}
},
cropImage() {
this.cropImg = this.$refs.cropper.getCroppedCanvas().toDataURL();
}
}
};
</script>
<style scoped>
h2 {
font-size: 25px;
margin-top: 20px;
}
h3 {
font-size: 20px;
}
</style>
2. App.vueの編集
- ロゴのサイズ調整
<img width="25%" src="./assets/logo.png">
- Cropper.vueの読み込み
<template>
<div id='app'>
<Cropper />
</div>
</template>
<script>
import Cropper from "./components/Cropper";
export default {
name: "App",
components: {
Cropper
}
};
</script>
App.vue
App.vue
<template>
<div id="app">
<img width="25%" src="./assets/logo.png">
<Cropper/>
</div>
</template>
<script>
import Cropper from "./components/Cropper";
export default {
name: "App",
components: {
Cropper
}
};
</script>
<style>
# app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>