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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

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

Q&A

解決済

1回答

1890閲覧

【JavaScript】テキストにhoverしたとき、ぐにゃっとする動きを実装させたいです

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

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

1グッド

0クリップ

投稿2021/11/09 18:21

編集2021/11/10 03:01

前提・実現したいこと

【HTML,CSS,JavaScript】
テキストをhoverすると、下記のようなぐにゃぐにゃと動くデザインを実装したいです。
https://goworkship.com/magazine/text-effect-typography/#23
普段はデザインを担当しており、簡単なHTML,CSSの知識しかないため
上記ページのコードを丸々コピペしましたがうまくいかず困っています。

発生している問題・エラーメッセージ

html,css,JSのファイルを作り、cssとjsは読み込まれているようです。
htmlのコードは<body>の中に丸々コピペし、
cssとjsファイルもそのままコピペしました。

そして、こちらでご回答をいただき、head内に

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>

の3行も記載いたしました。

しかし、画面は真っ白で何も動かないようです。
devツールのconsoleには、

エラーメッセージ test.js:81 Uncaught TypeError: Cannot read properties of null (reading 'innerHTML') at App.start (test.js:81) at new App (test.js:50) at test.js:165

とありますが、調べてみても全く解決しませんでした。。
プログラム的なことは無知なため、非常識な質問の仕方をしていたら申し訳ありません。
勉強不足だとは思いますが、仕事で急遽私の方で実装が必要になってしまったため、こちらの場をお借りいたしました。

試したこと

以下、ソースコードを記載します。
HTML

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="style.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script> <script src="test.js"></script> </head> <body> <script id="fragmentShader" type="x-shader/x-fragment"> precision mediump float; uniform float time; uniform float mouseX; uniform float mouseY; uniform sampler2D texture; varying vec2 vUv; void main() { float d = -distance(vec2(mouseX,mouseY), gl_FragCoord.xy); float r = dot(gl_FragCoord.xy, vec2(0.005,0.005))/d; vec2 tex = vec2(vUv.x + r, vUv.y + r); gl_FragColor = vec4(texture2D(texture, tex).rgb, 1.0); } </script> <script id="vertexShader" type="x-shader/x-vertex"> precision mediump float; varying vec2 vUv; uniform float time; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } </script> <div class="stage"></div> <canvas class="noise-canvas"></canvas> </body> </html>

css

.noise-canvas{ position: absolute; top: 0; left: 0; bottom: 0; right: 0; width: 100%; height: 100%; opacity: 0.3; z-index: 2; }

js

// Copyright (c) 2021 by Corentin (https://codepen.io/corentinfardeau/pen/VmZBpv) // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict' console.clear(); const APP_CONFIG = { debug: false, gridDebugSize: { x: 10, y: 10 }, fontSize: 600, axisHelperSize: 10 } class App { constructor(){ _.bindAll(this, 'animate', 'onResize', 'onMouseMove'); this.time = 0; this.planeHeight = 50; this.ratio = window.innerWidth / window.innerHeight; this.planeWidth = this.planeHeight*this.ratio; //SET-UP CAMERA this.cameraOpts = { aspect: window.innerWidth / window.innerHeight, near: 0.1, far : 10000, z: this.planeHeight } let fov = 2 * Math.atan( this.planeHeight / ( 2 * this.cameraOpts.z ) ) * ( 180 / Math.PI ); this.camera = new THREE.PerspectiveCamera(fov, this.cameraOpts.aspect, this.cameraOpts.near, this.cameraOpts.far); this.camera.position.z = this.cameraOpts.z; //SET-UP STAGE this.stage = new THREE.Scene(); this.stage.add(this.camera); //SET-UP RENDERER this.renderer = new THREE.WebGLRenderer({ antialias: true}); this.renderer.setSize(window.innerWidth, window.innerHeight); this.start(); } start(){ if (APP_CONFIG.debug){ this.debug(); } let texture = new THREE.Texture(this.createCanvas("Interactive Art Director")); texture.needsUpdate = true; let planeGeometry = new THREE.PlaneGeometry(this.planeWidth, this.planeHeight, 0, 0); this.uniforms = { texture: { type: 't', value: texture }, time: { type: "f", value: this.time }, mouseX: { type: "f", value: 0 }, mouseY: { type: "f", value: 0 } } var vertShader = document.getElementById('vertexShader').innerHTML; var fragShader = document.getElementById('fragmentShader').innerHTML; let planeMaterial = new THREE.ShaderMaterial({ uniforms: this.uniforms, vertexShader: vertShader, fragmentShader: fragShader, wireframe : false, wireframeLinewidth : 2, transparent : true }); this.plane = new THREE.Mesh(planeGeometry, planeMaterial); this.stage.add(this.plane); let container = document.querySelector('.stage'); container.appendChild(this.renderer.domElement); TweenMax.ticker.addEventListener('tick', this.animate); //ADD EVENTS LISTENER this.listen(); } createCanvas(text){ this.canvas = document.createElement( 'canvas' ); this.canvas.height = 4096; this.canvas.width = this.canvas.height*this.ratio; let context = this.canvas.getContext( '2d' ); context.beginPath(); context.rect(0, 0, this.canvas.width, this.canvas.height); context.fillStyle = '#202020'; context.fill(); context.closePath(); context.beginPath(); context.font = 'Bold '+ APP_CONFIG.fontSize +'px Avenir'; context.fillStyle = '#262626'; let width = context.measureText(text).width; context.fillText(text, this.canvas.width/2 - width/2, this.canvas.height/2); context.fill(); return this.canvas; } debug(){ let gridHelper = new THREE.GridHelper( APP_CONFIG.gridDebugSize.x, APP_CONFIG.gridDebugSize.y ); this.stage.add( gridHelper ); let axisHelper = new THREE.AxisHelper( APP_CONFIG.axisHelperSize ); this.stage.add( axisHelper ); } listen(){ let lazyLayout = _.debounce(this.onResize, 300); window.addEventListener('resize', lazyLayout); window.addEventListener('mousemove', this.onMouseMove); } onResize(e){ this.renderer.setSize(window.innerWidth, window.innerHeight); this.camera.updateProjectionMatrix(); } onMouseMove(e){ this.mousePos = { x: e.clientX, y: e.clientY } } animate(){ if(this.mousePos){ this.uniforms.mouseX.value = this.mousePos.x; this.uniforms.mouseY.value = window.innerHeight - this.mousePos.y; } this.renderer.render(this.stage, this.camera); this.uniforms.time.value += 0.1; } } new App();

また、HTMLのエディタ画面では、コードが普段はすべてカラーのはずが一部白文字になっているため、正しく読み込まれていないのは分かりました。
イメージ説明

何かヒントや解決方法ご存知の方、いらっしゃらないでしょうか?
また、参考サイトのコードではなく、他のやりやすい実装方法があればご教授いただけますと幸いです。

退会済みユーザー👍を押しています

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

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

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

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

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

m.ts10806

2021/11/09 19:45

まず現在のご自身のコードを提示してください。
hatena19

2021/11/09 19:59

> cssとjsファイルもそのままコピペしました。 リンク先のコードは、SCSSとBabelですが、素のCSSとJSにコンパイルしてますか。
退会済みユーザー

退会済みユーザー

2021/11/10 03:08

m.ts10806さま 失礼いたしました。ソースコード記載いたしました。 hatena19さま ご回答ありがとうございます。 SCSSとBabelでは、特有の構文は利用されていなく、コンパイルの必要はないとのことでした。 何卒よろしくお願いいたします。
guest

回答1

0

ベストアンサー

本文

test.js:18 Uncaught ReferenceError: _ is not defined

と書かれていますが、これ(_)はLodashまたはUNDERSCORE.JSで用いられているものです。

リンク先のcodepenにあるサンプルの設定を確認したところ、CDNに存在する3つの外部スクリプトに依存していました。これはSettings→JS→Add External Scripts/Pensで確認できます。

3つのスクリプトは以下の通りです

また、ソースコードを斜め読みしたところ、追記修正依頼に書かれているようなSCSS/Babel特有の構文は利用されていませんでした。よって、素のCSS/JSへのトランスパイルは必要ありません。(必要ないならどうしてリンク先のpenでは言語の設定がSCSS/Babelになっているのか、うろ覚えではありますがおそらく昔、codepenの言語のデフォルトの設定がSCSS/Babelだったからだと思います)

以上をまとめると、このサンプルを別のサイトで動作させるためには上記3つの外部スクリプトを追加するだけでいいはずです。

そのためには、例えばヘッダーの中に以下の形でスクリプトを埋め込みましょう。

html

1<head> 2 <!-- ...中略... --> 3 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script> 4 <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> 5 <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script> 6 <!-- ⇅あなたのスクリプトの**上**に追加してください --> 7 <script src="/test.js"></script> 8 <!-- ...中略... --> 9</head>

簡単なQA

Lodash, UNDERSCORE.JSとは?

汎用性の高い関数を提供してくれるライブラリです。両方とも利用自由、出典必要、無保証のMITライセンスの元提供されています。

CDNとは?

コンテンツデリバリーネットワークの頭文字を取ったものです。例えば多数のWebページで利用されているファイルを沢山のサーバーに分散させることで、負担の軽減を狙う目的などで利用されます。

SCSS/Babelとは?

CSS(SCSS)またはJavaScript(Babel)を拡張する仕組み、あるいはスーパーセットです。CSSなら関数、JavaScriptならJSXなど、本来の言語ではサポートされていない構文を解釈し、トランスコンパイル、または短くトランスパイルと呼ばれる手法でブラウザが実行できるCSS/JavaScript形式に変換してくれます。

補足

他人のソースコードを取り込む際は必ずライセンスを確認しましょう。CDNで提供されているものには多くの場合、デフォルトの状態でライセンスの情報が埋め込まれていますが、そうでなければライセンス文をしっかりと参照してソースコード内のコメントなどに貼り付けると良いでしょう。

例えばcodepen上のソースコードに係るライセンスについてはページ下部、Commentsのボタンを押すことで確認できます。サンプルとして提示していただいたpenにはCopyright (c) 2021 by ...と、MITライセンスに当たるライセンス文があります。利用する際はこれをtest.jsの上部にコメントとして追加しましょう。

投稿2021/11/09 22:21

編集2021/11/09 22:23
itepechi

総合スコア248

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

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

退会済みユーザー

退会済みユーザー

2021/11/10 03:05

ありがとうございます。こんなに丁寧なご回答を頂けるとは思いませんでした。 早速CDNのコードを記載してみたのですがやはりエラーが出てしまったようです。。 質問修正し、ソースコード、エラーコードを追加しましたので、もしお手すきでしたら見ていただくことは可能でしょうか?
itepechi

2021/11/10 03:19

> Uncaught TypeError: Cannot read properties of null (reading 'innerHTML') innerHTMLを読もうとしたオブジェクトはnullですよ、という内容のエラーですね。Document.getElementById()はHTML要素が見つからなかった場合にnullを返すようになっています。紐解いていくと、'vertexShader'がHTML上に見つからなかったため、document.getElementById('vertexShader').innerHTMLがnull.innerHTMLとして解釈され、エラーが発生したことがわかりますね。 HTML内のscriptはデフォルトで、記載順に解釈して実行されるようになっています。今回はtest.jsがhead内に、実際のシェーダーがbody内に書いてあるため、test.js→シェーダーの順番で解釈しまい、正常な実行に失敗しています。head内のtest.jsをbody内のシェーダーよりも下に移動するか、body内のシェーダーをhead内のtest,jsより上に移動すれば解決すると思います。 シェーダーの文字が白くなっているのはシンタックスハイライト用のプラグインがVSCode内に存在しないためです。これなどはどうでしょうか↓ https://marketplace.visualstudio.com/items?itemName=raczzalan.webgl-glsl-editor
退会済みユーザー

退会済みユーザー

2021/11/10 03:47 編集

こんな素早く的確なご回答、、本当にありがとうございます。感動しました。 無事、参考サイトと同じものは表示することができました! ここからテキストのカラーやサイズ、背景削除等細かいところにチャレンジしてみたいと思います。その際はまた質問立ててしまうかもしれませんが、、 今回はこちらに頂いたご回答で締め切らせていただきます。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問