对threejs还不熟悉的小伙伴可以先这篇文章:Threejs入门教程_程序猿青石的博客-CSDN博客
1.初始化场景,相机
import * as THREE from "three";
// 初始化场景
const scene = new THREE.Scene();
// 初始化相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
2000
);
// // 设置相机位置
camera.position.set(-50, 50, 130);
scene.add(camera);
2.初始化渲染器
// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染器宽高
renderer.setSize(window.innerWidth, window.innerHeight);
// 将渲染器添加到页面
document.body.appendChild(renderer.domElement);
// 实例化控制器
const controls = new OrbitControls(camera, renderer.domElement);
3.添加轨道控制器并循环渲染图画
// 导入控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 实例化控制器
const controls = new OrbitControls(camera, renderer.domElement);
function render() {
// 渲染场景
renderer.render(scene, camera);
// 引擎自动更新渲染器
requestAnimationFrame(render);
}
render();
4.监听窗口并实现画布自适应
// 监听屏幕的大小改变,修改渲染器的宽高,相机的比例
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
// 修改属性后需要刷新来使改变生效
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
1.为场景添加平行光
平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光 的效果; 太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的。
构造函数:
DirectionalLight( color : Integer, intensity : Float )
color - (可选参数) 16进制表示光的颜色。 缺省值为 0xffffff (白色)。
intensity - (可选参数) 光照的强度。缺省值为1。
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(-100, 100, 10);
scene.add(light);
2.为背景添加天空球体
TextureLoader
加载texture的一个类。 内部使用ImageLoader来加载文件。
.load ( url : String, onLoad : Function, onProgress : Function, onError : Function ) : Texture
url — 文件的URL或者路径,也可以为 Data URI.
onLoad — 加载完成时将调用。回调参数为将要加载的texture.
onProgress — 将在加载过程中进行调用。参数为XMLHttpRequest实例,实例包含total和loaded字节。
onError — 在加载错误时被调用。
注意:此处的url的默认目录当前目录是项目打包生成的dist文件夹,所有资源文件均需放置到此文件夹下方可访问
.map : Texture
颜色贴图。可以选择包括一个alpha通道,通常与.transparent 或.alphaTest。默认为null。
.scale ( x : Float, y : Float, z : Float ) : this
缩放几何体。该操作一般在一次处理中完成,不会循环处理。典型的用法是通过调用 Object3D.scale 实时旋转几何体。
// 创建一个巨大的天空球体
let texture = new THREE.TextureLoader().load("./textures/water/sky.jpg");
const skyGeometry = new THREE.SphereGeometry(1000, 60, 60);
const skyMaterial = new THREE.MeshBasicMaterial({
map: texture,
});
skyGeometry.scale(1, 1, -1);
const sky = new THREE.Mesh(skyGeometry, skyMaterial);
scene.add(sky);
3.添加视频纹理
VideoTexture
创建一个使用视频来作为贴图的纹理对象。
它和其基类Texture几乎是相同的,除了它总是将needsUpdate设置为true,以便使得贴图能够在视频播放时进行更新。自动创建mipmaps也会被禁用。
// 视频纹理
const video = document.createElement("video");
video.src = "./textures/sky.mp4";
video.loop = true;
window.addEventListener("click", (e) => {
// 当鼠标移动的时候播放视频
// 判断视频是否处于播放状态
if (video.paused) {
video.play();
let texture = new THREE.VideoTexture(video);
skyMaterial.map = texture;
skyMaterial.map.needsUpdate = true;
}
});
4.创建水面
CircleGeometry是欧式几何的一个简单形状,它由围绕着一个中心点的三角分段的数量所构造,由给定的半径来延展。 同时它也可以用于创建规则多边形,其分段数量取决于该规则多边形的边数。
CircleGeometry(radius : Float, segments : Integer, thetaStart : Float, thetaLength : Float)
radius — 圆形的半径,默认值为1
segments — 分段(三角面)的数量,最小值为3,默认值为8。
thetaStart — 第一个分段的起始角度,默认为0。(three o'clock position)
thetaLength — 圆形扇区的中心角,通常被称为“θ”(西塔)。默认值是2*Pi,这使其成为一个完整的圆。
// 导入水面
import { Water } from "three/examples/jsm/objects/Water2";
// 创建水面
const waterGeometry = new THREE.CircleBufferGeometry(300, 64);
const water = new Water(waterGeometry);
water.position.y = -80;
// 水面旋转至水平
water.rotation.x = -Math.PI / 2;
scene.add(water);
5.导入实例模型
draco
draco是谷歌出的一款模型压缩工具,可将gltf格式的模型进行进一步压缩提高页面加载速的一种方法
github官网:https://github.com/google/draco
下载后将javascript文件夹复制到本项目dist目录下
sketchfab(3d模型网站)
同样下载的模型也需要放置到dist目录下,我的模型在model文件夹下
// 导入gltf载入库
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
// 添加小狗模型
// 实例化gltf载入库
const loader = new GLTFLoader();
// 实例化draco载入库
const dracoLoader = new DRACOLoader();
// 添加draco载入库
dracoLoader.setDecoderPath("./javascript/");
// 添加draco载入库
loader.setDRACOLoader(dracoLoader);
loader.load("./model/shiba.glb", (gltf) => {
gltf.scene.scale.set(100,100,100)
scene.add(gltf.scene);
});
package.json
{
"name": "ch02",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "parcel src/index.html",
"build": "parcel build src/index.html"
},
"author": "",
"license": "ISC",
"devDependencies": {
"parcel": "^2.4.1"
},
"dependencies": {
"dat.gui": "^0.7.9",
"gsap": "^3.10.3",
"three": "^0.139.2"
}
}
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
我有一些非常大的模型,我必须将它们迁移到最新版本的Rails。这些模型有相当多的验证(User有大约50个验证)。是否可以将所有这些验证移动到另一个文件中?说app/models/validations/user_validations.rb。如果可以,有人可以提供示例吗? 最佳答案 您可以为此使用关注点:#app/models/validations/user_validations.rbrequire'active_support/concern'moduleUserValidationsextendActiveSupport:
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs