LoginSignup
30
22

More than 3 years have passed since last update.

Vue.jsとCodeSandboxでトリミング機能の実装

Last updated at Posted at 2019-09-24

0. はじめに

CodeSandboxとvue-cropperjsを使用してVue.jsで簡単なトリミング機能を作成しました。

demo.gif

トリミングの比率を入力することで、様々なサイズにトリミングをすることができます。

1. 実行環境

エディタ : CodeSandbox

CodeSandbox

  • https://codesandbox.io/
  • オンラインコードエディター
  • Vue.jsのフレームワークを簡単に使える
  • ライブラリやコンポーネントの追加も簡単に行える

2. vue-cropperjsとは

3. 準備

  1. CodeSandboxを開く
  2. 右上の Create Sandbox をクリック vue1.png
  3. Vueのアイコンをクリック vue2.png
  4. Vueのプロジェクトが出てくるので、左側のDependenciesの中の Add Dependecy をクリック vue3.png
  5. 検索ボックスで vue-cropperjs を検索 vue4.png
  6. 1番上に出てきたものをクリック vue5.png
  7. Vue.jsのプロジェクトの立ち上げとvue-cropperjsのインストールが終了

4. プロジェクト作成

  1. 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>

5. デモページ

参考

30
22
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
22