Увеличить новое расчет происхождения с использованием матрицы преобразования CSSJavascript

Форум по Javascript
Ответить
Anonymous
 Увеличить новое расчет происхождения с использованием матрицы преобразования CSS

Сообщение Anonymous »

Я должен реализовать функцию PAN и Zoom для изображения, мой проект реализован из ReAct, из -за проблем с производительностью я не мог использовать обычные пользователи и другие API из -за проблем с производительностью. Я пошел вместе с кодом VanillaJS, вдохновленным
https://github.com/kwdowik/zoom-pan/blo ... азноexport const hasPositionChanged = ({ pos, prevPos }: Position): boolean =>
pos !== prevPos;
< /code>
const valueInRange = ({ minScale, maxScale, scale }: ScaleRange): boolean =>
scale = minScale;
< /code>
const getTranslate =
({ minScale, maxScale, scale }: ScaleRange) =>
({ pos, prevPos, translate }: TranslateParams): number =>
valueInRange({ minScale, maxScale, scale }) &&
hasPositionChanged({ pos, prevPos })
? translate + (pos - prevPos * scale) * (1 - 1 / scale)
: translate;
< /code>
const getScale = ({
scale,
minScale,
maxScale,
scaleSensitivity,
deltaScale,
}: ScaleParams): [number, number] => {
let newScale = scale + deltaScale / (scaleSensitivity / scale);
newScale = Math.max(minScale, Math.min(newScale, maxScale));
return [scale, newScale];
};
< /code>
const getMatrix = ({ scale, translateX, translateY }: MatrixParams): string =>
`matrix(${scale}, 0, 0, ${scale}, ${translateX}, ${translateY})`;

< /code>

const makeZoom = (state: RendererState): ZoomActions => ({
zoom: ({ x, y, deltaScale }: ZoomParams) => {
const { left, top } = state.element.getBoundingClientRect();
const { minScale, maxScale, scaleSensitivity } = state;
const [scale, newScale] = getScale({
scale: state.transformation.scale,
deltaScale,
minScale,
maxScale,
scaleSensitivity,
});

const originX = x - left;
const originY = y - top;
const newOriginX = originX / scale;
const newOriginY = originY / scale;
const translate = getTranslate({ scale, minScale, maxScale });

let translateX = translate({
pos: originX,
prevPos: state.transformation.originX,
translate: state.transformation.translateX,
});

let translateY = translate({
pos: originY,
prevPos: state.transformation.originY,
translate: state.transformation.translateY,
});

const transformOrigin = `${newOriginX}px ${newOriginY}px`;
const transform = getMatrix({
scale: newScale,
translateX,
translateY,
});

state.element.style.transformOrigin = transformOrigin;
state.element.style.transform = transform;

if (state.canvasElement) {
state.canvasElement.style.transformOrigin = transformOrigin;
state.canvasElement.style.transform = transform;
}

state.transformation = {
originX: newOriginX,
originY: newOriginY,
translateX,
translateY,
scale: newScale,
};
},
});
< /code>
export const renderer = ({
minScale,
maxScale,
element,
canvasElement,
scaleSensitivity = 0.1,
}: RendererParams): RendererInstance => {
const state: RendererState = {
element,
canvasElement,
minScale,
maxScale,
scaleSensitivity,
transformation: {
originX: 0,
originY: 0,
translateX: 0,
translateY: 0,
scale: 1,
},
};

if (canvasElement) {
canvasElement.style.zIndex = "10";
}

return Object.assign({}, makeZoom(state));
};

< /code>
you can view full code from the link above.
As you can observe
const originX = x - left;
const originY = y - top;
const newOriginX = originX / scale;
const newOriginY = originY / scale;

< /code>
the new origin is calculated from the scale as well the mouse position and image position difference, when the image is zooming out, the value of scale becomes so small that the new origin values becomes very large, making the image to have unexpected translated positions. I went with transform matrix because I wanted to do the pan as well (the code is not included above), but my problem is with the origin calculation.
I found out using a clamp function is a solution, but it didn't worked out for though.
If there are any suggestions, those would be most thankful.

Подробнее здесь: https://stackoverflow.com/questions/796 ... orm-matrix
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»