JavaScript (ES7), 83 80 78 77 bytes
s=>s.repeat(l=s.length).replace(/./g,_=>s[(c-=--i**.5-l&1||-1)%l],c=-1,i=l*l)
Bonus ES3-compliant program:
for(s=prompt(r=""),c=-1,l=i=s.length;i--;)for(j=i*2+1;j--;)r+=s[(c+=(l-i)%2*2-1)%l];alert(r)
Explanation
This takes advantage of the fact that the output for e.g. a length 5 string can be represented as:
abcdeabcd cbaedcb cdeab aed e
012345678 7654321 23456 543 4
where each digit represents an index in the string (starting at 0), modulo the length of the string. In other words, if n is the length of the string, we increment the index 2n - 1 times, then decrement it 2(n - 1) - 1 times, then increment it 2(n - 2) - 1 times, etc. This can be simplified to the following algorithm:
- Start the index i at -1.
- For each integer x in the range [n2..1]:
- If floor(sqrt(x)) is of the same parity (even/odd) as n, increment i.
- Otherwise, decrement i.
- Add the character at index i mod n to the output.
This works because floor(sqrt(x)) switches parities after 2n - 1 iterations, then 2(n - 1) - 1 iterations, etc.