anime icon indicating copy to clipboard operation
anime copied to clipboard

Add support for CSS custom property

Open buckle2000 opened this issue 7 years ago • 10 comments

Currently, there is no way I can animate CSS custom property with anime.js.

div {
  --progress: 100%;
  transform: scale(var(--progress));
}

You can use this to set CSS custom property:

el.style.setProperty('--progress', '40%')

buckle2000 avatar Nov 14 '18 03:11 buckle2000

Anyone?

buckle2000 avatar Dec 06 '18 03:12 buckle2000

Interesting idea, will look a the feasibility later.

juliangarnier avatar Jan 09 '19 13:01 juliangarnier

In theory it's possible. You can do it with plain CSS transitions, and Greensock supports this in a similar API: https://greensock.com/css-variables

Note: it's common to define vars in the pseudoclass :root. A working example should look something like this.

:root {
  --main-bg-color: #ff00ff;
}
.elem {
  background-color: var(--main-bg-color);
}
anime({
  targets: ':root',
  '--var': '#ff00ff'
});

It would also be nice to have documentation about how to do something like this, if it's possible at all.

anime({
  targets: '.elem',
  backgroundColor: ["var(--active-color)","var(--inactive-color)"]
});

VulumeCode avatar Jan 16 '19 16:01 VulumeCode

has anyone found a workaround for this feature?

nonlinearcom avatar Nov 04 '19 10:11 nonlinearcom

Hi,

I was just searching for this very thing and I came across this post, I this this would be an awesome feature.
I am using Anime in my app and it works really well.

Note: it's common to define vars in the pseudoclass :root.

Vars can be defined in any element, I am using mine in SVG to set the fill colour, I have frame and I want to animate from one colour to the next. eg:

anime({
  targets: 'svg path',
  '--fill-colour': [
    { value: 'blue', duration: 1000, delay: 500 },
    { value: 'red', duration: 1000, delay: 500 }
  ],
  easing: 'easeOutElastic(1, .8)',
  loop: true
});

LukeTOBrien avatar Aug 16 '20 21:08 LukeTOBrien

Hey all, I happened to need this feature too, and set up a helper function to sync values set by anime to a target element:

const getCssVarProxy = (targetElement, ...varNames) => {
  // Declare object to proxy
  let proxyTarget = { };
  
  // Capture initial values
  varNames.forEach(varName => proxyTarget[varName] = getComputedStyle(targetElement).getPropertyValue(varName));
  
  // Create proxy to update element's CSS vars
  return new Proxy(proxyTarget, {
    set: (targetObject, property, value) => {
      targetElement.style.setProperty(property, value);
      return true;
    }
  });
};

And usage is like this:

let elementProxy = getCssVarProxy(document.querySelector('.class-name'), '--elementX', '--elementY', '--elementScale');
anime({ targets: elementProxy, duration: 1000, '--elementX': 200, '--elementY': 400, '--elementScale': 1.5 });

– where --elementX, --elementY and --elementScale are declared somewhere in the page style and referenced by the element's style rules.

I put a minimal demo up here: https://codepen.io/admvx/pen/wvrMbwN

admvx avatar Dec 07 '21 08:12 admvx

Sad that it still isn't supported. I like Anime.js over Gsap due to its minimal size. Please Julian, do something about Setproperty.

monolithMktg avatar Mar 10 '23 11:03 monolithMktg

This is coming in V4 (finishing writing tests and new documentation right now).

juliangarnier avatar Mar 14 '23 15:03 juliangarnier

This is coming in V4 (finishing writing tests and new documentation right now).

Yessss! I always prefer Anime over GSAP. I find it more user-friendly and light. And I seriously hope you can keep Anime.js growing by expanding its capabilities and keeping size to a minimum. :D

monolithMktg avatar Mar 14 '23 20:03 monolithMktg

Personally, I found this set up to be the easiest, pre-4.0.0:

const header = headerRef.current

const variables = {
  twBgOpacity: '100%',
}

anime({
  targets: variables,
  twBgOpacity: ['100%', '0%'],
  easing: 'easeOutQuad',
  duration: 200,
  update: () => {
    header.style.setProperty('--tw-bg-opacity', variables.twBgOpacity)
  },
})

I'm using React and Tailwind CSS. Without React, header variable should be const header = document.querySelector('header') in my case.

I'm not sure if this is helpful to anyone, but I figured I'd put it here, since just in case.

andrilla-francis avatar Sep 18 '23 16:09 andrilla-francis