質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

Vuetify.js

Vuetify.jsは、マテリアルデザインを基本とするVue.jsのCSSフレームワークです。多くのマテリアルデザインのコンポーネントを提供しており、あらゆるアプリケーションに対応可能。vue-cli用テンプレートがあり、簡単にページを作成できます。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

0回答

1155閲覧

Vuetify+アップロードボタンを組み合わせたら、アップロードボタンが異常に大きくなった。

toshihirokato

総合スコア20

Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

Vuetify.js

Vuetify.jsは、マテリアルデザインを基本とするVue.jsのCSSフレームワークです。多くのマテリアルデザインのコンポーネントを提供しており、あらゆるアプリケーションに対応可能。vue-cli用テンプレートがあり、簡単にページを作成できます。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2020/01/28 06:43

前提・実現したいこと

現在、Vuetifyのヘッダーとアップロードボタンを組み合わせて、簡単な画像表示アプリを作成しています。

そこで、以下のような現象が起こりました。

発生している問題

通常の大きさ
通常の大きさ

異常な大きさ
異常な大きさ

該当のソースコード

upload

1<template> 2 <div class="resize-img"> 3 <!-- 画像選択 --> 4 <div v-show="!resizedImg" class="resize-img__post"> 5 <!-- 要素の繰り返し --> 6 <label for="file" class="resize-img__post__label"> 7 <input 8 id="file" 9 ref="fileInput" 10 type="file" 11 @change="uploadImg" 12 > 13 </label> 14 </div> 15 <!-- プレビュー (画像を選択する画面) --> 16 <div v-show="resizedImg" class="resize-img__preview"> 17 <canvas ref="canvas" class="resize-img__preview__canvas" /> 18 <!-- 画像の削除 --> 19 <div class="resize-img__preview__circle" @click="clearUploadImg"> 20 <span class="resize-img__preview__circle__close-icon">×</span> 21 </div> 22 </div> 23 </div> 24</template> 25 26<script> 27export default { 28 data () { 29 return { 30 resizedImg: null 31 } 32 }, 33 destroyed () { 34 this.clearUploadImg() 35 }, 36 methods: { 37 // e は event の e 38 uploadImg (e) { 39 // e.target はイベントデリゲーションの実装 40 const file = e.target.files[0] 41 const reader = new FileReader() 42 reader.onload = (e) => { 43 this.generateImgUrl(e.target.result) 44 } 45 reader.readAsDataURL(file) 46 }, 47 generateImgUrl (file) { 48 const image = new Image() 49 image.crossOrigin = 'Anonymous' 50 51 image.onload = (e) => { 52 const resizedBase64 = this.makeResizeImg(image) 53 // リサイズ済みのBase64をblobに変換 54 const resizedBlob = this.base64ToBlob(resizedBase64) 55 // urlを生成してプレビュー表示できるようにする 56 const resizedImg = window.URL.createObjectURL(resizedBlob) 57 this.resizedImg = resizedImg 58 } 59 image.src = file 60 }, 61 makeResizeImg (image) { 62 const canvas = this.$refs.canvas 63 const ctx = canvas.getContext('2d') // 2Dコンテキスト 64 // 縦横で長い方の最大値を 140とする 65 const MAX_SIZE = 140 66 67 // MAX_SIZEよりも小さい場合、MAX_SIZE = 140 に固定 68 if (image.width < MAX_SIZE || image.height < MAX_SIZE) { 69 image.width = MAX_SIZE 70 image.height = MAX_SIZE 71 canvas.width = image.width 72 canvas.height = image.height 73 ctx.drawImage(image, 0, 0) 74 return canvas.toDataURL('image/jpeg') 75 } 76 77 let dstWidth 78 let dstHeight 79 // 縦横比の計算 80 if (image.width > image.height) { 81 dstWidth = dstHeight = MAX_SIZE 82 // dstHeight = (image.height * MAX_SIZE) / image.width 83 } else { 84 dstWidth = dstHeight = MAX_SIZE 85 // dstWidth = (image.width * MAX_SIZE) / image.height 86 } 87 canvas.width = dstWidth 88 canvas.height = dstHeight 89 // リサイズ 90 ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, dstWidth, dstHeight) 91 92 // data_url形式に変換したものを返す 93 return canvas.toDataURL('image/jpeg') 94 }, 95 clearUploadImg () { 96 this.resizedImg = null 97 if (this.$refs.fileInput && this.$refs.fileInput.value !== undefined) { 98 this.$refs.fileInput.value = '' 99 } 100 }, 101 base64ToBlob (base64) { 102 const bin = atob(base64.replace(/^.*,/, '')) 103 const buffer = new Uint8Array(bin.length) 104 for (let i = 0; i < bin.length; i++) { 105 buffer[i] = bin.charCodeAt(i) 106 } 107 return new Blob([buffer.buffer], { 108 type: 'image/png' 109 }) 110 } 111 } 112} 113</script> 114 115<style> 116.resize-img { 117 margin-left: 80px; 118} 119 120label input #file { 121 height: 20; 122 width: 40; 123} 124 125.resize-img__preview__circle__close-icon { 126 padding-left: 180px; 127 cursor: pointer; 128} 129</style> 130

header

1<template> 2 <v-app id="inspire"> 3 <v-navigation-drawer 4 v-model="drawer" 5 app 6 clipped 7 > 8 <v-list dense> 9 <v-list-item 10 v-for="item in items" 11 :key="item.text" 12 link 13 > 14 <v-list-item-action> 15 <v-icon>{{ item.icon }}</v-icon> 16 </v-list-item-action> 17 <v-list-item-content> 18 <v-list-item-title> 19 {{ item.text }} 20 </v-list-item-title> 21 </v-list-item-content> 22 </v-list-item> 23 <v-subheader class="mt-4 grey--text text--darken-1"> 24 SUBSCRIPTIONS 25 </v-subheader> 26 <v-list> 27 <v-list-item 28 v-for="item in items2" 29 :key="item.text" 30 link 31 > 32 <v-list-item-avatar> 33 <img 34 :src="`https://randomuser.me/api/portraits/men/${item.picture}.jpg`" 35 alt="" 36 > 37 </v-list-item-avatar> 38 <v-list-item-title v-text="item.text" /> 39 </v-list-item> 40 </v-list> 41 <v-list-item 42 class="mt-4" 43 link 44 > 45 <v-list-item-action> 46 <v-icon color="grey darken-1"> 47 mdi-plus-circle-outline 48 </v-icon> 49 </v-list-item-action> 50 <v-list-item-title class="grey--text text--darken-1"> 51 Browse Channels 52 </v-list-item-title> 53 </v-list-item> 54 <v-list-item link> 55 <v-list-item-action> 56 <v-icon color="grey darken-1"> 57 mdi-settings 58 </v-icon> 59 </v-list-item-action> 60 <v-list-item-title class="grey--text text--darken-1"> 61 Manage Subscriptions 62 </v-list-item-title> 63 </v-list-item> 64 </v-list> 65 </v-navigation-drawer> 66 67 <v-app-bar 68 app 69 clipped-left 70 color="rgba(255, 204, 0, 1)" 71 dense 72 > 73 <v-app-bar-nav-icon @click.stop="drawer = !drawer" /> 74 <v-toolbar-title class="mr-12 align-center"> 75 <span class="title">Sample</span> 76 </v-toolbar-title> 77 <v-spacer /> 78 <v-row 79 align="center" 80 style="max-width: 650px" 81 > 82 <v-text-field 83 :append-icon-cb="() => {}" 84 placeholder="Search..." 85 single-line 86 append-icon="search" 87 color="#1A237E" 88 hide-details 89 /> 90 </v-row> 91 </v-app-bar> 92 93 <v-content> 94 <v-container class="fill-height"> 95 <v-row 96 justify="center" 97 align="center" 98 /> 99 </v-container> 100 </v-content> 101 </v-app> 102</template> 103 104<script> 105export default { 106 props: { 107 // eslint-disable-next-line 108 source: String 109 }, 110 data: () => ({ 111 drawer: null, 112 items: [ 113 { icon: 'mdi-trending-up', text: 'Most Popular' }, 114 { icon: 'mdi-youtube-subscription', text: 'Subscriptions' }, 115 { icon: 'mdi-history', text: 'History' }, 116 { icon: 'mdi-playlist-check', text: 'Playlists' }, 117 { icon: 'mdi-clock', text: 'Watch Later' } 118 ], 119 items2: [ 120 { picture: 28, text: 'Joseph' }, 121 { picture: 38, text: 'Apple' }, 122 { picture: 48, text: 'Xbox Ahoy' }, 123 { picture: 58, text: 'Nokia' }, 124 { picture: 78, text: 'MKBHD' } 125 ] 126 }), 127 created () { 128 this.$vuetify.theme.dark = false 129 } 130} 131</script> 132 133<style> 134.title { 135 color: #1A237E; 136} 137</style> 138

試したこと

検証にかけて直接uploadボタンのCSSを直接編集したが、予期せぬ挙動となりました。

具体的には、全体の大きさを変更するために

style="width: 100px; height: 100px;"

こちらを指定したところ、 ↓↓のようになった。

イメージ説明

勝手な推測

Vuetifyは、CSSが崩れないようにv-appタグで囲う必要があるが、逆にそのv-appタグのせいで
他の純粋なHTMLの要素が崩れているかも知れません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問