@ Ответ Маркиззо работает, но если вы действительно хотите использовать анимацию 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>