Анимация трех JS светлого цвета с tweenmax - PullRequest
0 голосов
/ 27 февраля 2020

Я бы хотел поменять свои три JS цвета подсветки с временной шкалой tweenmax, но, похоже, это не работает. Вот то, что я попробовал. Я что-то не так делаю?


var light  = new THREE.HemisphereLight( "hsl(0,0%,87%);", 0xFFFFFF, 1);
var light2 = new THREE.PointLight( 0x69be94, 1, 15, 2 );
var light3 = new THREE.SpotLight( 0xFFFFE0, 1, 30, Math.PI/14, 1 );

...

var tl = new TimelineMax();
tl.to(light.color.setHSL, 1, { h : 1, s : 0.4, l : 0.58 });
tl.to(light2.color.setHex, 1, { hex: "#69BE94" });
tl.to(light3.color.setRGB, 1, { r: 105, g:190 ,b:148 }, 1,);

Ответы [ 3 ]

2 голосов
/ 27 февраля 2020

Обратите внимание, что .setHSL, .setHex, & .setRGB - это все методы , функции AKA. Вы не можете указывать на метод в качестве первого аргумента TweenMax, это должно быть свойство. Вам нужно будет сделать что-то вроде этого:

tl.to(light3.color, 1, {r: 0.3, g:0.7, b:0.5}, 1,); Чтобы график мог получить к нему доступ.

Также имейте в виду, что значения цвета .rgb находятся в диапазоне [0, 1] , а не [0, 255]. Если вам нужно перейти к указанному значению c HSL, просто используйте временную переменную цвета:

// Create temp variable to extract RGB values
var tempColor = new THREE.Color().setHSL(1, 0.4, 0.58);
tl.to(light.color, 1, { r: tempColor.r, g: tempColor.g, b: tempColor.b });

// Extract RGB values from tempColor again
tempColor.setHex(0x69BE94);
tl.to(light2.color, 1, { r: tempColor.r, g: tempColor.g, b: tempColor.b });

.setHex принимает целое число, а не строку

1 голос
/ 27 февраля 2020

@ Ответ Маркиззо работает, но если вы действительно хотите использовать анимацию HSL, а не RGB, вам нужно другое решение.

Как указывалось в tweenmax, настройте свойства, чтобы вы могли сделать объект, который использует геттеры и сеттеры, чтобы он имеет свойства для настройки tweenmax, но в итоге устанавливает цвет.

class HSLHelper {
  constructor(color) {
    this.color = color;
    this.temp = {h: 0, s: 0, l: 0};
  }
  get h() { return this.color.getHSL(this.temp).h; }
  set h(h) {
    const {s, l} = this.color.getHSL(this.temp);
    this.color.setHSL(h, s, l);
  }
  get s() { return this.color.getHSL(this.temp).s; }
  set s(s) {
    const {h, l} = this.color.getHSL(this.temp);
    this.color.setHSL(h, s, l);
  }
  get l() { return this.color.getHSL(this.temp).l; }
  set l(l) {
    const {h, s} = this.color.getHSL(this.temp);
    this.color.setHSL(h, s, l);
  }
}

И теперь вы можете использовать его, например.

const p = new THREE.PointLight( 0x69be94, 1, 15, 2 );
const helper = new HSLHelper(p.color);

var tl = new TimelineMax();
tl.to(helper, 1, { h : 1, s : 0.4, l : 0.58 });

Сравните результаты: куб слева использует анимацию RGB, куб справа использует анимацию HSL

class HSLHelper {
  constructor(color) {
    this.color = color;
    this.temp = {h: 0, s: 0, l: 0};
  }
  get h() { return this.color.getHSL(this.temp).h; }
  set h(h) {
    const {s, l} = this.color.getHSL(this.temp);
    this.color.setHSL(h, s, l);
  }
  get s() { return this.color.getHSL(this.temp).s; }
  set s(s) {
    const {h, l} = this.color.getHSL(this.temp);
    this.color.setHSL(h, s, l);
  }
  get l() { return this.color.getHSL(this.temp).l; }
  set l(l) {
    const {h, s} = this.color.getHSL(this.temp);
    this.color.setHSL(h, s, l);
  }
}

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas});

  const fov = 75;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 5;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 2;

  const scene = new THREE.Scene();

  const boxWidth = 1;
  const boxHeight = 1;
  const boxDepth = 1;
  const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);

  const material1 = new THREE.MeshBasicMaterial({color: 0xFF0000});
  const material2 = new THREE.MeshBasicMaterial({color: 0xFF0000});

  const cube1 = new THREE.Mesh(geometry, material1);
  scene.add(cube1);
  cube1.position.x = -1;
  const cube2 = new THREE.Mesh(geometry, material2);
  scene.add(cube2);
  cube2.position.x = 1;


  const tl1 = new TimelineMax();
  tl1.fromTo(material1.color, {r: 1, g: 0, b: 0}, {duration: 2, r: 0, g: 0, b: 1, ease:Linear.easeNone});
  tl1.repeat(-1);
  
  const helper2 = new HSLHelper(material2.color);
  const tl2 = new TimelineMax();
  tl2.fromTo(helper2, {h: 0, s: 1, l: 0.5}, {duration: 2, h: 0.66, s: 1, l: 0.5, ease:Linear.easeNone});
  tl2.repeat(-1);
  
  function render() {
    renderer.render(scene, camera);
    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);
}

main();
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r113/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.0.1/dist/gsap.min.js"></script>
<canvas id="c"></canvas>

Также обратите внимание, что H (оттенок) в HSL не ограничен 0 = красный, 0,33 = зеленый, 0,66 = синий, 1 = красный, 1,33 = зеленый, 1.66 = синий и т. Д. c .. Так, например, если я установлю h на go от 0 до 10 в течение 5 секунд, он будет go через все цвета 10 раз в течение 5 секунд

class HSLHelper {
  constructor(color) {
    this.color = color;
    this.temp = {h: 0, s: 0, l: 0};
  }
  get h() { return this.color.getHSL(this.temp).h; }
  set h(h) {
    const {s, l} = this.color.getHSL(this.temp);
    this.color.setHSL(h, s, l);
  }
  get s() { return this.color.getHSL(this.temp).s; }
  set s(s) {
    const {h, l} = this.color.getHSL(this.temp);
    this.color.setHSL(h, s, l);
  }
  get l() { return this.color.getHSL(this.temp).l; }
  set l(l) {
    const {h, s} = this.color.getHSL(this.temp);
    this.color.setHSL(h, s, l);
  }
}

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas});

  const fov = 75;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 5;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 2;

  const scene = new THREE.Scene();

  const boxWidth = 1;
  const boxHeight = 1;
  const boxDepth = 1;
  const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);

  const material1 = new THREE.MeshBasicMaterial({color: 0xFF0000});
  const material2 = new THREE.MeshBasicMaterial({color: 0xFF0000});

  const cube1 = new THREE.Mesh(geometry, material1);
  scene.add(cube1);
  cube1.position.x = -1;
  const cube2 = new THREE.Mesh(geometry, material2);
  scene.add(cube2);
  cube2.position.x = 1;


  const helper1 = new HSLHelper(material1.color);
  const tl1 = new TimelineMax();
  tl1.fromTo(helper1, {h: 0, s: 1, l: 0.5}, {duration: 5, h: 1, s: 1, l: 0.5, ease:Linear.easeNone});
  tl1.repeat(-1);
  
  const helper2 = new HSLHelper(material2.color);
  const tl2 = new TimelineMax();
  tl2.fromTo(helper2, {h: 0, s: 1, l: 0.5}, {duration: 5, h: 10, s: 1, l: 0.5, ease:Linear.easeNone});
  tl2.repeat(-1);
  
  function render() {
    renderer.render(scene, camera);
    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);
}

main();
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r113/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.0.1/dist/gsap.min.js"></script>
<canvas id="c"></canvas>
0 голосов
/ 27 февраля 2020

Хотя и Маркиззо, и Гман движутся в правильном направлении, на самом деле в GSAP все еще проще! Вы можете просто анимировать .color к установленным вами значениям (проще всего использовать новый объект THREE.Color). Например:

// The new colors in whatever format you want
const newColor1 = new THREE.Color("hsl(120, 100%, 50%)");
const newColor2 = new THREE.Color("blue");

const tl1 = gsap.timeline({repeat: -1});
tl1.to(material1.color, {duration: 5, r: newColor1.r, g: newColor1.g, b: newColor1.b, ease:"none"});

const tl2 = gsap.timeline({repeat: -1});
tl2.to(material2.color, {duration: 5, r: newColor2.r, g: newColor2.g, b: newColor2.b, ease:"none"});

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas});

  const fov = 75;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 5;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 2;

  const scene = new THREE.Scene();

  const boxWidth = 1;
  const boxHeight = 1;
  const boxDepth = 1;
  const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);

  const material1 = new THREE.MeshBasicMaterial({color: 0xFF0000});
  const material2 = new THREE.MeshBasicMaterial({color: 0xFF0000});

  const cube1 = new THREE.Mesh(geometry, material1);
  scene.add(cube1);
  cube1.position.x = -1;
  const cube2 = new THREE.Mesh(geometry, material2);
  scene.add(cube2);
  cube2.position.x = 1;


  // The new colors in whatever format you want
  const newColor1 = new THREE.Color("hsl(120, 100%, 50%)");
  const newColor2 = new THREE.Color("blue");

  const tl1 = gsap.timeline({repeat: -1});
  tl1.to(material1.color, {duration: 5, r: newColor1.r, g: newColor1.g, b: newColor1.b, ease:"none"});
  
  const tl2 = gsap.timeline({repeat: -1});
  tl2.to(material2.color, {duration: 5, r: newColor2.r, g: newColor2.g, b: newColor2.b, ease:"none"});
  
  function render() {
    renderer.render(scene, camera);
    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);
}

main();
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r113/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.2.1/dist/gsap.min.js"></script>
<canvas id="c"></canvas>
...