Я пытаюсь сохранить пропорции хотя бы немного, когда окно изменено в меньших размерах на CodePen здесь . В настоящее время оказывается очень трудно увидеть линии и взаимодействие на мобильном телефоне. У вас есть решение для этого? Может быть, имеет смысл удвоить масштаб при изменении размера в зависимости от окна, но я немного растерялся из-за того, как я могу его реализовать.
Ответственная часть JS:
onWindowResize();
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize(event) {
container.style.height = window.innerHeight+"px";
container.style.width = window.innerWidth+"px";
canvasWidth = container.offsetWidth;
canvasHeight = container.offsetHeight;
//send new size value to the shader and resize the window
uniforms.resolution.value.x = canvasWidth;
uniforms.resolution.value.y = canvasHeight;
//var res = canvasWidth / cols;
//rows = canvasHeight / res;
uniforms.colsrows.value.x = cols;
uniforms.colsrows.value.y = rows;//rows;
renderer.setSize(canvasWidth, canvasHeight);
}
Вот ручка:
//Create var for the contenair, the webGL 3D scene, uniforms to bind into shader and timer
var container;
var camera, scene, renderer;
var uniforms;
var startTime;
var cols = 50.;
var rows = 50.0;
init(); //init scene
animate(); //updateScene
function init() {
//get contenaire
container = document.getElementById('container');
//Create THREE.JS scene and timer
startTime = Date.now();
camera = new THREE.Camera();
camera.position.z = 1;
scene = new THREE.Scene();
//create a simple plance
var geometry = new THREE.PlaneBufferGeometry(16, 9);
//create uniform table which provide all our GLSL binding
uniforms = {
time: { type: "f", value: 1.0 },
resolution: { type: "v2", value: new THREE.Vector2() },
colsrows: {type: "v2", value: new THREE.Vector2()},
mouse: {type: "v2", value: new THREE.Vector2()}
};
//create THREE.JS material
var material = new THREE.ShaderMaterial( {
//set shaders and uniforms into material
uniforms: uniforms,
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent
} );
//create mesh, add it to the scene
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
//create renderer and add it to the DOM
renderer = new THREE.WebGLRenderer();
container.appendChild(renderer.domElement);
//check window for resize This will give us the proper resolution values to bind
onWindowResize();
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize(event) {
container.style.height = window.innerHeight+"px";
container.style.width = window.innerWidth+"px";
canvasWidth = container.offsetWidth;
canvasHeight = container.offsetHeight;
//send new size value to the shader and resize the window
uniforms.resolution.value.x = canvasWidth;
uniforms.resolution.value.y = canvasHeight;
//var res = canvasWidth / cols;
//rows = canvasHeight / res;
uniforms.colsrows.value.x = cols;
uniforms.colsrows.value.y = rows;//rows;
renderer.setSize(canvasWidth, canvasHeight);
}
function animate() {
render();
requestAnimationFrame(animate);
}
function render() {
var currentTime = Date.now();
var elaspedSeconds = (currentTime - startTime) / 1000.0;
var maxTime = 4.0;
var normTime = (elaspedSeconds % maxTime) / maxTime;
uniforms.time.value = elaspedSeconds * 1.0;
renderer.render(scene, camera);
}
function move(ev){
mx = ev.clientX
my = ev.clientY;
// console.log(mx+" , "+my);
uniforms.mouse.value.x = mx;
uniforms.mouse.value.y = my;
}
document.addEventListener('mousemove', move)
html, body {
margin: 0;
height: 100%;
background : #1a1a1a;
}
canvas {
display: block;
cursor: none;
}
#container{
background : black;
color : white;
margin: auto;
width : 500px;
height : 500px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<div id="container"></div>
<!-- GLSL SCRIPT -->
<!-- vertex shader -->
<script id="vertexShader" type="x-shader/x-vertex">
void main() {
gl_Position = vec4(position, 1.0);
}
</script>
<!-- fragment shader -->
<script id="fragmentShader" type="x-shader/x-fragment">
#define TWO_PI 6.28318530718
#define EPSILON 0.000011
uniform vec2 resolution;
uniform float time;
uniform vec2 colsrows;
uniform vec2 mouse;
float HueToRGB(float f1, float f2, float hue)
{
if (hue < 0.0)
hue += 1.0;
else if (hue > 1.0)
hue -= 1.0;
float res;
if ((6.0 * hue) < 1.0)
res = f1 + (f2 - f1) * 6.0 * hue;
else if ((2.0 * hue) < 1.0)
res = f2;
else if ((3.0 * hue) < 2.0)
res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0;
else
res = f1;
return res;
}
vec3 HSLToRGB(vec3 hsl)
{
vec3 rgb;
if (hsl.y == 0.0)
rgb = vec3(hsl.z); // Luminance
else
{
float f2;
if (hsl.z < 0.5)
f2 = hsl.z * (1.0 + hsl.y);
else
f2 = (hsl.z + hsl.y) - (hsl.y * hsl.z);
float f1 = 2.0 * hsl.z - f2;
rgb.r = HueToRGB(f1, f2, hsl.x + (1.0/3.0));
rgb.g = HueToRGB(f1, f2, hsl.x);
rgb.b= HueToRGB(f1, f2, hsl.x - (1.0/3.0));
}
return rgb;
}
mat2 rotate2d(float _angle){
return mat2(cos(_angle),-sin(_angle),
sin(_angle),cos(_angle));
}
vec2 rotateFrom(vec2 uv, vec2 center, float angle){
vec2 uv_ = uv - center;
uv_ = rotate2d(angle) * uv_;
uv_ = uv_ + center;
return uv_;
}
float random(float value){
return fract(sin(value) * 43758.5453123);
}
float random(vec2 tex){
return fract(sin(dot(tex.xy, vec2(12.9898, 78.233))) * 43758.5453123);
}
vec2 random2D(vec2 uv){
uv = vec2(dot(uv, vec2(127.1, 311.7)), dot(uv, vec2(269.5, 183.3)));
//return -1.0 + 2.0 * fract(sin(uv) * 43758.5453123);
return fract(sin(uv) * 43758.5453123); //return without offset on x, y
}
vec3 random3D(vec3 uv){
uv = vec3(dot(uv, vec3(127.1, 311.7, 120.9898)), dot(uv, vec3(269.5, 183.3, 150.457)), dot(uv, vec3(380.5, 182.3, 170.457)));
return -1.0 + 2.0 * fract(sin(uv) * 43758.5453123);
}
float cubicCurve(float value){
return value * value * (3.0 - 2.0 * value); // custom cubic curve
}
vec2 cubicCurve(vec2 value){
return value * value * (3.0 - 2.0 * value); // custom cubic curve
}
vec3 cubicCurve(vec3 value){
return value * value * (3.0 - 2.0 * value); // custom cubic curve
}
float noise(vec2 uv){
vec2 iuv = floor(uv);
vec2 fuv = fract(uv);
vec2 suv = cubicCurve(fuv);
float dotAA_ = dot(random2D(iuv + vec2(0.0)), fuv - vec2(0.0));
float dotBB_ = dot(random2D(iuv + vec2(1.0, 0.0)), fuv - vec2(1.0, 0.0));
float dotCC_ = dot(random2D(iuv + vec2(0.0, 1.0)), fuv - vec2(0.0, 1.0));
float dotDD_ = dot(random2D(iuv + vec2(1.0, 1.0)), fuv - vec2(1.0, 1.0));
return mix(
mix(dotAA_, dotBB_, suv.x),
mix(dotCC_, dotDD_, suv.x),
suv.y);
}
float noise(vec3 uv){
vec3 iuv = floor(uv);
vec3 fuv = fract(uv);
vec3 suv = cubicCurve(fuv);
float dotAA_ = dot(random3D(iuv + vec3(0.0)), fuv - vec3(0.0));
float dotBB_ = dot(random3D(iuv + vec3(1.0, 0.0, 0.0)), fuv - vec3(1.0, 0.0, 0.0));
float dotCC_ = dot(random3D(iuv + vec3(0.0, 1.0, 0.0)), fuv - vec3(0.0, 1.0, 0.0));
float dotDD_ = dot(random3D(iuv + vec3(1.0, 1.0, 0.0)), fuv - vec3(1.0, 1.0, 0.0));
float dotEE_ = dot(random3D(iuv + vec3(0.0, 0.0, 1.0)), fuv - vec3(0.0, 0.0, 1.0));
float dotFF_ = dot(random3D(iuv + vec3(1.0, 0.0, 1.0)), fuv - vec3(1.0, 0.0, 1.0));
float dotGG_ = dot(random3D(iuv + vec3(0.0, 1.0, 1.0)), fuv - vec3(0.0, 1.0, 1.0));
float dotHH_ = dot(random3D(iuv + vec3(1.0, 1.0, 1.0)), fuv - vec3(1.0, 1.0, 1.0));
float passH0 = mix(
mix(dotAA_, dotBB_, suv.x),
mix(dotCC_, dotDD_, suv.x),
suv.y);
float passH1 = mix(
mix(dotEE_, dotFF_, suv.x),
mix(dotGG_, dotHH_, suv.x),
suv.y);
return mix(passH0, passH1, suv.z);
}
float drawLine(vec2 uv, vec2 p1, vec2 p2, float r)
{
//from https://www.shadertoy.com/view/MtlSDr
vec2 l = p2 - p1;
float L = length(l);
float L2 = L*L;
float d1 = length(uv - p1);
float d2 = length(uv - p2);
float d = min(d1, d2);
float ds = dot(uv - p1, l);
if (ds >= 0.0 && ds <= L2)
{
vec2 n = vec2(-l.y, l.x) / L;
d = min(d, abs(dot(uv - p1, n)));
}
return 1.0 - smoothstep(0.0, 0.01, d - r);
}
vec2 fishey(vec2 uv, vec2 center, float ratio, float dist){
vec2 puv = uv + vec2(1.0);
//center coords
vec2 m = vec2(center.x, center.y/ratio) + vec2(1.0);
//vector from center to current fragment
vec2 d = puv - m;
// distance of pixel from center
float r = sqrt(dot(d, d));
//amount of effect
float power = ( TWO_PI / (2.0 * sqrt(dot(m, m)))) * mix(0.1, 0.4, pow(dist, 0.75));
//radius of 1:1 effect
float bind;
if (power > 0.0) bind = sqrt(dot(m, m));//stick to corners
//else {if (ratio < 1.0) bind = m.x; else bind = m.y;}//stick to borders
//Weird formulas
vec2 nuv;
if (power > 0.0)//fisheye
nuv = m + normalize(d) * tan(r * power) * bind / tan( bind * power);
else if (power < 0.0)//antifisheye
nuv = m + normalize(d) * atan(r * -power * 10.0) * bind / atan(-power * bind * 10.0);
else
nuv = puv;//no effect for power = 1.0
return nuv - vec2(1.0);
}
vec4 addGrain(vec2 uv, float time, float grainIntensity){
float grain = random(fract(uv * time)) * grainIntensity;
return vec4(vec3(grain), 1.0);
}
void main(){
vec2 ouv = gl_FragCoord.xy / resolution.xy;
vec2 uv = ouv;
float ratio = resolution.x / resolution.y;
vec2 nmouse = vec2(mouse.x, mouse.y) / resolution.xy;
nmouse.y = 1.0 - nmouse.y;
float maxDist = 0.35;
float blurEdge = maxDist * 0.5;
float blurEdge2 = maxDist * 1.0;
vec2 mouseToUV = (uv - nmouse) / vec2(1.0, ratio);
float mouseDistance = 1.0 - smoothstep(maxDist - blurEdge, maxDist, length(mouseToUV));
float mouseDistance2 = 1.0 - smoothstep(maxDist - blurEdge2, maxDist, length(mouseToUV));
uv = fishey(uv, nmouse, ratio, mouseDistance2);
uv = rotateFrom(uv, vec2(0.5), time * 0.1);
//animate y
//wave
uv.y /= ratio;
vec2 basedUV = uv + vec2(1.0);
float complexityX = 10.0;
float complexityY = 10.0;
float maxAmp = mix(0.05, 0.75, mouseDistance);
float amp = 0.01 * mouseDistance + noise(vec3(basedUV.x * complexityX, basedUV.y * complexityY, time * 0.1)) * maxAmp;
float theta = time + mouseDistance + basedUV.y * (TWO_PI);
uv.x = fract(uv.x + sin(theta) * amp);
//divide into cols rows
vec2 nuv = uv * colsrows;
vec2 fuv = fract(nuv);
vec2 iuv = floor(nuv);
float minSpeed = 1.0;
float maxSpeed = 5.0;
float speed = minSpeed + random(floor(uv.x * colsrows.x)) * (maxSpeed - minSpeed);
fuv.y = fract(fuv.y + time * speed);
//draw dash line
float minWeight = 0.005 + random(vec2(iuv.x, 0.0)) * 0.05;
float strokeWeight = mix(minWeight, minWeight * 5.0, mouseDistance);
float dlineWidth = mix(1.0, 0.25 - strokeWeight, mouseDistance);//0.5 - strokeWeight;
float dline = drawLine(fuv, vec2(0.5, 0.5 - dlineWidth * 0.5), vec2(0.5, 0.5 + dlineWidth * 0.5), strokeWeight);
float randIndexHue = random(vec2(iuv.x + floor(time), 0.0));
float noiseHue = noise(vec3(randIndexHue, randIndexHue, time));
float hue = mix(0.111, 0.138, randIndexHue + (noiseHue * 0.5));
vec4 grain = addGrain(ouv, time, 0.15);
//vec3 color = HSLToRGB(vec3(hue, 1.0, 0.5));
//vec3 bgColor = HSLToRGB(vec3(0.772, mix(0.75, 1.0, mouseDistance), mix(0.1, 0.25, mouseDistance)));
vec3 color = vec3(1.0);
vec3 bgColor = vec3(0.0);
float val = dline * (mouseDistance * 0.5 + 0.5);
vec3 albedo = mix(bgColor, color, val);
gl_FragColor = vec4(albedo, 1.0) + grain;
}
</script>