文字を立体で表示する(HTML/CSS/JS)
前書き
文字を立体で表示する方法を掲載しています。
目次
- cssで立体に見せる
- three.jsで文字を表示する
- 参考
cssで立体に見せる
下記ページを参考にしています。
text-shadowを重ねて立体に見せています。
【CSS】text-shadowを使ったテキストの装飾パターンを色々作ってみた
いろはに
ほへと
<p class="text">いろはに<br>ほへと</p>
.text{
color: #a675a5;
text-shadow:
1px 1px #845080,
2px 2px #845080,
3px 3px #845080,
4px 4px #845080,
5px 5px #845080,
6px 6px 4px #777;
}
three.jsで文字を表示する
下記ページを参考にしています。
フォントを準備する必要があります。
threejs examples #webgl_geometry_shapes
threejs examples #webgl_geometry_text_shapes
概要
- 日本語のフォント(TrueType形式)をjsonに変換
- そのフォントを読み込んで形を作る
- 立体にする
英語のフォント
今回利用したフォント、サイト
見本
<div class="wrap js-wrap-a">
<canvas class="canvas js-canvas"></canvas>
</div>
.wrap{
position: relative; padding: 50% 0 0; overflow: hidden;
}
.canvas{
position: absolute; top: 0; left: 0; width: 100%; height: 100%;
}
import * as THREE from './three_r127/build/three.module.js';
import { OrbitControls } from './three_r127/examples/jsm/controls/OrbitControls.js';
// サイズ------------------
const wrap = document.querySelector(".js-wrap-a");
let wrapWidth = wrap.clientWidth;
let wrapHeight = wrap.clientHeight;
// レンダラー------------------
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector(".js-canvas"),
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(wrapWidth, wrapHeight);
// シーン------------------
const scene = new THREE.Scene();
scene.background = new THREE.Color( 0xf5edf3 ); //背景色
// カメラ------------------
const camera = new THREE.PerspectiveCamera( 45, wrapWidth / wrapHeight );
camera.position.set( 0, 0, 600 );
// カメラコントローラーを作成
const controls = new OrbitControls( camera, renderer.domElement );
// 光源------------------
const hLight = new THREE.HemisphereLight(0xffffff, 1); // 半球光源
scene.add(hLight);
// フォント ------------------
const fontInit = e => {
// 共通
const message = "いろはに\n ほへと";
//塗りつぶす文字の形状
const shapesA = e.generateShapes( message, 100 );
//縁取りをする文字の形状( 穴の開いている部分のパスを追加する )
const shapesB = e.generateShapes( message, 100 );
const holeShapes = [];
for ( let i = 0; i < shapesB.length; i ++ ) {
const shape = shapesB[ i ];
if ( shape.holes && shape.holes.length > 0 ) {
for ( let j = 0; j < shape.holes.length; j ++ ) {
const hole = shape.holes[ j ];
holeShapes.push( hole );
}
}
}
shapesB.push.apply( shapesB, holeShapes );
//位置調整
const group = new THREE.Group();
const geometry00 = new THREE.ShapeGeometry( shapesA );
geometry00.computeBoundingBox();
const x = - 0.5 * ( geometry00.boundingBox.max.x + geometry00.boundingBox.min.x );
const y = - 0.5 * ( geometry00.boundingBox.max.y + geometry00.boundingBox.min.y );
group.position.x = x;
group.position.y = y;
scene.add( group );
// 01 塗りつぶしの文字(平面) ------------------
const material01 = new THREE.MeshBasicMaterial( {
color: 0x845080,
side: THREE.DoubleSide
});
const geometry01 = new THREE.ShapeGeometry( shapesA );
const text01 = new THREE.Mesh( geometry01, material01 );
text01.position.z = - 50;
group.add( text01 );
// 02 塗りつぶしの文字(立体) ------------------
const material02 = new THREE.MeshPhongMaterial( {
color: 0x845080,
side: THREE.DoubleSide
});
const extrudeSettings02 = {
depth: 25,
bevelThickness: 1,
};
const geometry02 = new THREE.ExtrudeGeometry( shapesA, extrudeSettings02 );
const text02 = new THREE.Mesh( geometry02, material02 ) ;
text02.position.z = -150;
group.add( text02 );
// 03 縁取りをする文字(実線) ------------------
const material03 = new THREE.LineBasicMaterial( {
color: 0x845080,
side: THREE.DoubleSide
});
const text03 = new THREE.Object3D();
for ( let i = 0; i < shapesB.length; i ++ ) {
const shape = shapesB[ i ];
const points = shape.getPoints();
const geometry03 = new THREE.BufferGeometry().setFromPoints( points );
const mesh = new THREE.Line( geometry03, material03 );
text03.add( mesh );
}
text03.position.z = 50;
group.add( text03 );
// 04 縁取りをする文字(点線) ------------------
const material04 = new THREE.PointsMaterial( {
color: 0x845080,
size: 5,
side: THREE.DoubleSide
});
const text04 = new THREE.Object3D();
for ( let i = 0; i < shapesB.length; i ++ ) {
const shape = shapesB[ i ];
const length = shape.getLength(); //曲線の長さ
const spacedPoints = shape.getSpacedPoints( length * 0.2 ); //点の間隔
const geometry04 = new THREE.BufferGeometry().setFromPoints( spacedPoints );
const mesh = new THREE.Points( geometry04, material04 );
text04.add( mesh );
}
text04.position.z = 150;
group.add( text04 );
}
// フォントの読み込み
const loader = new THREE.FontLoader();
loader.load( './three_r127/examples/fonts/font.typeface.json', fontInit);
//リサイズ------------------
const wrapResize = () =>{
wrapWidth = wrap.clientWidth;
wrapHeight = wrap.clientHeight;
renderer.setSize(wrapWidth, wrapHeight);
// camera.aspect = wrapWidth / wrapHeight;
// camera.updateProjectionMatrix();
}
//一定時間毎に処理------------------
let tick;
const switching = (e) => {
if( e[0].isIntersecting ){ //見えてる時
tick = () => {
wrapResize(); //リサイズ
renderer.render(scene, camera); //レンダリング
requestAnimationFrame( tick ); //繰り返し
}
requestAnimationFrame( tick );
}else{ //見えてない時
tick = () => {
cancelAnimationFrame( tick )
}
}
}
//見えているかどうか(Intersection Observer API)------------------
const createObserver = () => {
let observer;
const options = { root: null, rootMargin: "0%", threshold: 0 };
observer = new IntersectionObserver(switching, options); //コールバック関数とオプションを渡す
observer.observe(wrap); //要素の監視を開始
}
createObserver();
参考
【CSS】text-shadowを使ったテキストの装飾パターンを色々作ってみた
threejs examples #webgl_geometry_shapes
threejs examples #webgl_geometry_text_shapes
関連記事
マウスの位置に合わせて要素を動かす(HTML/CSS/JS)
この記事は役に立ちましたか?
送信中