Add originX and originY support to images Add fields for modifying origin x/y to images. Add support for images to freeze. Hopefully this is the right approach. Editor: https://github.com/rive-app/rive/assets/186340/838b2c69-bd25-4c55-85ab-611e423c8983 CPP: https://github.com/rive-app/rive/assets/186340/8e7d76db-d0b5-4fdb-9ea6-a6d921fee8ef Diffs= fcccdeccd Add originX and originY support to images (#5624) Co-authored-by: Philip Chung <philterdesign@gmail.com>
diff --git a/.rive_head b/.rive_head index 28bcc96..368df58 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -5b2a52f44ebf18e44b960202844d56424b777aa3 +fcccdeccddd2b9c47992f131f9ba741bccee5da8
diff --git a/dev/defs/shapes/image.json b/dev/defs/shapes/image.json index a56cec0..fb45809 100644 --- a/dev/defs/shapes/image.json +++ b/dev/defs/shapes/image.json
@@ -16,6 +16,26 @@ "string": "assetid" }, "description": "Image drawable for an image asset" + }, + "originX": { + "type": "double", + "initialValue": "0.5", + "animates": true, + "key": { + "int": 380, + "string": "originx" + }, + "description": "Origin x in normalized coordinates (0.5 = center, 0 = left, 1 = right)." + }, + "originY": { + "type": "double", + "initialValue": "0.5", + "animates": true, + "key": { + "int": 381, + "string": "originy" + }, + "description": "Origin y in normalized coordinates (0.5 = center, 0 = top, 1 = bottom)." } } } \ No newline at end of file
diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index ee38679..cac7f25 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp
@@ -825,6 +825,12 @@ case StarBase::innerRadiusPropertyKey: object->as<StarBase>()->innerRadius(value); break; + case ImageBase::originXPropertyKey: + object->as<ImageBase>()->originX(value); + break; + case ImageBase::originYPropertyKey: + object->as<ImageBase>()->originY(value); + break; case CubicDetachedVertexBase::inRotationPropertyKey: object->as<CubicDetachedVertexBase>()->inRotation(value); break; @@ -1421,6 +1427,10 @@ return object->as<PolygonBase>()->cornerRadius(); case StarBase::innerRadiusPropertyKey: return object->as<StarBase>()->innerRadius(); + case ImageBase::originXPropertyKey: + return object->as<ImageBase>()->originX(); + case ImageBase::originYPropertyKey: + return object->as<ImageBase>()->originY(); case CubicDetachedVertexBase::inRotationPropertyKey: return object->as<CubicDetachedVertexBase>()->inRotation(); case CubicDetachedVertexBase::inDistancePropertyKey: @@ -1768,6 +1778,8 @@ case CubicMirroredVertexBase::distancePropertyKey: case PolygonBase::cornerRadiusPropertyKey: case StarBase::innerRadiusPropertyKey: + case ImageBase::originXPropertyKey: + case ImageBase::originYPropertyKey: case CubicDetachedVertexBase::inRotationPropertyKey: case CubicDetachedVertexBase::inDistancePropertyKey: case CubicDetachedVertexBase::outRotationPropertyKey:
diff --git a/include/rive/generated/shapes/image_base.hpp b/include/rive/generated/shapes/image_base.hpp index ead835e..7a6e4a6 100644 --- a/include/rive/generated/shapes/image_base.hpp +++ b/include/rive/generated/shapes/image_base.hpp
@@ -1,5 +1,6 @@ #ifndef _RIVE_IMAGE_BASE_HPP_ #define _RIVE_IMAGE_BASE_HPP_ +#include "rive/core/field_types/core_double_type.hpp" #include "rive/core/field_types/core_uint_type.hpp" #include "rive/drawable.hpp" namespace rive @@ -34,9 +35,13 @@ uint16_t coreType() const override { return typeKey; } static const uint16_t assetIdPropertyKey = 206; + static const uint16_t originXPropertyKey = 380; + static const uint16_t originYPropertyKey = 381; private: uint32_t m_AssetId = -1; + float m_OriginX = 0.5f; + float m_OriginY = 0.5f; public: inline uint32_t assetId() const { return m_AssetId; } @@ -50,10 +55,34 @@ assetIdChanged(); } + inline float originX() const { return m_OriginX; } + void originX(float value) + { + if (m_OriginX == value) + { + return; + } + m_OriginX = value; + originXChanged(); + } + + inline float originY() const { return m_OriginY; } + void originY(float value) + { + if (m_OriginY == value) + { + return; + } + m_OriginY = value; + originYChanged(); + } + Core* clone() const override; void copy(const ImageBase& object) { m_AssetId = object.m_AssetId; + m_OriginX = object.m_OriginX; + m_OriginY = object.m_OriginY; Drawable::copy(object); } @@ -64,12 +93,20 @@ case assetIdPropertyKey: m_AssetId = CoreUintType::deserialize(reader); return true; + case originXPropertyKey: + m_OriginX = CoreDoubleType::deserialize(reader); + return true; + case originYPropertyKey: + m_OriginY = CoreDoubleType::deserialize(reader); + return true; } return Drawable::deserialize(propertyKey, reader); } protected: virtual void assetIdChanged() {} + virtual void originXChanged() {} + virtual void originYChanged() {} }; } // namespace rive
diff --git a/src/shapes/image.cpp b/src/shapes/image.cpp index 9635f82..7d3c2cd 100644 --- a/src/shapes/image.cpp +++ b/src/shapes/image.cpp
@@ -35,7 +35,7 @@ else { renderer->transform(worldTransform()); - renderer->translate(-width / 2.0f, -height / 2.0f); + renderer->translate(-width * originX(), -height * originY()); renderer->drawImage(renderImage, blendMode(), renderOpacity()); } @@ -57,7 +57,8 @@ } else { - auto mx = xform * worldTransform() * Mat2D::fromTranslate(-width * 0.5f, -height * 0.5f); + auto mx = xform * worldTransform() * + Mat2D::fromTranslate(-width * originX(), -height * originY()); HitTester tester(hinfo->area); tester.addRect(AABB(0, 0, (float)width, (float)height), mx); if (tester.test())