首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么css变量动画不能在web组件中工作?

为什么css变量动画不能在web组件中工作?
EN

Stack Overflow用户
提问于 2022-06-21 18:39:49
回答 1查看 74关注 0票数 1

我已经使用实验性的@property特性成功地创建了一个css变量动画。

重要事项:这仅适用于Chrome、Opera或边缘兼容性表

代码语言:javascript
复制
document.addEventListener('DOMContentLoaded', () => {
  const rangeInput = document.querySelector('#scale');
  const htmlElement = document.querySelector('#html-element');
  rangeInput.addEventListener('change', (e) => {
    htmlElement.style.setProperty(
      '--html-element-scale',
      (e.target.value / 100).toFixed(2)
    );
  });
});
代码语言:javascript
复制
@property --html-element-background-color {
  syntax: '<color>';
  inherits: false;
  initial-value: #00ff00;
}

@property --html-element-rotate {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

@property --html-element-scale {
  syntax: '<number>';
  inherits: false;
  initial-value: 1;
}

#html-element {
  transform: rotate(var(--html-element-rotate))
    scale(var(--html-element-scale));

  border: 1px solid #000;
  height: 100px;
  width: 100px;
  background-color: var(--html-element-background-color);
  animation: anim 1s ease-in infinite alternate;
}

@keyframes anim {
  100% {
    --html-element-rotate: 180deg;
    --html-element-background-color: #ff00ff;
  }
}
代码语言:javascript
复制
<div id="html-element">HTML Element</div>

<div id="range-container">
  <input
    type="range"
    id="scale"
    name="scale"
    min="0"
    max="100"
    value="100"
  />
  <label for="scale">Scale</label>
</div>

但是当将它包装到web组件中时,只有css值会被更改,但是css var的值不会被动画化。此外,旋转不起作用,除非您更改缩放滑块或将:host {--html-element-scale: 1}作为默认值.这很奇怪。

代码语言:javascript
复制
const html = `
<style>
  @property --web-component-background-color {
    syntax: '<color>';
    inherits: false;
    initial-value: #00ff00;
  }

  @property --web-component-rotate {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
  }

  @property --web-component-scale {
    syntax: '<number>';
    inherits: false;
    initial-value: 1;
  }

  #web-component {
    transform: scale(var(--web-component-scale)) rotate(var(--web-component-rotate));

    border: 1px solid #000;
    height: 100px;
    width: 100px;
    background-color: var(--web-component-background-color);
    animation: anim 1s ease-in infinite alternate;
  }

  @keyframes anim {
    100% {
      --web-component-rotate: 180deg;
      --web-component-background-color: #ff00ff;
    }
  }
</style>

<div id="web-component">Web Component</div>
<div id="range-container">
  <input type="range" id="scale" name="scale" min="0" max="100" value="100" />
  <label for="scale">Scale</label>
</div>`;

customElements.define(
  'web-component',
  class WebComponent extends HTMLElement {
    shadowRoot = this.attachShadow({ mode: 'open' });
    constructor() {
      super();
      let template = document.createElement('template');
      template.innerHTML = html;
      this.shadowRoot.appendChild(template.content.cloneNode(true));
    }
    connectedCallback() {
      const rangeInput = this.shadowRoot.querySelector('#scale');
      const webComponent = this.shadowRoot.querySelector('#web-component');
      rangeInput.addEventListener('change', (e) => {
        webComponent.style.setProperty(
          '--web-component-scale',
          (e.target.value / 100).toFixed(2)
        );
      });
    }
  }
);
代码语言:javascript
复制
<web-component></web-component>

最后但并非最不重要的一点是,如果您将样式表从web组件复制到常规的dom中,那么web组件继承了css,它将再次工作。

问题是,这是由于该特性的实验阶段造成的错误,还是我在web组件中实现它时做错了什么?

EN

回答 1

Stack Overflow用户

发布于 2022-06-21 21:29:30

看起来,@property定义在web组件中不起作用。我不确定这是有意还是错误,我会把它作为一个问题向项目报告。

但是,如果您只想在动画中使用全局定义的css变量(这在web组件的用例中是非常有限的),那么如果您对工作版本感兴趣的话。

代码语言:javascript
复制
const html = `
<style>
  #web-component {
    transform: rotate(var(--html-element-rotate))
      scale(var(--html-element-scale));
    border: 1px solid #000;
    height: 100px;
    width: 100px;
    background-color: var(--html-element-background-color);
    animation: anim 1s ease-in infinite alternate;
  }

  @keyframes anim {
    100% {
      --html-element-rotate: -180deg;
      --html-element-background-color: #0000ff;
    }
  }
</style>

<div id="web-component">Web Component</div>
<div id="range-container">
  <input type="range" id="scale" name="scale" min="0" max="100" value="100" />
  <label for="scale">Scale</label>
</div>`;

document.addEventListener('DOMContentLoaded', () => {
  const rangeInput = document.querySelector('#scale');
  const htmlElement = document.querySelector('#html-element');
  rangeInput.addEventListener('change', (e) => {
    htmlElement.style.setProperty(
      '--html-element-scale',
      (e.target.value / 100).toFixed(2)
    );
  });
});


customElements.define(
  'web-component',
  class WebComponent extends HTMLElement {
    shadowRoot = this.attachShadow({ mode: 'open' });
    constructor() {
      super();
      let template = document.createElement('template');
      template.innerHTML = html;
      this.shadowRoot.appendChild(template.content.cloneNode(true));
    }
    connectedCallback() {
      const rangeInput = this.shadowRoot.querySelector('#scale');
      const webComponent = this.shadowRoot.querySelector('#web-component');
      rangeInput.addEventListener('change', (e) => {
        webComponent.style.setProperty(
          '--html-element-scale',
          (e.target.value / 100).toFixed(2)
        );
      });
    }
  }
);
代码语言:javascript
复制
@property --html-element-background-color {
  syntax: '<color>';
  inherits: false;
  initial-value: #00ff00;
}

@property --html-element-rotate {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

@property --html-element-scale {
  syntax: '<number>';
  inherits: false;
  initial-value: 1;
}

#html-element {
  transform: rotate(var(--html-element-rotate))
    scale(var(--html-element-scale));
  border: 1px solid #000;
  height: 100px;
  width: 100px;
  background-color: var(--html-element-background-color);
  animation: anim 1s ease-in infinite alternate;
}

@keyframes anim {
  100% {
    --html-element-rotate: 180deg;
    --html-element-background-color: #ff00ff;
  }
}
代码语言:javascript
复制
<web-component></web-component>


<div id="html-element">HTML Element</div>

<div id="range-container">
  <input
    type="range"
    id="scale"
    name="scale"
    min="0"
    max="100"
    value="100"
  />
  <label for="scale">Scale</label>
</div>

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72705688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档