- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 Three.js 构建一个基于图像的艺术制作应用程序。
我正在使用 React.js,但希望即使对于那些没有 React 经验的人来说,以下内容也很清楚。该组件呈现一个 ,并从父组件传递了一个本地托管的图像 URL。
当前代码设置为简单地创建一个全窗口 Canvas ,创建一个跨越整个 Canvas 的 2D 形状,并将提供的图像设置为纹理:
import React, { PureComponent } from 'react';
import * as THREE from 'three';
const textureLoader = new THREE.TextureLoader();
const vertexShader = `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4(uv * 2. - vec2(1, 1), 0., 1.);
}
`;
const fragmentShader = `
precision highp float;
varying vec2 vUv;
uniform sampler2D texture1;
void main() {
gl_FragColor = texture2D(texture1, vUv.xy);
}
`;
class Canvas extends PureComponent {
state = {
width: window.innerWidth,
height: window.innerHeight
}
componentDidMount() {
// TODO: resize handlers for width/height
const {width, height} = this.state;
this.canvas.width = width;
this.canvas.height = height;
const rendererParams = {
canvas: this.canvas,
};
const cameraParams = [
-width / 2,
width / 2,
-height / 2,
height / 2,
];
this.renderer = new THREE.WebGLRenderer(rendererParams);
this.renderer.setClearColor(0xFFFFFF, 1.0)
this.renderer.setSize(width, height);
this.camera = new THREE.OrthographicCamera(...cameraParams);
this.camera.position.set(0, 0, 200);
this.scene = new THREE.Scene();
this.scene.add(this.camera);
// Our initial texture will be the specified default image.
const imageSrc = this.props.defaultImageSrc;
textureLoader.load(imageSrc, texture => {
this.texture = texture;
// TODO: Do I need this?
this.material = new THREE.ShaderMaterial({
vertexShader,
fragmentShader,
uniforms: {
texture1: {
type: "t",
value: this.texture
}
}
});
this.mesh = new THREE.Mesh(new THREE.PlaneGeometry(1), this.material);
this.scene.add(this.mesh);
this.animate();
})
}
animate = () => {
requestAnimationFrame(this.animate);
this.renderer.render(this.scene, this.camera);
}
render() {
return (
<canvas innerRef={elem => this.canvas = elem} />
);
}
}
export default Canvas;
我遇到的问题是纹理将被拉伸(stretch)以适应。这意味着,如果图像是 1600x1600 的正方形,但浏览器窗口是 1000x500,则图像将被挤压和扭曲,因为它将图像映射为完全适合可用空间:
我想要的是background-size: cover
的等价物。我希望它缩小到最大的窗口尺寸(在我的示例中为 1000x1000),然后从中心裁剪以仅显示中间 500px 的高度。
最佳答案
您需要展示您的相机,您使用的是PerspectiveCamera
、OrthographicCamera
还是占位符Camera
。而且,如果您使用自定义着色器,您需要展示如何计算顶点位置(您是否使用 projectionMatrix
等...)。如果没有这些知识,没有人能够回答这个问题。
以下是如何使用刚刚设置为单位矩阵的 OrthographicCamera
和 2 个单位 PlaneGeometry
来实现此操作。
如果我们不做任何更改,这将显示一个填充 Canvas 的平面。之后,我们根据 Canvas 的方面和图像的方面对其进行缩放
const canvas = renderer.domElement;
const image = material.map.image;
const canvasAspect = canvas.clientWidth / canvas.clientHeight;
const imageAspect = image.width / image.height;
// this assumes we want to fill vertically
let horizontalDrawAspect = imageAspect / canvasAspect;
let verticalDrawAspect = 1;
// does it fill horizontally?
if (horizontalDrawAspect < 1) {
// no it does not so scale so we fill horizontally and
// adjust vertical to match
verticalDrawAspect /= horizontalDrawAspect;
horizontalDrawAspect = 1;
}
mesh.scale.x = horizontalDrawAspect;
mesh.scale.y = verticalDrawAspect;
const scene = new THREE.Scene();
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, -1, 1);
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);
const geometry = new THREE.PlaneGeometry(2, 2);
const material = new THREE.MeshBasicMaterial({});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
camera.position.z = 1;
function render() {
resize();
if (!material.map.image) {
return;
}
const canvas = renderer.domElement;
const image = material.map.image;
const canvasAspect = canvas.clientWidth / canvas.clientHeight;
const imageAspect = image.width / image.height;
// this assumes we want to fill vertically
let horizontalDrawAspect = imageAspect / canvasAspect;
let verticalDrawAspect = 1;
// does it fill horizontally?
if (horizontalDrawAspect < 1) {
// no it does not so scale so we fill horizontally and
// adjust vertical to match
verticalDrawAspect /= horizontalDrawAspect;
horizontalDrawAspect = 1;
}
mesh.scale.x = horizontalDrawAspect;
mesh.scale.y = verticalDrawAspect;
renderer.render(scene, camera);
}
function resize() {
const canvas = renderer.domElement
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (canvas.width !== width || canvas.height !== height) {
renderer.setSize(width, height, false);
}
}
window.addEventListener('resize', render);
const loader = new THREE.TextureLoader();
loader.crossOrigin = "";
// load a resource
loader.load('http://i.imgur.com/TSiyiJv.jpg', function (texture) {
texture.wrapS = THREE.ClampToEdgeWrapping;
texture.wrapT = THREE.ClampToEdgeWrapping;
texture.minFilter = THREE.LinearFilter;
material.map = texture;
render();
});
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.min.js"></script>
关于javascript - THREEjs - 裁剪纹理而不是拉伸(stretch)以适应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44720511/
我想创建一个随页面宽度变化的页眉。 我的标题由三部分组成,固定宽度的两侧和可拉伸(stretch)的中间部分。 我使用 displa
我正在尝试在导航栏下方创建一列内容,以便内容的宽度与导航栏的宽度完全匹配。事实证明这比我预期的要困难。 给定这样的东西: link
我有一个大小为 12*30 的字符串的图像。我想创建一个动画,让它给人一种拉伸(stretch)字符串的感觉。我通过缩放图像来做到这一点,但我面临的问题是缩放图像没有发生碰撞。它仅出现在原始图像大小的
在 Silverlight 中,如何拉伸(stretch) Line 的宽度以填充作为子元素的 StackPanel 的宽度?更喜欢 XAML 解决方案,而不是代码隐藏。这是我在 WPF 中的操作方法
QML 怎么可能?自动拉伸(stretch)元素以使其所有子元素都适合它?以及如何指定间距?例如,我想在文本周围有一个矩形。矩形应该有一些内部间距。 如果我写以下内容,则矩形的大小为 0,0。 Rec
我已经习惯了使用 matlab,现在正在尝试转换 matplotlib 和 numpy。 matplotlib 中是否有一种方法可以让您绘制的图像占据整个图形窗口。 import numpy as n
我有一个(简化的)2x2 网格,里面有三个控件。左控制在两行上延伸。
假设我有 3 个大小不匹配的列表,[3, 7, 6]、[12, 67, 89, 98] 和 [1, 2, 3, 4, 5, 6, 7]我想要一个函数来执行此操作: >>> stretch([3, 7,
如果 Image 被 Stretched,我可以获取 Height 和 Width 吗>UniformToFill? 我尝试了 Width 和 Height 属性,但它们始终是 NaN。 最佳答案 如
当我为微调器使用我自己的背景主题时,它是拉伸(stretch)图标。 我的微调器代码是: 我的 spinner.xml 是: 和我从 sdk 4 复制的图
我正在尝试在 OpenGL 中创建一个简单的 GUI。我创建了一张图片,以便我可以引用它并使解释更简单: 当我将按钮 (32x32) 的纹理应用到大小为 120x20 的四边形多边形(即不是矩形作为纹
SurfaceTexture 预览被拉伸(stretch)了!我正在开发一个 camera2 应用程序。每个设备都工作不好。视频和照片的预览被拉伸(stretch)。 public class Cam
我使用一些ImageButtons 创建了一个Android layout。我的布局在小屏幕(例如 3.6 英寸到 4.2 英寸)上运行良好,但是当我在 7 英寸或 9 英寸平板电脑上使用我的应用程序
我在拉伸(stretch) GridView 以适应显示宽度时遇到问题。任何人都知道如何解决这个问题?我希望 GridView 占据整个宽度,包括蓝色标记的字段(见下图)
我使用位图作为 Activity 的背景。自定义背景代码为: 但是它位于中间,并没有占据整个屏幕空间。我怎样才能让它填满所有可用空间?我尝试将宽度和高度设置为 fill_parent。 谢谢 最
所以我最近一直在为 iOS 开发应用程序,但遇到了一个难题。我正在制作一个迷你合成器,然后开始制作 GUI。我开始制作键盘(目前为 2 个 Octave )并测量了白键的大致长度。一切都很好,直到我在
好的,所以我在 slider 内有一个图像,但它不能正确缩放。 先小后伸,想一直伸到底,怎么实现? 看一下截图(忽略第二张截图中的红色部分): 还有CSS: .slider-wrapper {
我有下面的 HTML,我希望容器 div 拉伸(stretch)到窗口的整个高度。这对 wine 有效,但是当您移除容器内的两个蓝色 div 时会发生什么?容器延伸到其中蓝色 div 的底部,但不会延
我正尝试在 this example 之后制作背景,但我需要嵌套 2 个容器。 我的代码看起来像这样: XHTML:
这是关于用颜色填充背景。 我正在构建 this project 的 SwiftUI 版本.这是一个选项卡式应用程序(测试工具)。 This is my Working Project 我要做的第一件事
我是一名优秀的程序员,十分优秀!