How to tighten the loose focus ring on Canon lens?

I have an EF 24-105mm f / 4 L IS that is 'well broken' with a very loose zoom ring. When the camera is pointed down, as it is when hanging on a strap or neck strap, the front of the lens fully drags to the fully extended 105mm position.

I use a plastic bracelet stretched around the lens body with part of the width of the bracelet on the zoom ring and part of the width on the stationary part of the lens body. The band provides enough resistance to prevent the zoom from dragging due to gravity. The amount of the band in the zoom ring and the amount in the barrel determines how much resistance is added.

The same type of band can be used to give a focus ring more resistance. There is even a company that markets such bands specifically for camera lenses, but I have never tried them because they appear to be the same as the rubber bands I already have for me.

enter the image description here

The TS-E 24mm f / 3.5L is a slightly smaller diameter (approximately 78mm) in the focus ring than the barrel of my EF 24-105mm f / 4L IS (approximately 83.5mm). The TS-E 24mm f / 3.5 L II has a slightly larger diameter (approximately 88.5mm) than my EF 24-105mm f / 4L IS. I would hope that you could easily find a generic plastic / rubber bracelet of the type used to promote charities and companies that cater to any one of them.

From a comment by the OP to another answer:

I bought this lens a few months ago (new). I think it is, but I find it strange that it is so loose by design.

The focus ring of all Canon TS-E lenses that I have handled is fairly well damped without being stiff. If the lens is under warranty, I would not hesitate to contact Canon Service. If you send it to them and they tell you there is nothing wrong, at worst it is out of the shipping price.

Collision detection: How to properly tighten an object when pressed between two others?

@jgallant, @Hamza Hasan, I'm trying to do this: How can I "squeeze" an object from the game when pressed between two others?

What they both answered there, but with some problems, such as not returning to the original scale or not changing the size correctly based on the percentage of collisions (with what I am struggling). This is how I have solved it until now:

Original Vector3 Original scale;
privateX floating current;
private floating currentZ;
private float area;
public floating value minValue = 0.6f;
// 1 is perfect horizontal / vertical
Filter mesh filter;

public float skinWidth = 0.1f;
public float firstLenght = 0.2f;
// must be greater than skniWidth;

RaycastHit hit;

GameObject leftEmpty;
GameObject rightEmpty;

bool pressLeft = false;
bool pressRight = false;

float diffX;
original floatDiffX;

bool orig = false;

Empty Awake ()
{
filter = this.GetComponent();
}

void Home ()
{
originalScale = new Vector3 (filter.mesh.bounds.size.x, filter.mesh.bounds.size.y, filter.mesh.bounds.size.z);
area = originalScale.x * originalScale.z;
leftEmpty = new GameObject ();
rightEmpty = new GameObject ();
}

void OnCollisionStay (collision)
{
if (coll.gameObject.tag! = "Ground" && coll.gameObject.tag! = "Ceiling")
{
// if the collision is on the left side
for (int i = 0; i < coll.contacts.Length; i++)
        {
            if (coll.contacts[i].normal.x > minValue) // I'm checking the address according to the normals, not the positions
{
Vector3 rayOrigin = coll.contacts[i].point + Vector3.right * skinWidth;
if (pressed Left == false)
{
if (Physics.Raycast (rayOrigin, -Vector3.right, out hit, firstLenght))
{
Debug.DrawRay (rayOrigin, -Vector3.right * firstLenght, Color.blue, 0.1f);
// I'm doing all this to take the points of contact only when they're right (before they hit, they're wrong). So the point of contact is in the right place only if ...
if (hit.distance <= skinWidth + 0.00008f) // the last number is to compensate for the strange physics, just ignore it
{
leftEmpty.transform.position = hit.point;
pressLeft = true; // so the leftEmpty's position is set only once, then it moves through the parenting under
}
}
}

leftEmpty.transform.SetParent (coll.transform); // I am raising them to be able to keep them after OnCollisionExit because I will use these numbers also to return to the original scale
}
}
// if the collision is on the right side
for (int i = 0; i <coll.contacts.Length; i ++)
{
yes (col. contacts)[i].normal.x <- (minValue))
{
Vector3 rayOrigin = coll.contacts[i].point - Vector3.right * skinWidth;
yes (pressed right == false)
{
if (Physics.Raycast (rayOrigin, Vector3.right, out hit, firstLenght))
{
if (hit.distance <= skinWidth + 0.00008f)
{
rightEmpty.transform.position = hit.point;
pressRight = true;
}
}
}

rightEmpty.transform.SetParent (coll.transform);
}
}
}


if (pressLeft == true && pressRight == true && orig == false)
{
originalDiffX = Mathf.Abs (rightEmpty.transform.position.x - leftEmpty.transform.position.x);
orig = true;
}
}

Null update ()
{
diffX = Mathf.Abs (rightEmpty.transform.position.x - leftEmpty.transform.position.x);
// originally, I was doing this:
currentX = diffX;
currentZ = area / currentX;
if (leftEmpty.transform.position.x! = 0 && rightEmpty.transform.position.x! = 0)
{
if (currentX <= originalScale.x)
{
transform.localScale = new Vector3 (currentX / filter.mesh.bounds.size.x, transform.localScale.y, currentZ / filter.mesh.bounds.size.z);
}
}

// And it worked, but only if the collisions were always in the most separated points of the mesh (because the scale x was always the distance between collisions)
// That's why I wanted a percentage, on a scale based on the points of impact and not on the full width, so I did this:
currentX = originalScale.x / (originalDiffX / diffX); // o (originalScale.x / originalDiffX) * diffX; anything works.
// However, while solving the percentage problem, it only does so if the collisions remain at the original collision points, which will not be the case.
// then I tried this to get the original DiffX original of the updated diffX:
Vector3 closestLeft = this.GetComponent() .ClosestPoint (leftEmpty.transform.position);
Vector3 closestRight = this.GetComponent() .ClosestPoint (rightEmpty.transform.position);

float distX = Mathf.Abs (closestRight.x - closestLeft.x);
float mult = (originalDiffX / diffX) * distX;

currentX = originalScale.x / (mult / diffX); // the same formula but replacing the originalDiffX with "mult". I did not work at all. The object began to vibrate strangely.
}