Skip to content

Commit

Permalink
Also consider non stylistic attribute valid parameters on SVG targets #…
Browse files Browse the repository at this point in the history
  • Loading branch information
juliangarnier committed Aug 19, 2022
1 parent c54041a commit ca71829
Show file tree
Hide file tree
Showing 11 changed files with 343 additions and 26 deletions.
10 changes: 6 additions & 4 deletions documentation/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ <h3 class="demo-title">SVG Attributes</h3>
<div class="demo-content align-center svg-attributes-demo">
<svg width="128" height="128" viewBox="0 0 128 128">
<filter id="displacementFilter">
<feTurbulence type="turbulence" baseFrequency=".05" numOctaves="2" result="turbulence"/>
<feTurbulence type="turbulence" numOctaves="2" baseFrequency="0" result="turbulence"/>
<feDisplacementMap in2="turbulence" in="SourceGraphic" scale="15" xChannelSelector="R" yChannelSelector="G"/>
</filter>
<polygon points="64 68.64 8.574 100 63.446 67.68 64 4 64.554 67.68 119.426 100" style="filter: url(#displacementFilter)" fill="currentColor"/>
Expand All @@ -481,9 +481,11 @@ <h3 class="demo-title">SVG Attributes</h3>
var polyEl = document.querySelector('.svg-attributes-demo polygon');
var feTurbulenceEl = document.querySelector('feTurbulence');
var feDisplacementMap = document.querySelector('feDisplacementMap');
polyEl.setAttribute('points', '64 68.64 8.574 100 63.446 67.68 64 4 64.554 67.68 119.426 100');
feTurbulenceEl.setAttribute('baseFrequency', '.05');
feDisplacementMap.setAttribute('scale', '15');
// anime.set('.svg-attributes-demo polygon', { points: '64 68.64 8.574 100 63.446 67.68 64 4 64.554 67.68 119.426 100' });
// anime.set('feTurbulence', { baseFrequency: '64 68.64 8.574 100 63.446 67.68 64 4 64.554 67.68 119.426 100' });
// anime.set('feDisplacementMap', { scale: '15' });
console.log(polyEl.getAttribute('scale'), 'scale' in polyEl.style);
console.log(feTurbulenceEl.getAttribute('baseFrequency'), 'baseFrequency' in polyEl.style);
/*DEMO*/
anime({
targets: ['.svg-attributes-demo polygon', 'feTurbulence', 'feDisplacementMap'],
Expand Down
2 changes: 1 addition & 1 deletion lib/anime.es5.js
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ var anime = (function () {
if (is.obj(el)) {
return animationTypes.OBJECT;
} else if (is.dom(el)) {
if (!is.nil(el.getAttribute(prop)) || is.svg(el) && prop in el.style) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes
if (!is.nil(el.getAttribute(prop)) || is.svg(el) && (prop in el.style || prop in el)) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes
// if (!is.nil(el.getAttribute(prop))) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes

if (arrayContains(validTransforms, prop)) return animationTypes.TRANSFORM; // Handle CSS Transform properties differently than CSS to allow individual animations
Expand Down
2 changes: 1 addition & 1 deletion lib/anime.es5.min.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions lib/anime.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,10 +446,10 @@ function convertValueUnit(el, decomposedValue, unit) {

function sanitizePropertyName(propertyName, targetEl, animationType) {
if (
(animationType === animationTypes.CSS) ||
animationType === animationTypes.CSS ||
// Handle special cases where properties like "strokeDashoffset" needs to be set as "stroke-dashoffset"
// but properties like "baseFrequency" should stay in lowerCamelCase
(animationType === animationTypes.ATTRIBUTE && (is.svg(targetEl) && (propertyName in targetEl.style)))
(animationType === animationTypes.ATTRIBUTE && (is.svg(targetEl) && propertyName in targetEl.style))
) {
const cachedPropertyName = cache.propertyNames[propertyName];
if (cachedPropertyName) {
Expand Down Expand Up @@ -789,7 +789,7 @@ function getAnimationType(el, prop) {
if (is.obj(el)) {
return animationTypes.OBJECT;
} else if (is.dom(el)) {
if (!is.nil(el.getAttribute(prop)) || (is.svg(el) && prop in el.style)) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes
if (!is.nil(el.getAttribute(prop)) || (is.svg(el) && (prop in el.style || prop in el))) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes
// if (!is.nil(el.getAttribute(prop))) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes
if (arrayContains(validTransforms, prop)) return animationTypes.TRANSFORM; // Handle CSS Transform properties differently than CSS to allow individual animations
if (prop in el.style) return animationTypes.CSS; // All other CSS properties
Expand Down
6 changes: 3 additions & 3 deletions lib/anime.umd.js
Original file line number Diff line number Diff line change
Expand Up @@ -452,10 +452,10 @@

function sanitizePropertyName(propertyName, targetEl, animationType) {
if (
(animationType === animationTypes.CSS) ||
animationType === animationTypes.CSS ||
// Handle special cases where properties like "strokeDashoffset" needs to be set as "stroke-dashoffset"
// but properties like "baseFrequency" should stay in lowerCamelCase
(animationType === animationTypes.ATTRIBUTE && (is.svg(targetEl) && (propertyName in targetEl.style)))
(animationType === animationTypes.ATTRIBUTE && (is.svg(targetEl) && propertyName in targetEl.style))
) {
const cachedPropertyName = cache.propertyNames[propertyName];
if (cachedPropertyName) {
Expand Down Expand Up @@ -795,7 +795,7 @@
if (is.obj(el)) {
return animationTypes.OBJECT;
} else if (is.dom(el)) {
if (!is.nil(el.getAttribute(prop)) || (is.svg(el) && prop in el.style)) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes
if (!is.nil(el.getAttribute(prop)) || (is.svg(el) && (prop in el.style || prop in el))) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes
// if (!is.nil(el.getAttribute(prop))) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes
if (arrayContains(validTransforms, prop)) return animationTypes.TRANSFORM; // Handle CSS Transform properties differently than CSS to allow individual animations
if (prop in el.style) return animationTypes.CSS; // All other CSS properties
Expand Down
4 changes: 2 additions & 2 deletions src/properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import {

export function sanitizePropertyName(propertyName, targetEl, animationType) {
if (
(animationType === animationTypes.CSS) ||
animationType === animationTypes.CSS ||
// Handle special cases where properties like "strokeDashoffset" needs to be set as "stroke-dashoffset"
// but properties like "baseFrequency" should stay in lowerCamelCase
(animationType === animationTypes.ATTRIBUTE && (is.svg(targetEl) && (propertyName in targetEl.style)))
(animationType === animationTypes.ATTRIBUTE && (is.svg(targetEl) && propertyName in targetEl.style))
) {
const cachedPropertyName = cache.propertyNames[propertyName];
if (cachedPropertyName) {
Expand Down
2 changes: 1 addition & 1 deletion src/values.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function getAnimationType(el, prop) {
if (is.obj(el)) {
return animationTypes.OBJECT;
} else if (is.dom(el)) {
if (!is.nil(el.getAttribute(prop)) || (is.svg(el) && prop in el.style)) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes
if (!is.nil(el.getAttribute(prop)) || (is.svg(el) && (prop in el.style || prop in el))) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes
// if (!is.nil(el.getAttribute(prop))) return animationTypes.ATTRIBUTE; // Handle DOM and SVG attributes
if (arrayContains(validTransforms, prop)) return animationTypes.TRANSFORM; // Handle CSS Transform properties differently than CSS to allow individual animations
if (prop in el.style) return animationTypes.CSS; // All other CSS properties
Expand Down
1 change: 0 additions & 1 deletion tests/visual/assets/js/scripts.js

This file was deleted.

45 changes: 45 additions & 0 deletions tests/visual/assets/js/tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const cBlack = 'color:#252423;'
const cWhite = 'color:#FFF;'
const cRed = 'color:#FF4B4B;'
const bgRed = cBlack+'background-color:#FF4B4B;'
const cGreen = 'color:#18FF74;'
const bgGreen = cBlack+'background-color:#18FF74;'

function log(testName, expected, received, isPassing) {
if (!isPassing) {
console.log('%c FAIL ' + '%c ' + testName, bgRed, cRed);
console.log('%c✓ ' + '%cExpected: ' + '%c' + expected, cGreen, cWhite, cGreen);
console.log('%c✕ ' + '%cReceived: ' + '%c' + received, cRed, cWhite, cRed);
} else {
console.log('%c SUCCESS ' + '%c ' + testName, bgGreen, cWhite);
}
}

export function test(testName, testFunc) {
try {
const { expected, received, isPassing } = testFunc();
log(testName, expected, received, isPassing);
} catch(e) {
console.log('%c TEST ERROR ' + '%c ' + testName, bgRed, cRed);
return console.log(e);
}
}

export function expect(value) {
return {
toBe: (expected) => {
return {
expected,
received: value,
isPassing: value === expected
}
},
toBeSuperiorTo: (expected) => {
return {
expected,
received: value,
isPassing: value > expected
}
}
}
}
74 changes: 64 additions & 10 deletions tests/visual/svg-lines.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,30 +50,84 @@
<polygon id="polygon" stroke="#D1FA9E" points="500 130.381 464.772 149 471.5 109.563 443 81.634 482.386 75.881 500 40 517.614 75.881 557 81.634 528.5 109.563 535.228 149"/>
<polyline id="polyline" stroke="#7BE6D6" points="63.053 345 43 283.815 95.5 246 148 283.815 127.947 345 63.5 345"/>
<!-- <path id="path" stroke="#4E7EFC" d="M250 300c0-27.614 22.386-50 50-50s50 22.386 50 50v50h-50c-27.614 0-50-22.386-50-50z"/> -->
<path id="path-without-d-attribute" stroke="#4E7EFC"/>
<path id="path-without-d-attribute-1" stroke="#4E7EFC"/>
<path id="path-without-d-attribute-2" stroke="#F96F82"/>
<rect id="rect" width="100" height="100" x="451" y="251" stroke="#C987FE" rx="25"/>
</g>
</svg>
</div>
<script type="module">
import anime from '../../src/anime.js';
import { test, expect } from './assets/js/tests.js';

const line1El = document.querySelector('#line1');
const line2El = document.querySelector('#line2');
const circleEl = document.querySelector('#circle');
const polygonEl = document.querySelector('#polygon');
const polylineEl = document.querySelector('#polyline');
const rectEl = document.querySelector('#rect');

const dashOffsetAnimation = anime({
targets: ['line', 'circle', 'polygon', 'polyline', 'path', 'rect'],
targets: ['line', 'circle', 'polygon', 'polyline', 'rect'],
strokeDashoffset: [anime.setDashoffset, 0],
easing: 'easeInOutSine',
duration: 1500,
direction: 'alternate',
loop: true
duration: 500,
complete: () => {
test('stroke-dasharray on line 1 element', () => {
return expect(line1.getAttribute('stroke-dasharray')).toBe('138.59292602539062');
});
test('stroke-dasharray on line 2 element', () => {
return expect(line2.getAttribute('stroke-dasharray')).toBe('138.59292602539062');
});
test('stroke-dasharray on circle element', () => {
return expect(circleEl.getAttribute('stroke-dasharray')).toBe('313.6517028808594');
});
test('stroke-dasharray on polygon element', () => {
return expect(polygonEl.getAttribute('stroke-dasharray')).toBe('399.06207275390625');
});
test('stroke-dasharray on polyline element', () => {
return expect(polylineEl.getAttribute('stroke-dasharray')).toBe('322.62371826171875');
});
test('stroke-dasharray on rect element', () => {
return expect(rectEl.getAttribute('stroke-dasharray')).toBe('356.0674743652344');
});
}
});
test('stroke-dashoffset on line 1 element', () => {
return expect(line1.getAttribute('stroke-dashoffset')).toBe('138.59292602539062');
});
test('stroke-dashoffset on line 2 element', () => {
return expect(line2.getAttribute('stroke-dashoffset')).toBe('138.59292602539062');
});
// anime.set('#path-without-d-attribute', {
// d: 'M250 300c0-27.614 22.386-50 50-50s50 22.386 50 50v50h-50c-27.614 0-50-22.386-50-50z',
// })
test('stroke-dashoffset on circle element', () => {
return expect(circleEl.getAttribute('stroke-dashoffset')).toBe('313.6517028808594');
});
test('stroke-dashoffset on polygon element', () => {
return expect(polygonEl.getAttribute('stroke-dashoffset')).toBe('399.06207275390625');
});
test('stroke-dashoffset on polyline element', () => {
return expect(polylineEl.getAttribute('stroke-dashoffset')).toBe('322.62371826171875');
});
test('stroke-dashoffset on rect element', () => {
return expect(rectEl.getAttribute('stroke-dashoffset')).toBe('356.0674743652344');
});
anime.set('#path-without-d-attribute-1', {
d: 'M250 300c0-27.614 22.386-50 50-50s50 22.386 50 50v50h-50c-27.614 0-50-22.386-50-50z',
})
const animateNonExistantAttribute = anime({
targets: '#path-without-d-attribute',
targets: '#path-without-d-attribute-2',
d: 'M250 300c0-27.614 22.386-50 50-50s50 22.386 50 50v50h-50c-27.614 0-50-22.386-50-50z',
easing: 'easeInOutQuad',
complete: () => {
const pathEl = anime.path('#path-without-d-attribute');
const pathEl = anime.path('#path-without-d-attribute-2');
const dashOffsetAnimation = anime({
targets: '#path-without-d-attribute-2',
strokeDashoffset: [anime.setDashoffset, 0],
easing: 'easeInOutSine',
duration: 1500,
direction: 'alternate',
loop: true
});
const pathAnimation = anime({
targets: '.item',
translateX: pathEl('x'),
Expand Down
Loading

0 comments on commit ca71829

Please sign in to comment.