To feed the data to a function correctly, I need to swap two axes in a four-dimensional array in Swift. I'd like to know how to implement or are there any useful function for this purpose.
In Python, if I use numpy.swapaxes(a, axis1, axis2), it's straightforward (https://docs.scipy.org/doc/numpy/reference/generated/numpy.swapaxes.html):
def swapaxes_from_tail_to_head(nparray):
nparray = np.swapaxes(nparray, 2, 3)
nparray = np.swapaxes(nparray, 1, 2)
nparray = np.swapaxes(nparray, 0, 1)
return nparray
Just note that if the array is two-dimensional, I can do like this:
func prettyPrintMatrix( _ matrix:[[Int]] ) {
for array in matrix {
print( array )
}
}
func main() -> (){
print( "MatrixTranspose_Demo" )
print()
let matrix =
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
]
print( "Matrix:")
prettyPrintMatrix( matrix )
print()
let transpose = transposeMatrix( matrix )
print( "Transpose matrix:")
prettyPrintMatrix( transpose )
print()
}
func transposeMatrix( _ matrix:[[Int]] ) -> [[Int]] {
var result = [[Int]](
repeating: [Int]( repeating: 0, count: matrix.count ),
count: matrix[ 0 ].count
)
for i in 0 ..< matrix.count {
for k in 0 ..< matrix[ 0 ].count {
result[ k ][ i ] = matrix[ i ][ k ]
}
}
return result
}
main()
// Reference: http://www.runswiftlang.com/
If you have any ideas how to do swapaxes for four-dimentional (or more) array, please let me know. I appreciate your help.
The simplest way is to hard code everything like the followings:
internal func swapaxesOfFlatArray4d<T>(originalArray: [T], axis1: Int, axis2: Int, dimensionOfArray: [Int]) -> [T] {
assert(axis1 != axis2)
assert(dimensionOfArray.count == 4)
assert(axis1 < dimensionOfArray.count)
assert(axis2 < dimensionOfArray.count)
assert(originalArray.count == dimensionOfArray.reduce(1, *))
assert((T.self == Float.self) || (T.self == Double.self))
var newArray = Array<T>()
if ((axis1 == 0 && axis2 == 1) || (axis1 == 1 && axis2 == 0)) {
for j in 0..<dimensionOfArray[1] {
for i in 0..<dimensionOfArray[0] {
for k in 0..<dimensionOfArray[2] {
for l in 0..<dimensionOfArray[3] {
newArray.append(originalArray[i*dimensionOfArray[1]*dimensionOfArray[2]*dimensionOfArray[3] + j*dimensionOfArray[2]*dimensionOfArray[3] + k*dimensionOfArray[3] + l])
}
}
}
}
} else if ((axis1 == 0 && axis2 == 2) || (axis1 == 2 && axis2 == 0)) {
for k in 0..<dimensionOfArray[2] {
for j in 0..<dimensionOfArray[1] {
for i in 0..<dimensionOfArray[0] {
for l in 0..<dimensionOfArray[3] {
newArray.append(originalArray[i*dimensionOfArray[1]*dimensionOfArray[2]*dimensionOfArray[3] + j*dimensionOfArray[2]*dimensionOfArray[3] + k*dimensionOfArray[3] + l])
}
}
}
}
} else if ((axis1 == 0 && axis2 == 3) || (axis1 == 3 && axis2 == 0)) {
for l in 0..<dimensionOfArray[3] {
for j in 0..<dimensionOfArray[1] {
for k in 0..<dimensionOfArray[2] {
for i in 0..<dimensionOfArray[0] {
newArray.append(originalArray[i*dimensionOfArray[1]*dimensionOfArray[2]*dimensionOfArray[3] + j*dimensionOfArray[2]*dimensionOfArray[3] + k*dimensionOfArray[3] + l])
}
}
}
}
} else if ((axis1 == 1 && axis2 == 2) || (axis1 == 2 && axis2 == 1)) {
for i in 0..<dimensionOfArray[0] {
for k in 0..<dimensionOfArray[2] {
for j in 0..<dimensionOfArray[1] {
for l in 0..<dimensionOfArray[3] {
newArray.append(originalArray[i*dimensionOfArray[1]*dimensionOfArray[2]*dimensionOfArray[3] + j*dimensionOfArray[2]*dimensionOfArray[3] + k*dimensionOfArray[3] + l])
}
}
}
}
} else if ((axis1 == 1 && axis2 == 3) || (axis1 == 3 && axis2 == 1)) {
for i in 0..<dimensionOfArray[0] {
for l in 0..<dimensionOfArray[3] {
for k in 0..<dimensionOfArray[2] {
for j in 0..<dimensionOfArray[1] {
newArray.append(originalArray[i*dimensionOfArray[1]*dimensionOfArray[2]*dimensionOfArray[3] + j*dimensionOfArray[2]*dimensionOfArray[3] + k*dimensionOfArray[3] + l])
}
}
}
}
} else if ((axis1 == 2 && axis2 == 3) || (axis1 == 3 && axis2 == 2)) {
for i in 0..<dimensionOfArray[0] {
for j in 0..<dimensionOfArray[1] {
for l in 0..<dimensionOfArray[3] {
for k in 0..<dimensionOfArray[2] {
newArray.append(originalArray[i*dimensionOfArray[1]*dimensionOfArray[2]*dimensionOfArray[3] + j*dimensionOfArray[2]*dimensionOfArray[3] + k*dimensionOfArray[3] + l])
}
}
}
}
} else {
fatalError("Didn't match all the case")
}
return newArray
}
To decrease the amount of the code, you can a class to change the order of for loops.
Change order of for loops?
It is fairly easy to make a transpose function for a 2d matrix:
func transpose<T>(_ matrix:[[T]]) -> [[T]]
{
return matrix.reduce([[T]]())
{
zip($0,$1).map{$0+[$1]}
+ $0.dropFirst($1.count)
+ $1.dropFirst($0.count).map{[$0]}
}
}
Once you have that, all other transpositions of any dimensions can be converted to a series of 2d transposes on consecutive dimensions (essentially swapping them)
let array12 = (1...4).map{ n in (1...4).map{n*10 + $0} }
let array123 = (1...4).map{ n in array12.map{ $0.map{ n*100 + $0 } } }
let array1234 = (1...4).map{ n in array123.map{ $0.map{ $0.map{ n*1000 + $0 } } } }
let array2134 = transpose(array1234) // swap dimensions 1 and 2
let array1324 = array1234.map{transpose($0)} // swap dimensions 2 and 3
let array1243 = array1234.map{$0.map{transpose($0)}} // swap dimensions 3 and 4
Reusing these 3 basic dimension swaps, all other combinations of the 4 dimensions are possible.
let array2143 = array2134.map{$0.map{transpose($0)}}
let array2413 = array2143.map{transpose($0)}
let array4213 = transpose(array2413)
let array4231 = array4213.map{$0.map{transpose($0)}}
let array4321 = array4231.map{transpose($0)}
// and so on ...
To help test this, I made a 4d print function for the matrix that I used in the playground:
It prints in row column order so you get dimension one as a vertical group of "blocks", dimension 2 as a column of blocks, dimension 3 is rows of each block and dimension 4 is the columns of each block:
func print4d<T>(_ matrix4d:[[[[T]]]])
{
var lines:[String] = []
for d1 in matrix4d
{
lines = []
for (indent,d2) in d1.enumerated()
{
let indentWidth = indent * 80
var lineNumber = 0
let blankLine = "".padding(toLength:indentWidth, withPad:" ", startingAt:0)
for d34 in d2
{
while lines.count <= lineNumber
{ lines.append(blankLine) }
lines[lineNumber] = lines[lineNumber]
.padding(toLength:indentWidth, withPad:" ", startingAt:0)
+ " \(d34)"
lineNumber += 1
}
for index in lines.indices
{
while lines[index].contains(" ")
{ lines[index] = lines[index].replacingOccurrences(of: " ", with: " ") }
}
}
lines.forEach{ print($0) }
print("")
}
}
4d matrix : d1, d2, d3, d4
===========================
[1111, 1112, 1113, 1114] [1211, 1212, 1213, 1214] [1311, 1312, 1313, 1314] [1411, 1412, 1413, 1414]
[1121, 1122, 1123, 1124] [1221, 1222, 1223, 1224] [1321, 1322, 1323, 1324] [1421, 1422, 1423, 1424]
[1131, 1132, 1133, 1134] [1231, 1232, 1233, 1234] [1331, 1332, 1333, 1334] [1431, 1432, 1433, 1434]
[1141, 1142, 1143, 1144] [1241, 1242, 1243, 1244] [1341, 1342, 1343, 1344] [1441, 1442, 1443, 1444]
[2111, 2112, 2113, 2114] [2211, 2212, 2213, 2214] [2311, 2312, 2313, 2314] [2411, 2412, 2413, 2414]
[2121, 2122, 2123, 2124] [2221, 2222, 2223, 2224] [2321, 2322, 2323, 2324] [2421, 2422, 2423, 2424]
[2131, 2132, 2133, 2134] [2231, 2232, 2233, 2234] [2331, 2332, 2333, 2334] [2431, 2432, 2433, 2434]
[2141, 2142, 2143, 2144] [2241, 2242, 2243, 2244] [2341, 2342, 2343, 2344] [2441, 2442, 2443, 2444]
[3111, 3112, 3113, 3114] [3211, 3212, 3213, 3214] [3311, 3312, 3313, 3314] [3411, 3412, 3413, 3414]
[3121, 3122, 3123, 3124] [3221, 3222, 3223, 3224] [3321, 3322, 3323, 3324] [3421, 3422, 3423, 3424]
[3131, 3132, 3133, 3134] [3231, 3232, 3233, 3234] [3331, 3332, 3333, 3334] [3431, 3432, 3433, 3434]
[3141, 3142, 3143, 3144] [3241, 3242, 3243, 3244] [3341, 3342, 3343, 3344] [3441, 3442, 3443, 3444]
[4111, 4112, 4113, 4114] [4211, 4212, 4213, 4214] [4311, 4312, 4313, 4314] [4411, 4412, 4413, 4414]
[4121, 4122, 4123, 4124] [4221, 4222, 4223, 4224] [4321, 4322, 4323, 4324] [4421, 4422, 4423, 4424]
[4131, 4132, 4133, 4134] [4231, 4232, 4233, 4234] [4331, 4332, 4333, 4334] [4431, 4432, 4433, 4434]
[4141, 4142, 4143, 4144] [4241, 4242, 4243, 4244] [4341, 4342, 4343, 4344] [4441, 4442, 4443, 4444]
4d matrix : d2, d1, d3, d4
===========================
[1111, 1112, 1113, 1114] [2111, 2112, 2113, 2114] [3111, 3112, 3113, 3114] [4111, 4112, 4113, 4114]
[1121, 1122, 1123, 1124] [2121, 2122, 2123, 2124] [3121, 3122, 3123, 3124] [4121, 4122, 4123, 4124]
[1131, 1132, 1133, 1134] [2131, 2132, 2133, 2134] [3131, 3132, 3133, 3134] [4131, 4132, 4133, 4134]
[1141, 1142, 1143, 1144] [2141, 2142, 2143, 2144] [3141, 3142, 3143, 3144] [4141, 4142, 4143, 4144]
[1211, 1212, 1213, 1214] [2211, 2212, 2213, 2214] [3211, 3212, 3213, 3214] [4211, 4212, 4213, 4214]
[1221, 1222, 1223, 1224] [2221, 2222, 2223, 2224] [3221, 3222, 3223, 3224] [4221, 4222, 4223, 4224]
[1231, 1232, 1233, 1234] [2231, 2232, 2233, 2234] [3231, 3232, 3233, 3234] [4231, 4232, 4233, 4234]
[1241, 1242, 1243, 1244] [2241, 2242, 2243, 2244] [3241, 3242, 3243, 3244] [4241, 4242, 4243, 4244]
[1311, 1312, 1313, 1314] [2311, 2312, 2313, 2314] [3311, 3312, 3313, 3314] [4311, 4312, 4313, 4314]
[1321, 1322, 1323, 1324] [2321, 2322, 2323, 2324] [3321, 3322, 3323, 3324] [4321, 4322, 4323, 4324]
[1331, 1332, 1333, 1334] [2331, 2332, 2333, 2334] [3331, 3332, 3333, 3334] [4331, 4332, 4333, 4334]
[1341, 1342, 1343, 1344] [2341, 2342, 2343, 2344] [3341, 3342, 3343, 3344] [4341, 4342, 4343, 4344]
[1411, 1412, 1413, 1414] [2411, 2412, 2413, 2414] [3411, 3412, 3413, 3414] [4411, 4412, 4413, 4414]
[1421, 1422, 1423, 1424] [2421, 2422, 2423, 2424] [3421, 3422, 3423, 3424] [4421, 4422, 4423, 4424]
[1431, 1432, 1433, 1434] [2431, 2432, 2433, 2434] [3431, 3432, 3433, 3434] [4431, 4432, 4433, 4434]
[1441, 1442, 1443, 1444] [2441, 2442, 2443, 2444] [3441, 3442, 3443, 3444] [4441, 4442, 4443, 4444]
4d matrix : d1, d2, d4, d3
===========================
[1111, 1121, 1131, 1141] [2111, 2121, 2131, 2141] [3111, 3121, 3131, 3141] [4111, 4121, 4131, 4141]
[1112, 1122, 1132, 1142] [2112, 2122, 2132, 2142] [3112, 3122, 3132, 3142] [4112, 4122, 4132, 4142]
[1113, 1123, 1133, 1143] [2113, 2123, 2133, 2143] [3113, 3123, 3133, 3143] [4113, 4123, 4133, 4143]
[1114, 1124, 1134, 1144] [2114, 2124, 2134, 2144] [3114, 3124, 3134, 3144] [4114, 4124, 4134, 4144]
[1211, 1221, 1231, 1241] [2211, 2221, 2231, 2241] [3211, 3221, 3231, 3241] [4211, 4221, 4231, 4241]
[1212, 1222, 1232, 1242] [2212, 2222, 2232, 2242] [3212, 3222, 3232, 3242] [4212, 4222, 4232, 4242]
[1213, 1223, 1233, 1243] [2213, 2223, 2233, 2243] [3213, 3223, 3233, 3243] [4213, 4223, 4233, 4243]
[1214, 1224, 1234, 1244] [2214, 2224, 2234, 2244] [3214, 3224, 3234, 3244] [4214, 4224, 4234, 4244]
[1311, 1321, 1331, 1341] [2311, 2321, 2331, 2341] [3311, 3321, 3331, 3341] [4311, 4321, 4331, 4341]
[1312, 1322, 1332, 1342] [2312, 2322, 2332, 2342] [3312, 3322, 3332, 3342] [4312, 4322, 4332, 4342]
[1313, 1323, 1333, 1343] [2313, 2323, 2333, 2343] [3313, 3323, 3333, 3343] [4313, 4323, 4333, 4343]
[1314, 1324, 1334, 1344] [2314, 2324, 2334, 2344] [3314, 3324, 3334, 3344] [4314, 4324, 4334, 4344]
[1411, 1421, 1431, 1441] [2411, 2421, 2431, 2441] [3411, 3421, 3431, 3441] [4411, 4421, 4431, 4441]
[1412, 1422, 1432, 1442] [2412, 2422, 2432, 2442] [3412, 3422, 3432, 3442] [4412, 4422, 4432, 4442]
[1413, 1423, 1433, 1443] [2413, 2423, 2433, 2443] [3413, 3423, 3433, 3443] [4413, 4423, 4433, 4443]
[1414, 1424, 1434, 1444] [2414, 2424, 2434, 2444] [3414, 3424, 3434, 3444] [4414, 4424, 4434, 4444]
4d matrix : d1, d3, d2, d4
===========================
[1111, 1112, 1113, 1114] [1121, 1122, 1123, 1124] [1131, 1132, 1133, 1134] [1141, 1142, 1143, 1144]
[2111, 2112, 2113, 2114] [2121, 2122, 2123, 2124] [2131, 2132, 2133, 2134] [2141, 2142, 2143, 2144]
[3111, 3112, 3113, 3114] [3121, 3122, 3123, 3124] [3131, 3132, 3133, 3134] [3141, 3142, 3143, 3144]
[4111, 4112, 4113, 4114] [4121, 4122, 4123, 4124] [4131, 4132, 4133, 4134] [4141, 4142, 4143, 4144]
[1211, 1212, 1213, 1214] [1221, 1222, 1223, 1224] [1231, 1232, 1233, 1234] [1241, 1242, 1243, 1244]
[2211, 2212, 2213, 2214] [2221, 2222, 2223, 2224] [2231, 2232, 2233, 2234] [2241, 2242, 2243, 2244]
[3211, 3212, 3213, 3214] [3221, 3222, 3223, 3224] [3231, 3232, 3233, 3234] [3241, 3242, 3243, 3244]
[4211, 4212, 4213, 4214] [4221, 4222, 4223, 4224] [4231, 4232, 4233, 4234] [4241, 4242, 4243, 4244]
[1311, 1312, 1313, 1314] [1321, 1322, 1323, 1324] [1331, 1332, 1333, 1334] [1341, 1342, 1343, 1344]
[2311, 2312, 2313, 2314] [2321, 2322, 2323, 2324] [2331, 2332, 2333, 2334] [2341, 2342, 2343, 2344]
[3311, 3312, 3313, 3314] [3321, 3322, 3323, 3324] [3331, 3332, 3333, 3334] [3341, 3342, 3343, 3344]
[4311, 4312, 4313, 4314] [4321, 4322, 4323, 4324] [4331, 4332, 4333, 4334] [4341, 4342, 4343, 4344]
[1411, 1412, 1413, 1414] [1421, 1422, 1423, 1424] [1431, 1432, 1433, 1434] [1441, 1442, 1443, 1444]
[2411, 2412, 2413, 2414] [2421, 2422, 2423, 2424] [2431, 2432, 2433, 2434] [2441, 2442, 2443, 2444]
[3411, 3412, 3413, 3414] [3421, 3422, 3423, 3424] [3431, 3432, 3433, 3434] [3441, 3442, 3443, 3444]
[4411, 4412, 4413, 4414] [4421, 4422, 4423, 4424] [4431, 4432, 4433, 4434] [4441, 4442, 4443, 4444]
4d matrix : d4, d2, d3, d1
===========================
[1111, 2111, 3111, 4111] [1211, 2211, 3211, 4211] [1311, 2311, 3311, 4311] [1411, 2411, 3411, 4411]
[1121, 2121, 3121, 4121] [1221, 2221, 3221, 4221] [1321, 2321, 3321, 4321] [1421, 2421, 3421, 4421]
[1131, 2131, 3131, 4131] [1231, 2231, 3231, 4231] [1331, 2331, 3331, 4331] [1431, 2431, 3431, 4431]
[1141, 2141, 3141, 4141] [1241, 2241, 3241, 4241] [1341, 2341, 3341, 4341] [1441, 2441, 3441, 4441]
[1112, 2112, 3112, 4112] [1212, 2212, 3212, 4212] [1312, 2312, 3312, 4312] [1412, 2412, 3412, 4412]
[1122, 2122, 3122, 4122] [1222, 2222, 3222, 4222] [1322, 2322, 3322, 4322] [1422, 2422, 3422, 4422]
[1132, 2132, 3132, 4132] [1232, 2232, 3232, 4232] [1332, 2332, 3332, 4332] [1432, 2432, 3432, 4432]
[1142, 2142, 3142, 4142] [1242, 2242, 3242, 4242] [1342, 2342, 3342, 4342] [1442, 2442, 3442, 4442]
[1113, 2113, 3113, 4113] [1213, 2213, 3213, 4213] [1313, 2313, 3313, 4313] [1413, 2413, 3413, 4413]
[1123, 2123, 3123, 4123] [1223, 2223, 3223, 4223] [1323, 2323, 3323, 4323] [1423, 2423, 3423, 4423]
[1133, 2133, 3133, 4133] [1233, 2233, 3233, 4233] [1333, 2333, 3333, 4333] [1433, 2433, 3433, 4433]
[1143, 2143, 3143, 4143] [1243, 2243, 3243, 4243] [1343, 2343, 3343, 4343] [1443, 2443, 3443, 4443]
[1114, 2114, 3114, 4114] [1214, 2214, 3214, 4214] [1314, 2314, 3314, 4314] [1414, 2414, 3414, 4414]
[1124, 2124, 3124, 4124] [1224, 2224, 3224, 4224] [1324, 2324, 3324, 4324] [1424, 2424, 3424, 4424]
[1134, 2134, 3134, 4134] [1234, 2234, 3234, 4234] [1334, 2334, 3334, 4334] [1434, 2434, 3434, 4434]
[1144, 2144, 3144, 4144] [1244, 2244, 3244, 4244] [1344, 2344, 3344, 4344] [1444, 2444, 3444, 4444]
The lack of direct support for matrix operations in Swift was bothering me so I played around with array extensions and cam up with a few methods that could probably make thing a bit easier.
extension Array
{
func asMatrix(_ axisSizes: Int ...) -> [Any] { return asMatrix(axisSizes) }
func asMatrix(_ axisSizes:[Int]) -> [Any]
{
if count == 0 { return [] }
let requiredVectorSize = axisSizes.reduce(1,*)
let flatData = asVector
var newArray:[Any] = flatData
while newArray.count < requiredVectorSize { newArray = newArray + flatData }
for axisSize in axisSizes.dropFirst().reversed()
{
newArray = (0..<newArray.count/axisSize)
.map{($0*axisSize,($0+1)*axisSize)}
.map{newArray[$0..<$1].map{$0}}
}
return newArray
}
var matrixSize:[Int]
{
get { return [count] + ((first as? [Any])?.matrixSize ?? []) }
set { self = asVector.asMatrix(newValue) as! [Element] }
}
func vectorIndex(of indexes:[Int]) -> Int
{
return zip(matrixSize,indexes).reduce(0){ $0 * $1.0 + $1.1 }
}
func matrixIndex(of vectorIndex:Int) -> [Int]
{
var result:[Int] = []
var vectorIndex = vectorIndex
for dim in matrixSize.reversed()
{
result.append(vectorIndex % dim)
vectorIndex = vectorIndex / dim
}
return result.reversed()
}
func enumeratedMatrix() -> [([Int],Any)]
{
return asVector.enumerated().map{(self.matrixIndex(of:$0),$1)}
}
var vectorSize:Int { return matrixSize.reduce(1,*) }
var asVector:[Any]
{
get { return (self as? [[Any]])?.reduce(Array<Any>()){$0+$1}.asVector ?? self}
set { self = newValue.asMatrix(matrixSize) as! [Element] }
}
subscript(indexes:[Int]) -> Any
{
get { return indexes.reduce(self as Any){ ($0 as! [Any])[$1] } }
set {
if indexes.count == 1
{
self[indexes.first!] = newValue as! Element
}
else
{
var subArray = self[indexes.first!] as! Array<Any>
let subIndexes:[Int] = indexes.dropFirst().map{$0}
subArray[subIndexes] = newValue
self[indexes.first!] = subArray as! Element
}
}
}
func transposedMatrix(_ dim1:Int=0, _ dim2:Int=1) -> [Any]
{
if dim1 == dim2 { return self }
var transposedSizes = matrixSize
swap(&transposedSizes[dim1],&transposedSizes[dim2])
var indexMap = (0..<transposedSizes.count).map{$0}
swap(&indexMap[dim1],&indexMap[dim2])
let mapping = (0..<vectorSize)
.map{($0, matrixIndex(of:$0))}
.map{(vi,mi) in (vi,indexMap.map{mi[$0]})}
.map{(vi,mi) in (vi,self.vectorIndex(of:mi)) }
var flatData = asVector
return mapping
.sorted{$0.1 < $1.1}
.map{flatData[$0.0]}
.asMatrix(transposedSizes)
}
}
The only issue remaining is that I had to use type erasure so these matrices are treated as arrays or Any and require some type casting for actual use. Nevertheless, it is easier to manipulate them:
// initialized from vectors:
//
let squareNumbers = (0..<64).map{$0}
var chessBoard = squareNumbers.asMatrix(8,8)
// swapping axes
//
let m4Dim4842 = [0].asMatrix(4,8,4,2) // 1 element vector is repeated to fill content
let m4Dim2844 = m4Dim4842.transposedMatrix(3,0) // swapped dimensions 0 and 3
// double brackets to access elements
//
let queenPos = chessBoard[[4,0]] as! Int
chessBoard[[4,0]] = queenPos
// enumeration to traverse all elements
// (and data assignment using a 1d vector)
chessBoard.asVector = chessBoard.enumeratedMatrix().map{$0.0[0]==$0.0[1] ? 1 : 0}
I can not figure out why my svg is not drawing.
I get no "real" errors on my console (The "WARNING: tween was overwritten by another" is not relevant here)
You can see the full demo here:
http://mc-communicate.com/test/svg.html
Here are the relevant codes:
SVG HTML:
<svg version="1.1" width="1095" height="299" xmlns="http://www.w3.org/2000/svg">
<path id="c" d="m102,91.8c3,-0.5 5.6,-2.5 8.7,-2.5c3.10001,0.6 3.5,4.2 4.3,6.8c-2.4,-0.7 -4.7,-1.6 -7,-2.4c-10.4,8.5 -21.4,17.3 -27.9,29.4c-4.7,8.00001 -4.1,18.9 1.7,26.00001c4.6,5.7 12.1,8 19.2,8.09999c6.8,0 13.6,-0.89999 20.2,-2.09999c8.10001,-1.5 15.8,-4.8 23.90001,-6.10001c-12.40001,9.10001 -27.7,14.10001 -43.10001,15.10001c-8.5,0.5 -17.6,-0.3 -24.8,-5.40001c-8.5,-5.59999 -12.5,-16.7 -10.89999,-26.7c1.8,-10.9 6.8,-21.3 14.39999,-29.3c2.4,-2.8 5.7,-4.5 8.9,-6.2c2.8,-1.3 4.2,-4.4 6.7,-6.1c2,0.3 3.8,1.1 5.7,1.4z" stroke-width="0.09375" stroke="#7644b6" fill="#7644b6">
</path>
<path id="o" d="m179.10001,114c17.2,-2 35.29999,-1.7 51.29999,5.6c8.8,4 15.5,12.7 16.20001,22.50001c0.2,3.2 0.79999,7.2 -1.90001,9.59999c-9.2,9.90001 -22.59999,14.60001 -35.5,17.40001c-15.39999,2.79999 -32.5,1.39999 -45.59999,-7.70001c-2.90001,-2.39999 -7,-5 -6.70001,-9.29999c0,-8.3 2.3,-17 8,-23.20001c4.70001,-5.39999 11,-8.89999 17.3,-12.2c-1,-0.89999 -2,-1.8 -3.09999,-2.7m16.29999,7.7c-5.5,0.60001 -10.29999,3.5 -15.39999,5.2c-3.8,1.2 -7.39999,2.99999 -9.89999,6.2c-3.20001,3.2 -3.8,7.59999 -4.10001,11.89999c0,2.89999 -2.60001,6.39999 0.10001,8.8c4.79999,5.09999 11.79999,8.5 18.89999,8.5c8.7,0.2 17.39999,0.09999 26.10001,-1.10001c4.79999,-0.7 9.7,-0.2 14.5,-0.8c7.29999,-1.79999 13.09999,-8.79999 13.29999,-16.39999c0.5,-6.7 -3.09999,-13.5 -8.89999,-17c-4.8,-3 -10.39999,-3.8 -15.8,-5.2c-6.2,-1.60001 -12.59999,-0.8 -18.8,-0.10001z" stroke-width="0.09375" stroke="#7644b6" fill="#7644b6">
</path>
<path id="m" d="m269.20001,156.10001c10.89999,-13.40001 13.39999,-32.2 26.79999,-43.7c1.79999,1.2 4.70001,1.9 4.60001,4.6c0.89999,8.4 1.60001,16.89999 3.79999,25.10001c6.60001,-5 8.39999,-13.40001 12.5,-20.2c2.30002,-3.9 6.39999,-6.1 10.70001,-7c0.79999,9.7 2.60001,19.9 9,27.49999c4,4.8 11.10001,7.90001 17.10001,5.3c3.79999,-1.59999 7.5,-3.59999 11.69998,-4c-1,6.2 -7.69998,8 -12.60001,10.10001c-5.89999,2.7 -12.59998,0.5 -17.69998,-2.90001c-6.70001,-4.79999 -10.70001,-12.39999 -13.80002,-19.89999c-5.39999,5.3 -6.5,13.3 -11.09998,19.10001c-2.20001,2.89999 -5.80002,4 -9.20001,4.5c-4.70001,-8.90001 -5.39999,-19.20001 -7.39999,-28.90001c-9.30002,12.5 -13.30002,27.8 -18.89999,42.10001c-1.5,2.89999 -5,3.8 -7.60001,5.39999c-4.89999,-13.3 -9.89999,-26.89999 -11,-41.09999c-0.10001,-5.10001 -0.20001,-11.40001 4.29999,-14.7c1.89999,-0.6 3.70001,1.1 4.5,2.7c1.39999,3.1 1.20001,6.6 1.30002,9.9c0,8.8 0.29999,17.7 3,26.10001z" stroke-width="0.09375" stroke="#7644b6" fill="#7644b6">
</path>
<path id="i" d="m380.10001,113c1.10001,-1.8 3.5,-0.9 4.79999,0.2c0.20001,5.3 -0.69998,10.5 -0.39999,15.8c0.5,13.39999 7,25.5 11.60001,37.8c-1.60001,0.5 -3.30002,1 -4.89999,1.5c-6.90002,-10.8 -11.80002,-22.90001 -14.10001,-35.5c-0.80002,-6.60001 -1.89999,-14.4 3,-19.8z" stroke-width="0.09375" stroke="#7644b6" fill="#7644b6">
</path>
<path id="idot" d="m380.5,78.8c2.20001,-0.3 4.70001,-1.60001 6.60001,0.1c3.79999,3 6.19998,7.3 8.89999,11.3c-4.29999,1.8 -8.10001,-1.6 -11.5,-3.7c-2.79999,-1.6 -3.29999,-4.9 -4,-7.7z" stroke-width="0.09375" stroke="#7644b6" fill="#7644b6">
</path>
<path id="n" d="m444.39999,125.3c2,0 4,0.1 6,0.1c3.39999,10.99999 6,22.2 10.5,32.8c3.70001,9.3 10.80002,17.10001 19.10001,22.8c4.70001,3.3 10.70001,3.5 16.10001,2.2c5.5,-1.09999 10.29999,-4.09999 15.39999,-6.39999c-1.10001,3.39999 -3.79999,6 -6.89999,7.7c-4,2.10001 -7.80002,5.5 -12.60001,4.8c-10.29999,-0.8 -21.29999,-3.90001 -28.29999,-12c-10.70001,-11.10001 -14.10001,-26.60001 -18.70001,-40.8c-10.5,9 -12.29999,23.89999 -22.20001,33.3c-2.19998,2.2 -4.79999,3.7 -7.5,5.09999c-1.69998,-2 -3.59998,-3.89999 -4.89999,-6.2c-0.10001,-5.8 0.70001,-11.59999 0.10001,-17.5c-0.60001,-8.3 -0.89999,-17.59999 4.79999,-24.39999c2.10001,0.89999 4.70001,1.59999 5.90002,3.8c0,4.5 -1.60001,9 -1.70001,13.59999c0,4.60001 -0.29999,9.2 -0.60001,13.90001c9.60001,-10.10001 16.80002,-22 25.5,-32.8z" stroke-width="0.09375" stroke="#7644b6" fill="#7644b6">
</path>
<path id="g" d="m524.5,125.5c8.20001,-5.1 20.90002,-3.9 26.09998,4.89999c3.20001,4.8 1.70001,10.8 0.60004,16c2.59998,-1.29999 5,-3.2 7.79999,-4.09999c1.59998,-0.10001 4,0.39999 4.20001,2.39999c1.70001,9.90001 -0.29999,20.3 3.29999,29.90001c1.40002,3.29999 -1,6.89999 0.70001,10.09999c7.09998,19.10001 17.09998,36.90001 28.09998,54c3.79999,5.3 2.40002,12.3 2.5,18.40001c0.29999,6.29999 -6,9.89999 -11.09998,11.60001c-15.79999,4.79999 -33,2.59998 -48.29999,-3.10001c-6.40002,-2.60001 -13.40002,-5.89999 -16.60004,-12.3c-3.79999,-8.2 -3,-17.8 -1.59998,-26.5c1.5,9.59999 2.70001,20.09999 9.09998,27.89999c2.10004,2.8 5.70001,3.3 8.90002,4.2c7.89996,1.89999 15.79999,3.80002 23.79999,5.20001c4.40002,0.89999 8.70001,-1.30002 12.90002,-2.20001c4.79999,-1.29999 10.39996,-2.19998 13.69995,-6.39999c1.10004,-1.2 0.5,-2.89999 0.30005,-4.3c-5.5,-23.7 -23.60004,-41.89999 -29.60004,-65.5c-1.79999,-9.8 -1.09998,-20.2 -5.59998,-29.5c-2.5,0.60001 -5.10004,1 -7.5,2c-2.29999,0.90001 -3.5,4 -6.20001,4c-9.40002,0.40001 -17.59998,5.2 -26.59998,7.2c-5.40002,1.20001 -11.50003,2.60001 -16.70001,-0.2c-4.20001,-2.2 -6.20001,-7.5 -4.70001,-12c2.39999,-8 8.60001,-14.2 14.79999,-19.5c5.5,-4.59999 11.70001,-8.3 17.70001,-12.2m9.29999,5.3c-7.29999,2.2 -13.59998,6.7 -19.39996,11.5c-5.80002,4.89999 -11.30002,10.5 -14.40002,17.59999c6.20001,2.60001 13.20001,3.40001 19.79999,1.8c10,-2.39999 19.70001,-6.39999 28.90002,-11.09999c1.20001,-3.70001 0.59998,-7.8 0.79999,-11.70001c0.09998,-3.29999 -2.59998,-5.59999 -5.09998,-7.39999c-3.10004,-2.10001 -7.20001,-1.7 -10.60004,-0.7z" stroke-width="0.09375" stroke="#7644b6" fill="#7644b6">
</path>
<path id="s" d="m702,92c6.5,-2.9 14.20001,-3.4 20.70001,-0.2c-1.10004,6.3 -5.70001,11.1 -11.5,13.5c-1.10004,-1.2 -2.10004,-2.5 -3.40002,-3.60001c-10.59998,0.5 -17.89996,9.3 -25.79999,15.3c10.79999,0.9 21.70001,1 32.5,2.4c11.20001,1.1 22.79999,3.2 32.40002,9.7c3.09998,1.7 2.59998,5.79999 2.59998,8.89999c-0.40002,9.89999 -7.59998,17.89999 -15.70001,22.8c-6.20001,4 -13.70001,5 -19.79999,9.2c-3.40002,2.10001 -7.20001,5.2 -11.5,3.5c-7,-2.2 -9.20001,-10.7 -7.40002,-17.2c3.30005,2.2 2,8.7 6.90002,8.59999c7.20001,0.8 13.20001,-3.7 19.29999,-6.7c4.40002,-2.5 9.29999,-4.3 12.90002,-8c2.70001,-4 4.09998,-8.8 7.59998,-12.3c-6.09998,-9.2 -17.89996,-11.3 -28.09998,-12.39999c-11.29999,-1.4 -22.5,0.5 -33.70001,1.7c-4.29999,0 -9.59998,0.7 -13.09998,-2.39999c0.19995,-3.5 1.29999,-7.3 4,-9.9c1.5,-0.4 3.19995,-0.4 4.89996,-0.5c7.29999,-8.9 15.29999,-17.9 26.20001,-22.4z" stroke-width="0.09375" stroke="#7644b6" fill="#7644b6">
</path>
<path id="otwo" d="m781.09998,114c17.20001,-2 35.30005,-1.7 51.30005,5.6c8.79999,4 15.5,12.7 16.19995,22.50001c0.20001,3.2 0.80005,7.2 -1.79999,9.59999c-9.09998,9.7 -22.20001,14.40001 -34.79999,17.2c-15.59998,3.10001 -33.09998,1.8 -46.40002,-7.5c-2.89996,-2.39999 -7,-5 -6.69995,-9.29999c0,-8.3 2.29999,-17 8,-23.20001c4.69995,-5.39999 11,-8.99999 17.29999,-12.2c-1,-0.89999 -2,-1.8 -3.10004,-2.7m-8.29999,20.8c-2.59998,1.89999 -1.89996,5.2 -2.39996,8c-0.40002,3.2 -2.5,5.7 -4.20001,8.3c4.09998,6.79999 12.09998,10 19.70001,10.79999c11.39996,1.10001 23,0.20001 34.19995,-1.7c4.60004,-0.7 8.20001,-3.8 12.10004,-6c3.5,-2.09999 7,-5.09999 8,-9.3c1.09998,-4.89999 -0.90002,-10.2 -4,-14c-4,-4.99999 -10.20001,-7.2 -16.29999,-7.99999c-0.5,4.5 0.09998,9.49999 -2.5,13.49999c-0.90002,0.90001 -3.40002,2.3 -3.70001,0.3c0,-1.7 0.5,-3.39999 0.5,-5.09999c-3.29999,-7.40001 -12.20001,-11.50001 -20,-9.3c-8,2.3 -15.29999,6.8 -21.40002,12.5z" stroke-width="0.09375" stroke="#7644b6" fill="#7644b6">
</path>
<path id="othree" d="m899.40002,113.6c5.59998,-1.3 11.39996,0.1 17,1c9.09998,1.9 18.79999,4.7 25.29999,11.8c5.5,5.9 8,14.4 6.79999,22.4c-0.29999,1.59999 -1.70001,2.8 -2.70001,4c-7.09998,7 -16.5,11.2 -25.89996,14.09999c-13.40002,4.20001 -28.10004,4.90001 -41.5,0.70001c-7.30005,-2.40001 -14.90002,-6.10001 -19.20001,-12.8c-0.79999,-5.5 0.29999,-11.2 2.09998,-16.5c3.20001,-9 11.10004,-15.3 19.29999,-19.7c5.80005,-3.3 12.60004,-3.1 18.80005,-5m-6,8.9c-10.10004,2.7 -17.5,10.39999 -26.30005,15.7c-3.29999,3.3 -2.89996,8.90001 -1.19995,12.90001c3.39996,5.59999 9.79999,8.59999 15.89996,10.09999c5.90002,1.40001 11,5.5 17.20001,5.3c10.40002,-1.10001 20.59998,-4.5 29.40002,-10.10001c4,-2.39999 8.69995,-4.7 10.89996,-9.09999c2.5,-4.90001 0.70001,-10.90001 -2.29999,-15.3c-3.40002,-5 -9.29999,-7.7 -15.09998,-8.9c-5.20001,-1.4 -10.60004,-0.5 -15.90002,-0.8c-4.20001,-0.2 -8.5,-1 -12.59998,0.2z" stroke-width="0.09375" stroke="#7644b6" fill="#7644b6">
</path>
<path id="ntwo" d="m992.40002,125.3c2,0 4,0.1 6,0.1c2.09998,6.99999 4.09998,13.99999 6.19995,20.99999c3,9.40001 6.5,19.10001 13.70001,26.3c5.29999,5.3 11.60004,11.5 19.70001,11.2c7.80005,0.10001 14.69995,-3.79999 21.5,-7.09999c-1.09998,3.39999 -3.80005,6 -6.90002,7.7c-4,2.10001 -7.79993,5.5 -12.59998,4.8c-10.30005,-0.90001 -21.29999,-3.90001 -28.29999,-12c-10.70001,-11.10001 -14.10004,-26.60001 -18.70001,-40.8c-10.70001,9.10001 -12.40002,24.5 -22.70001,33.8c-2.09998,1.89999 -4.59998,3.3 -7,4.59999c-1.70001,-2 -3.59998,-3.89999 -4.89996,-6.2c-0.10004,-5.5 0.59998,-11.09999 0.19995,-16.59999c-0.59998,-8.60001 -1.19995,-18.20001 4.70001,-25.3c2.10004,0.89999 4.70001,1.59999 5.90002,3.8c0,4.5 -1.60004,9 -1.60004,13.59999c-0.09998,4.60001 -0.39996,9.2 -0.69995,13.90001c9.59998,-10.10001 16.79999,-22 25.5,-32.8z" stroke-width="0.09375" stroke="#7644b6" fill="#7644b6">
</path>
</svg>
JS:
<script>
function pathPrepare ($el) {
var lineLength = $el[0].getTotalLength();
$el.css("stroke-dasharray", lineLength);
$el.css("stroke-dashoffset", lineLength);
}
var $c = $("path#c");
var $o = $("path#o");
var $m = $("path#m");
var $i = $("path#i");
var $idot = $("path#idot");
var $n = $("path#n");
var $g = $("path#g");
var $s = $("path#s");
var $otwo = $("path#otwo");
var $othree = $("path#othree");
var $ntwo = $("path#ntwo");
// prepare SVG
pathPrepare($c);
pathPrepare($o);
pathPrepare($m);
pathPrepare($i);
pathPrepare($idot);
pathPrepare($n);
pathPrepare($g);
pathPrepare($s);
pathPrepare($otwo);
pathPrepare($othree);
pathPrepare($ntwo);
// init controller
var controller = new ScrollMagic.Controller();
// build tween
var tween = new TimelineMax()
.add(TweenMax.to($c, 0.9, {
strokeDashoffset: 0, ease:Linear.easeNone}
)) // draw word for 0.9
.add(TweenMax.to($o, 0.9, {
strokeDashoffset: 0, ease:Linear.easeNone}
)) // draw word for 0.9
.add(TweenMax.to($m, 0.9, {
strokeDashoffset: 0, ease:Linear.easeNone}
)) // draw word for 0.9
.add(TweenMax.to($i, 0.9, {
strokeDashoffset: 0, ease:Linear.easeNone}
)) // draw word for 0.9
.add(TweenMax.to($idot, 0.9, {
strokeDashoffset: 0, ease:Linear.easeNone}
)) // draw word for 0.9
.add(TweenMax.to($n, 0.9, {
strokeDashoffset: 0, ease:Linear.easeNone}
)) // draw word for 0.9
.add(TweenMax.to($g, 0.9, {
strokeDashoffset: 0, ease:Linear.easeNone}
)) // draw word for 0.9
.add(TweenMax.to($s, 0.9, {
strokeDashoffset: 0, ease:Linear.easeNone}
)) // draw word for 0.9
.add(TweenMax.to($otwo, 0.9, {
strokeDashoffset: 0, ease:Linear.easeNone}
)) // draw word for 0.9
.add(TweenMax.to($othree, 0.9, {
strokeDashoffset: 0, ease:Linear.easeNone}
)) // draw word for 0.9
.add(TweenMax.to($ntwo, 0.1, {
strokeDashoffset: 0, ease:Linear.easeNone}
)) // draw dot for 0.1
.add(TweenMax.to("path", 20, {
stroke: "#33629c", ease:Linear.easeNone}
), 0);
// change color during the whole thing
// build scene
var scene = new ScrollMagic.Scene({
triggerElement: "#trigger1", duration: 200, tweenChanges: true}
)
.setTween(tween)
.addIndicators() // add indicators (requires plugin)
.addTo(controller);
</script>
the reason is that you actually don't use paths, but shapes with fills.
You can only animate strokes this way, not fillings.
The stroke in this case is the (invisible) outline of each letter.
That is why it's not working.
regards,
J