Three.js+React实现3D文字悬浮效果

目录
  • 背景
  • 效果
  • 实现
    • 资源引入
    • DOM结构
    • 设置状态
    • 网格背景
    • 场景初始化
    • 创建材质
    • 创建文字模型
    • 创建几何体模型
    • 鼠标事件监听
    • 背景色切换
    • 后期渲染
    • 动画
    • 缩放适配
    • 双击全屏
  • 总结

背景

在 Three.js Journey 课程示例中,提供了一个使用 Three.js 内置方法实现的 3D 文字悬浮效果的例子,本文使用 React + Three.js 技术栈,参照示例实现类似的效果。本文中涉及到的知识点主要包括:CSS 网格背景、MeshNormalMaterial 法向材质、FontLoader 字体加载器、TextGeometry 文本缓冲几何体、TorusBufferGeometry 圆环缓冲几何体、ConeBufferGeometry 圆锥缓冲几何体、OctahedronBufferGeometry 八面缓冲几何体、Three.js 后期渲染、GlitchPass 通道、Element.requestFullscreenDocument.exitFullscreen 等。

效果

实现效果如 banner 图所示,页面主体由位于中心的文字网格模型以及四周的圆环面、圆锥以及八面体构成。随着鼠标在页面上移动或点击,模型也随之移动。页面右上角提供了2个按钮,可以切换页面背景色和切换故障风格后期特效。双击屏幕可以进入或退出全屏。

在线预览:https://3d-dragonir.vercel.app/#/floating

或 https://dragonir.github.io/3d/#/floating

已适配:

  • PC端
  • 移动端

实现

资源引入

首先引入开发所需要的模块资源,其中 FontLoader 用于加载字体文件,TextGeometry 用于创建 3D 字体网格,EffectComposerRenderPass 和 GlitchPass 用于后期特效渲染。

import * as THREE from "three";
import { FontLoader } from "three/examples/jsm/loaders/FontLoader";
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { GlitchPass } from 'three/examples/jsm/postprocessing/GlitchPass.js';

DOM结构

页面 DOM 结构非常简单,容器 #canvas 用于场景渲染,.color_pick 用于切换页面背景颜色,.pass_button 用于切换故障风格后期渲染。

<div className='floating_page' style={{ backgroundColor: this.state.backgroundColor }}>
  <div id="canvas"></div>
  <input className='color_pick' type="color" onChange={this.handleInputChange} value={this.state.backgroundColor} />
  <button className='pass_button' onClick={this.handleRenderChange}>特效<span className='highlight'>{this.state.renderGlithPass ? '开' : '关'}</span></button>
</div>

设置状态

backgroundColor 表示当前页面背景色, renderGlithPass 表示是否开启后期状态。自测发现在 iOS Safari 浏览器中,故障风格后期渲染会导致模型产生穿模问题,因此使用该参数控制手机端默认关闭后期效果、pc 端默认开启。

state = {
  backgroundColor: '#164CCA',
  renderGlithPass: !(window.navigator.userAgent.toLowerCase().indexOf('mobile') > 0)
}

网格背景

使用纯 CSS 属性 linear-gradient 实现网格背景来美化页面。

background-image: linear-gradient(rgba(3, 192, 60, .3) 1px, transparent 1px), linear-gradient(90deg, rgba(3, 192, 60, .3) 1px, transparent 1px);
background-size: 1em 1em;

场景初始化

初始化渲染容器、场景、摄像机,摄像机的位置可根据自身所需调整。render 开启 alpha 并设置 .setClearAlpha(0) 可将背景色设置为透明。

canvas = document.getElementById('canvas');
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio(Math.min(2, window.devicePixelRatio));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearAlpha(0);
canvas.appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, .1, 10000);
camera.position.set(-2 * 10000, 0, 780);

创建材质

本文中所有网格模型都将使用同一种材质 MeshNormalMaterial,应用它的特性,可以使网格模型产生彩色渐变。全局创建一次,后续开发不需要重复创建,有利于页面性能提升。

const material = new THREE.MeshNormalMaterial();

MeshNormalMaterial 法向材质

是一种把法向量映射到 RGB 颜色的材质,可以通过观察模型表面渐变颜色是否连续来检测模型表面是否平整

构造函数

MeshNormalMaterial(parameters : Object)

parameters:可选,用于定义材质外观的对象,具有一个或多个属性。

特殊属性

  • .normalMap[Texture]:用于创建法线贴图纹理,RGB 值会影响每个像素片段的曲面法线,并更改颜色照亮的方式。
  • .normalMapType[Integer]:法线贴图的类型,选项为 THREE.TangentSpaceNormalMap(默认)和 THREE.ObjectSpaceNormalMap
  • .normalScale[Vector2]:法线贴图对材质的影响程度。范围是 0-1,默认值是 Vector2 设置为 (1, 1)
  • .flatShading[Boolean]:定义材质是否使用平面着色进行渲染,默认值为 false
  • .morphNormals[Boolean]:定义是否使用 morphNormals。设置为 true 可将 morphNormal 属性从 geometry 传递到 shader。默认值为 false
  • .morphTargets[Boolean]:定义材质是否使用 morphTargets,默认值为 false

创建文字模型

使用 FontLoader 加载 fontface 字体 JSON 文件,并用 TextGeometry 创建文字几何体模型。

const loader = new FontLoader();
loader.load('./fonts/helvetiker_regular.typeface.json', font => {
  textMesh.geometry = new TextGeometry('@dragonir\nfantastic\nthree.js\nart work', {
    font: font,
    size: 100,
    height: 40,
    curveSegments: 12,
    bevelEnabled: true,
    bevelThickness: 30,
    bevelSize: 8,
    bevelOffset: 1,
    bevelSegments: 12
  });
  textMesh.material = material;
  scene.add(textMesh);
});

FontLoader 字体加载器

使用 JSON 格式中加载字体的一个类,返回 Font, 返回值是表示字体的 Shape 类型的数组,其内部使用 FileLoader 来加载文件。

构造函数

FontLoader(manager: LoadingManager)
  • manager:加载器所使用的 loadingManager,默认值为 THREE.DefaultLoadingManager

方法:

.load 从 URL 中进行加载,并将被加载的 texture 传递给 onLoad

  • .load(url: String, onLoad: Function, onProgress: Function, onError: Function): null
  • url:文件的URL或者路径,也可以为 Data URI
  • onLoad:加载完成时将调用。回调参数是将要被加载的 texture
  • onProgress:将在加载过程中进行调用。参数为 XMLHttpRequest 实例,包含 total 和 loaded 字节。
  • onError:加载错误时被调用。

.parse 以 JSON 格式进行解析,并返回一个 Font

  • .parse (json: Object ): Font
  • json:用于解析的 JSON 结构。

TextGeometry 文本几何体

用于将文本生成单一几何体的类,它是由一串给定的文本,以及由加载的 Font 字体和该几何体 ExtrudeGeometry 父类中的设置所组成的参数构造的。

构造函数

TextGeometry(text: String, parameters: Object)

text:将要显示的文本。

parameters

  • font[Font]THREE.Font 实例。
  • size[Float]:字体大小,默认值为 100
  • height[Float]:挤出文本的厚度,默认值为 50
  • curveSegments[Integer]:表示文本的曲线上点的数量,默认值为 12
  • bevelEnabled[Boolean]:是否开启斜角,默认为 false
  • bevelThickness[Float]:文本斜角的深度,默认值为 20
  • bevelSize[Float]:斜角与原始文本轮廓之间的延伸距离,默认值为 8
  • bevelSegments[Integer]:斜角的分段数,默认值为 3

可以使用facetype.js在线转换 Three.js 支持的字体。

创建几何体模型

使用其他 3种 内置几何体模型圆环、圆锥和八面体来装饰页面。装饰几何体的数量比较多,为了有效提升页面性能,需要注意以下两点:

  • 使用 THREE.Group 管理所有几何体。
  • 创建几何体时使用 BufferAttribute, 如使用ConeBufferGeometry而不是ConeGeometry,这样可以更有效地将数据传递到 GPU
// 批量创建模型方法
generateRandomMesh = (geometry, material, count) => {
  for (let i = 0; i < count; i++) {
    let mesh = new THREE.Mesh(geometry, material);
    let dist = farDist / 3;
    let distDouble = dist * 2;
    // 设置随机的位置和旋转角度
    mesh.position.x = Math.random() * distDouble - dist;
    mesh.position.y = Math.random() * distDouble - dist;
    mesh.position.z = Math.random() * distDouble - dist;
    mesh.rotation.x = Math.random() * 2 * Math.PI;
    mesh.rotation.y = Math.random() * 2 * Math.PI;
    mesh.rotation.z = Math.random() * 2 * Math.PI;
    // 手动控制何时重新计算3D变换以获得更好的性能
    mesh.matrixAutoUpdate = false;
    mesh.updateMatrix();
    group.add(mesh);
  }
}
// 创建100个八面体
const octahedronGeometry = new THREE.OctahedronBufferGeometry(80);
generateRandomMesh(octahedronGeometry, material, 100);
// 创建200个圆环面
const torusGeometry = new THREE.TorusBufferGeometry(40, 25, 16, 40);
generateRandomMesh(torusGeometry, material, 200);
// 创建100个圆锥
const coneGeometry = new THREE.ConeBufferGeometry(40, 80, 80);
generateRandomMesh(coneGeometry, material, 100);
scene.add(group);

TorusBufferGeometry 圆环缓冲几何体

用于生成圆环几何体的类。

构造函数

TorusBufferGeometry(radius: Float, tube: Float, radialSegments: Integer, tubularSegments: Integer, arc: Float)
  • radius:圆环的半径,从圆环的中心到管道横截面的中心,默认值是 1
  • tube:管道的半径,默认值为 0.4
  • radialSegments:圆环的分段数,默认值为 8
  • tubularSegments:管道的分段数,默认值为 6
  • arc:圆环的圆心角,单位是弧度,默认值为 Math.PI * 2

ConeBufferGeometry 圆锥缓冲几何体

用于生成圆锥几何体的类。

构造函数

ConeBufferGeometry(radius: Float, height: Float, radialSegments: Integer, heightSegments: Integer, openEnded: Boolean, thetaStart: Float, thetaLength: Float)
  • radius:圆锥底部的半径,默认值为 1
  • height:圆锥的高度,默认值为 1
  • radialSegments:圆锥侧面周围的分段数,默认为 8
  • heightSegments:圆锥侧面沿着其高度的分段数,默认值为 1
  • openEnded:指明该圆锥的底面是开放的还是封顶的。默认值为 false,即其底面默认是封顶的。
  • thetaStart:第一个分段的起始角度,默认为 0
  • thetaLength:圆锥底面圆扇区的中心角,通常被称为 θ。默认值是 2*PI,使其成为一个完整的圆锥。

OctahedronBufferGeometry 八面缓冲几何体

用于创建八面体的类。

构造函数

OctahedronBufferGeometry(radius: Float, detail: Integer)
  • radius:八面体的半径,默认值为 1
  • detail:默认值为 0,将这个值设为一个大于 0 的数将会为它增加一些顶点,使其不再是一个八面体。

鼠标事件监听

通过对鼠标移动坐标和模型坐标的相互转换来添加鼠标移动和触摸移动事件的监听方法。

const mouseFX = {
  windowHalfX: window.innerWidth / 2,
  windowHalfY: window.innerHeight / 2,
  coordinates: (coordX, coordY) => {
    mouseX = (coordX - mouseFX.windowHalfX) * 5;
    mouseY = (coordY - mouseFX.windowHalfY) * 5;
  },
  onMouseMove: e => { mouseFX.coordinates(e.clientX, e.clientY) },
  onTouchMove: e => { mouseFX.coordinates(e.changedTouches[0].clientX, e.changedTouches[0].clientY)}
};
document.addEventListener('mousemove', mouseFX.onMouseMove, false);
document.addEventListener('touchmove', mouseFX.onTouchMove, false);

背景色切换

使用一个 input[type='color'] 标签来实现背景色切换。

handleInputChange = e => {
  this.setState({ backgroundColor: e.target.value });
}

后期渲染

为了更具有冲击感的视觉效果,我添加了一个故障风格后期渲染特效,并使用一个按钮开关来控制开启和关闭该特效。

composer = new EffectComposer(renderer);
composer.addPass( new RenderPass(scene, camera));
glitchPass = new GlitchPass();
composer.addPass(glitchPass);
handleRenderChange = () => {
  this.setState({ renderGlithPass: !this.state.renderGlithPass });
}

后期渲染

Three.js 后期渲染处理,是通过叠加渲染通道达到预期视觉效果的过程。实现流程如下:

  • 创建效果组合器:效果组合器是各种处理通道的入口,使用 EffectComposer 对象创建一个效果组合器。
  • 添加通道:添加 RenderPass 通道 它将在指定的场景和相机的基础上渲染出一个新的场景。
  • 组合器更新:在动画循环中,调用效果组合器的 render 方法,通道生成效果将在场景中输出。

GlitchPass 故障风格通道

GlitchPass 通道产生模拟故障风格效果,它只有一个可选配置参数:

goWild 该属性接收一个布尔值,指定是否持续产生电磁风暴效果。

Three.js 提供了很多后期处理的通道,可以直接使用。同时提供了 ShaderPass 通道,它支持使用自定义 Shader,可以创建高级的自定义后期处理通道。

动画

在 requestAnimationFrame 中更新场景、相机、和后期渲染通道。

function animate() {
  requestAnimationFrame(animate);
  camera.position.x += (mouseX - camera.position.x) * 0.05;
  camera.position.y += (mouseY * -1 - camera.position.y) * 0.05;
  camera.lookAt(scene.position);
  // 给场景中的立方体网格和字体网格添加自转动画
  const t = Date.now() * 0.001;
  const rx = Math.sin(t * 0.7) * 0.5;
  const ry = Math.sin(t * 0.3) * 0.5;
  const rz = Math.sin(t * 0.2) * 0.5;
  group.rotation.x = rx;
  group.rotation.y = ry;
  group.rotation.z = rz;
  textMesh.rotation.x = rx;
  textMesh.rotation.y = ry;
  textMesh.rotation.z = rx;
  renderer.render(scene, camera);
  // 更新后期渲染通道
  composer.render();
}

缩放适配

renderer 和 composer 大小要同时调整。

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
  composer.setSize( window.innerWidth, window.innerHeight );
}, false);

双击全屏

监听页面鼠标双击 dblclick 事件,通过调用 requestFullscreen 和 exitFullscreen 进入或退出全屏状态。

window.addEventListener('dblclick', () => {
  let fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement;
  if (!fullscreenElement) {
    if (canvas.requestFullscreen) {
      canvas.requestFullscreen();
    } else if (canvas.webkitRequestFullscreen) {
      canvas.webkitRequestFullscreen();
    }
    console.log('进入全屏')
  } else {
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen();
    }
    console.log('退出全屏')
  }
})

Element.requestFullscreen

Element.requestFullscreen 方法用于发出异步请求使元素进入全屏模式。调用此 API 并不能保证元素一定能够进入全屏模式。如果元素被允许进入全屏幕模式,返回的 Promise 会 resolve,并且该元素会收到一个 fullscreenchange 事件,通知它已经进入全屏模式。如果全屏请求被拒绝,返回的 promise 会变成 rejected 并且该元素会收到一个 fullscreenerror 事件。如果该元素已经从原来的文档中分离,那么该文档将会收到这些事件。

语法

var Promise = Element.requestFullscreen(options);

options:可选,一个 FullscreenOptions 对象提供切换到全屏模式的控制选项。

这个方法只能在用户交互或者设备方向改变的时候调用,否则将会失败。FullscreenOptions 目前唯一的选项是 navigationUI,这控制了是否在元素处于全屏模式时显示导航条 UI。默认值是 auto,表明这将由浏览器来决定是否显示导航条。

Document.exitFullscreen

Document.exitFullscreen 方法用于让当前文档退出全屏模式。调用这个方法会让文档回退到上一个调用 Element.requestFullscreen 方法进入全屏模式之前的状态。

语法

document.exitFullscreen();

到此,示例页面的全部功能都完成了,可访问以下链接查看完整代码。

完整代码:https://github.com/dragonir/3d/tree/master/src/containers/Floating

总结

本文知识点主要包含的的新知识:

  • CSS 网格背景
  • MeshNormalMaterial 法向材质
  • FontLoader 字体加载器
  • TextGeometry 文本缓冲几何体
  • TorusBufferGeometry 圆环缓冲几何体
  • ConeBufferGeometry 圆锥缓冲几何体
  • OctahedronBufferGeometry 八面缓冲几何体
  • Three.js 后期渲染
  • GlitchPass 通道
  • Element.requestFullscreen
  • Document.exitFullscreen

以上就是Three.js+React实现3D文字悬浮效果的详细内容,更多关于Three.js React文字悬浮的资料请关注我们其它相关文章!

(0)

相关推荐

  • three.js如何实现3D动态文字效果

    前言 大家好,这里是 CSS 魔法使--alphardex. 之前在逛国外网站的时候,发现有些网站的文字是刻在3D图形上的,并且能在图形上运动,视觉效果相当不错,于是笔者就也想用three.js来尝试复现出这种效果 上图只是所有效果的其中之一,接下来让我们一起开干吧~ 准备工作 笔者自行封装的three.js模板:Three.js Starter 读者可以点击右下角fork一份后再开始本项目 本项目需要用到位图字体,可以直接复制demo的HTML里的font字体代码 一个注意点:three-bm

  • Three.js+React使二维图片呈现3D效果

    目录 背景 效果 实现 素材制作 资源引入 场景初始化 创建漫画主体 创建Boom背景 镜头控制.缩放适配.动画 总结 背景 逛 sketchfab 网站的时候我看到有很多二维平面转 3D 的模型例子,于是仿照他们的例子,使用 Three.js + React 技术栈,将二维漫画图片转化为三维视觉效果.本文包含的内容主要包括:THREE.Group 层级模型.MeshPhongMaterial 高光网格材质.正弦余弦函数 创建模型移动轨迹等. 效果 实现效果如下图所示:页面主要有背景图.漫画图片

  • 基于Three.js制作一个3D中国地图

    目录 1.使用geoJson绘制3d地图 1.1 创建场景相关 1.2 根据json绘制地图 2.增加光照 3.增加阴影模糊 4.增加鼠标事件 5.渲染 6.动画效果 不想看繁琐步骤的,可以直接去github下载项目,如果可以顺便来个star哈哈 本项目使用vue-cli创建,但不影响使用,主要绘制都已封装成类 1.使用geoJson绘制3d地图 1.1 创建场景相关 // 创建webGL渲染器 this.renderer = new THREE.WebGLRenderer( { antiali

  • 使用Three.js制作一个3D奖牌页面

    目录 背景 效果 实现 引入资源 场景初始化 光照效果 Three.js 提供的光源 添加网格和地面 创建奖牌 奖牌UI素材生成 Three.js 中的贴图 MeshPhysicalMaterial 物理材质 特殊属性 加载1000+文字模型 补间动画 动画更新 礼花动画 总结 背景 本文使用 React + Three.js 技术栈,实现粉丝突破1000的3D纪念页面,包含的主要知识点包括:Three.js 提供的光源.DirectionLight 平行光.HemisphereLight 半球

  • Three.js+React实现3D文字悬浮效果

    目录 背景 效果 实现 资源引入 DOM结构 设置状态 网格背景 场景初始化 创建材质 创建文字模型 创建几何体模型 鼠标事件监听 背景色切换 后期渲染 动画 缩放适配 双击全屏 总结 背景 在 Three.js Journey 课程示例中,提供了一个使用 Three.js 内置方法实现的 3D 文字悬浮效果的例子,本文使用 React + Three.js 技术栈,参照示例实现类似的效果.本文中涉及到的知识点主要包括:CSS 网格背景.MeshNormalMaterial 法向材质.FontL

  • Three.js+React制作3D梦中海岛效果

    目录 背景 效果 实现 素材准备 资源引入 页面结构 场景初始化 海 天空 虹 岛 鸟 交互点 动画 总结 背景 深居内陆的人们,大概每个人都有过大海之梦吧.夏日傍晚在沙滩漫步奔跑:或是在海上冲浪游泳:或是在海岛游玩探险:亦或静待日出日落……本文使用 React + Three.js 技术栈,实现 3D 海洋和岛屿,主要包含知识点包括:Tone Mapping.Water 类.Sky 类.Shader 着色.ShaderMaterial 着色器材质.Raycaster 检测遮挡以及 Three.

  • Three.js+React实现3D冰墩墩2022冬奥会主题

    目录 背景 效果 实现 引入资源 页面DOM结构 场景初始化 添加光源 加载进度管理 创建地面 创建冬奥吉祥物冰墩墩 创建奥运五环 TorusGeometry 圆环面 MeshLambertMaterial 非光泽表面材质 创建旗帜 创建树木 MeshDepthMaterial 深度网格材质 custromMaterial 自定义材质 创建雪花 Points 粒子 PointsMaterial 点材质 材质属性 .blending 材质属性 .sizeAttenuation Three.js 向

  • JS实现IE状态栏文字缩放效果代码

    本文实例讲述了JS实现IE状态栏文字缩放效果代码.分享给大家供大家参考,具体如下: 这里演示状态栏文字缩放变化效果,同样基于JavaScript技术,虽然很不起眼的小特效,不过对学习JS来说,还是很有用的.本效果直接运行可能看不到效果,你可以复制代码保存成一个HTML文件,双击后运行可看到效果. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-ie-ztl-txt-style-demo/ 具体代码如下: <HTML> <HEAD&g

  • Three.js+React实现3D开放世界小游戏

    目录 背景 效果 设计 实现 加载资源 页面结构 数据初始化 场景初始化 创建世界 创建星空 创建地形 加载进度管理 创建基地模型 创建阿狸模型 控制阿狸运动 动画更新 页面缩放适配 添加游戏逻辑 毛玻璃效果 总结 背景 2545光年之外的开普勒1028星系,有一颗色彩斑斓的宜居星球 ,星际移民必须穿戴基地发放的防辐射服才能生存.阿狸驾驶星际飞行器降临此地,快帮它在限定时间内使用轮盘移动找到基地获取防辐射服吧! 本文使用 Three.js + React + CANNON 技术栈,实现通过滑动屏

  • CSS3实现3D文字动画效果

    body{background:#333;} h1{font:normal 90px/1.5 'Ultra','Curlz MT','Bauhaus 93','Blackoak Std',Courier,Arial;color:#7e9409;position:absolute;top:85px;left:10px;width:300px; -moz-animation: 1s slidein; -webkit-animation: 1s slidein; -webkit-perspective

  • js实现图片3D轮播效果

    3D的图片轮播效果很炫,写到这里只是为了不丢代码,不为别的. 效果预览: html代码: <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>js实现3D图片逐张轮播幻灯片</title> </head> <body> <style> ul#bcty365_nav{pa

  • JS实现倒计时和文字滚动的效果实例

    本文实例讲述了JS实现倒计时和文字滚动效果的方法.分享给大家供大家参考.具体实现方法如下: 说明:一般我们在一些淘宝类店铺中会看到一些像搞竞拍之类的活动,从中我们时而会发现一些倒计时的效果,在一些年会等场合我们也会发现一些抽奖活动,从中我们也可以看到一些随即滚动的效果.这里给大家分享一种实现倒计时和文字滚动的方法,希望可以对大家有所帮助.这里主要是通过js实现的. 一.倒计时效果的实现 前台部分的完整代码如下: 复制代码 代码如下: <html xmlns="http://www.w3.o

  • JS溶解形式的文字切换特效

    JS溶解形式的文字切换特效 messages = new Array() messages[0] = "我们,都知道吧?" messages[1] = "我们更关注开源,欢迎发布开源源代码" messages[2] = "提供给你一个有质量的源代码资料站" mescolor = new Array() mescolor[0] = "000000" mescolor[1] = "FF0000" mescolo

随机推荐