Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Скейл относительно точки (http://www.flasher.ru/forum/showthread.php?t=209994)

Vlad84 13.01.2015 13:38

Скейл относительно точки
 
Не могу понять почему если скейл анимированный, т.е. медленно ползет от 1 до 3, скейл сходит с ума.
Код AS3:

import com.greensock.*;
import com.greensock.easing.*;
 
function scaleAroundPoint(target:DisplayObject, point:Point, scaleFactor:Number) {
        var m:Matrix = target.transform.matrix;
                m.translate(-point.x, -point.y);
                m.scale(scaleFactor, scaleFactor);
                m.translate(point.x, point.y);
        target.transform.matrix = m;
}
 
var scale:Number = mc.scaleX;
TweenMax.to(this, 5, {scale:3, onUpdate:update});
 
function update() {
        scaleAroundPoint(mc, new Point(300, 300), scale);
}


Когда однократно вызываешь метод, передавая туда финальное значение скейла, то все нормально.
Код AS3:

scaleAroundPoint(mc, new Point(300, 300), 3);


nubideus 13.01.2015 14:26

Vlad84, юзани TweenMax.to({scale: 1}, 5, {scale:3, onUpdate:update});

Zebestov 13.01.2015 14:37

Попробуй там заменить:
Код AS3:

var m:Matrix = new Matrix();


Vlad84 13.01.2015 15:15

Цитата:

Сообщение от Zebestov (Сообщение 1177467)
Попробуй там заменить:
Код AS3:

var m:Matrix = new Matrix();


В этом случае смещение считается некорректно, объект при скейле уезжает в левый верхний угол.

Zebestov 13.01.2015 15:27

Наверное, потому что надо еще:
Код AS3:

m.translate(point.x * scaleFactor, point.y * scaleFactor);


Vlad84 13.01.2015 15:51

Вложений: 1
Цитата:

Сообщение от Zebestov (Сообщение 1177471)
Наверное, потому что надо еще:
Код AS3:

m.translate(point.x * scaleFactor, point.y * scaleFactor);


Фиксируется в (0,0) на стейдже :(

Zebestov 13.01.2015 16:01

Короче вот:

Код AS3:

import flash.geom.Matrix;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.events.Event;
 
var bmp:Bitmap = new Bitmap(new BMP());
bmp.x = (stage.stageWidth - bmp.width) / 2;
bmp.y = (stage.stageHeight - bmp.height) / 2;
addChild(bmp);
 
var mtx:Matrix = bmp.transform.matrix;
var pt:Point = new Point(stage.stageWidth / 2 - 100, stage.stageHeight / 2 - 100);
 
var scale:Number = 0.0;
 
addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
 
function onEnterFrameHandler(event:Event):void
{
        scale += 0.01;
        scale <= 1.0 && scaleAroundPoint(bmp, pt, scale);
}
 
function scaleAroundPoint(target:DisplayObject, point:Point, scaleFactor:Number) {
        var m:Matrix = mtx.clone();
        m.translate(-point.x, -point.y);
        m.scale(scaleFactor, scaleFactor);
        m.translate(point.x, point.y);
        target.transform.matrix = m;
}


alatar 13.01.2015 23:21

Как раз короткую статью готовлю по трансформациям, но придется поспойлерить.
Код AS3:

private function scaleAround(m:Matrix, p:Point, sx:Number, sy:Number):Matrix
{
        var d:Point = m.deltaTransformPoint(p);
 
        var i:Point = new Point(m.a, m.b);
        var j:Point = new Point(m.c, m.d);
 
        i.normalize(sx);
        j.normalize(sy);
 
        m.a = i.x;
        m.b = i.y;
        m.c = j.x;
        m.d = j.y;
 
        d = d.subtract(m.deltaTransformPoint(p));
 
        m.translate(d.x, d.y);
 
        return m;
}

m - матрица трансформации объекта, p - точка вокруг которой происходит трансформация (в локальных координатах объекта), sx, sy - масштаб по осям.

Nooob 14.01.2015 01:55

alatar неправильно
нужна не нормализация, а умножение. так как нужна интерполяция положения точек, а не приведение их к длине
простой вариант:
Код AS3:

                private function scaleAround (m:Matrix, p:Point, sx:Number, sy:Number):Matrix
                {
                        var a:Number = m.a * sx;
                        var b:Number = m.b * sx;
                        var c:Number = m.c * sy;
                        var d:Number = m.d * sy;
                        m.tx += (m.a - a) * p.x + (m.c - c) * p.y;
                        m.ty += (m.b - b) * p.x + (m.d - d) * p.y;
                        m.a = a;
                        m.b = b;
                        m.c = c;
                        m.d = d;
                        return m;
                }


alatar 14.01.2015 02:18

Цитата:

Сообщение от Nooob (Сообщение 1177503)
alatar неправильно
нужна не нормализация, а умножение. так как нужна интерполяция положения точек, а не приведение их к длине

Вы свой простой вариант проверяли?
Вектор {m.a, m.b} описывает локальную ось x, поворот и масштаб. Длина этого вектора описывает масштаб по оси x. То что у вас получилось... в общем ерунда получилась. Попробуйте подать на вход матрицу с масштабированием и поворотом.

Добавлено через 4 минуты
http://www.flasher.ru/forum/blog.php?b=703


Часовой пояс GMT +4, время: 00:51.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.