Skip to content

Commit

Permalink
svg transformj
Browse files Browse the repository at this point in the history
  • Loading branch information
xiuhonglee committed Dec 9, 2018
1 parent 164f1d6 commit 59b779c
Show file tree
Hide file tree
Showing 13 changed files with 271 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# 开发设计相关
# 学习总结

* [主页](http://xiuhonglee.github.io/)
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions docs/.vuepress/components/SVG/s01-10.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<template>
<div class="s06">
<svg width="500" height="200" viewBox="0 0 500 200">
<circle cx="50" cy="50" r="30" stroke="red" stroke-dasharray="5 5" fill="none"></circle>
<circle cx="50" cy="50" r="30" fill="red" transform="translate(100, 50)"></circle>
<path d="M50,50 L150,100" stroke="black"></path>
<path d="M150,100 L151,98 152,101 149,102Z"></path>
</svg>
</div>
</template>

<style scoped>
.s06 {
width: 500px;
height: 200px;
margin: 15px 0;
background: #fff;
box-shadow: 0 0px 2px 2px #eee;
}
</style>
18 changes: 18 additions & 0 deletions docs/.vuepress/components/SVG/s01-11.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<div class="s06">
<svg width="500" height="200" viewBox="0 0 500 200">
<circle cx="180" cy="100" r="30" stroke="red" stroke-dasharray="5 5" fill="none"></circle>
<circle cx="180" cy="100" r="30" fill="red" transform="scale(1.5)" fill-opacity="0.7"></circle>
</svg>
</div>
</template>

<style scoped>
.s06 {
width: 500px;
height: 200px;
margin: 15px 0;
background: #fff;
box-shadow: 0 0px 2px 2px #eee;
}
</style>
18 changes: 18 additions & 0 deletions docs/.vuepress/components/SVG/s01-12.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<div class="s06">
<svg width="500" height="200" viewBox="0 0 500 200">
<circle cx="180" cy="100" r="30" stroke="black" stroke-dasharray="5 5" fill="none"></circle>
<circle cx="180" cy="100" r="30" fill="red" transform="translate(180, 100) scale(1.5) translate(-180, -100)" fill-opacity="0.7"></circle>
</svg>
</div>
</template>

<style scoped>
.s06 {
width: 500px;
height: 200px;
margin: 15px 0;
background: #fff;
box-shadow: 0 0px 2px 2px #eee;
}
</style>
32 changes: 32 additions & 0 deletions docs/.vuepress/components/SVG/s01-13.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<div class="s06">
<svg width="500" height="200" viewBox="0 0 500 200">
<!-- 围绕坐标原点旋转 -->
<rect x="40" y="75" width="100" height="50" stroke="red" stroke-dasharray="5 5" fill="none"></rect>
<rect x="40" y="75" width="100" height="50" transform="rotate(15)" fill="red" fill-opacity="0.7"></rect>

<!-- 围绕矩形左上角旋转 -->
<rect x="200" y="75" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="200" y="75" width="100" height="50" transform="rotate(15, 200, 50)" fill="red" fill-opacity="0.7"></rect>

<!-- 围绕矩形中心旋转 -->
<!-- 方法一 -->
<rect x="350" y="75" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="350" y="75" width="100" height="50" transform="rotate(15, 400, 75)" fill="red" fill-opacity="0.7"></rect>

<!-- 方法二 -->
<!-- <rect x="350" y="50" width="100" height="50" transform="translate(400, 75) rotate(15) translate(-400, -75)" fill="red" fill-opacity="0.3"></rect> -->

</svg>
</div>
</template>

<style scoped>
.s06 {
width: 500px;
height: 200px;
margin: 15px 0;
background: #fff;
box-shadow: 0 0px 2px 2px #eee;
}
</style>
28 changes: 28 additions & 0 deletions docs/.vuepress/components/SVG/s01-14.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<template>
<div class="s06">
<svg width="500" height="200" viewBox="0 0 500 200">
<!-- 围绕坐标原点斜切效果 -->
<rect x="30" y="75" width="100" height="50" stroke="red" stroke-dasharray="5 5" fill="none"></rect>
<rect x="30" y="75" width="100" height="50" transform="skewX(15) skewY(15)" fill="red" fill-opacity="0.7"></rect>

<!-- 围绕矩形左上角斜切效果 -->
<rect x="180" y="75" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="180" y="75" width="100" height="50" transform="translate(180, 50) skewX(15) skewY(15) translate(-180, -50)" fill="red" fill-opacity="0.7"></rect>

<!-- 围绕矩形中心斜切效果 -->
<rect x="350" y="75" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="350" y="75" width="100" height="50" transform="translate(400, 75) skewX(15) skewY(15) translate(-400, -75)" fill="red" fill-opacity="0.7"></rect>

</svg>
</div>
</template>

<style scoped>
.s06 {
width: 500px;
height: 200px;
margin: 15px 0;
background: #fff;
box-shadow: 0 0px 2px 2px #eee;
}
</style>
33 changes: 33 additions & 0 deletions docs/.vuepress/components/SVG/s01-15.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<template>
<div class="s06">
<svg width="500" height="200" viewBox="0 0 500 200">
<!-- 初始位置 -->
<rect x="30" y="10" width="100" height="50" stroke="black" stroke-dasharray="6 5" fill="none"></rect>

<!-- 先位移,后旋转 -->
<rect x="30" y="10" width="100" height="50" stroke="red" transform="translate(100, 60)" stroke-dasharray="3 5" fill="none"></rect>
<rect x="30" y="10" width="100" height="50" transform="translate(100, 60) rotate(15)" stroke-dasharray="3 5" fill="red" fill-opacity=".7"></rect>

<!-- 先旋转,后位移 -->
<rect x="30" y="10" width="100" height="50" stroke="blue" transform="rotate(15)" stroke-dasharray="3 5" fill="none"></rect>
<rect x="30" y="10" width="100" height="50" transform="rotate(15) translate(100, 60)" stroke-dasharray="3 5" fill="blue" fill-opacity=".7"></rect>

<!-- 说明 -->
<rect x="320" y="100" width="20" height="10" fill="red"></rect>
<rect x="320" y="130" width="20" height="10" fill="blue"></rect>

<text x="350" y="109" style="font-size: 12px">先位移,再旋转</text>
<text x="350" y="139" style="font-size: 12px">先旋转,再位移</text>
</svg>
</div>
</template>

<style scoped>
.s06 {
width: 500px;
height: 200px;
margin: 15px 0;
background: #fff;
box-shadow: 0 0px 2px 2px #eee;
}
</style>
4 changes: 2 additions & 2 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
base: '/',
title: '程序设计开发',
title: '学习总结',
description: '学习实践总结',
markdown: {
lineNumbers: true,
Expand Down Expand Up @@ -63,7 +63,7 @@ module.exports = {
sidebar: {
'/Canvas/': ['d01', 'd02'],
'/CSS3/': ['c02', 'c03', 'c04', 'c05'],
'/SVG/': ['s01', 's01-01', 's02', 's03', 's04', 's05', 's06', 's07'],
'/SVG/': ['s01', 's01-01', 's01-02', 's02', 's03', 's04', 's05', 's06', 's07'],
'/Nginx/': ['n01', 'n02', 'n03', 'n04', 'n05'],
'/MySQL/': ['m01', 'm02']
}
Expand Down
2 changes: 1 addition & 1 deletion docs/Canvas/d01.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Canvas的坐标系统并不是固定的,根据实际场景,往往需要对Ca

#### 1. 在canvas中心绘制矩形

<Canvas-ch01-d01/>
<Canvas-d01/>

- [完整代码](https://github.com/xiuhonglee/canvasDoc/blob/master/docs/.vuepress/components/Canvas-ch01/d01.vue#L26-L36)

Expand Down
2 changes: 1 addition & 1 deletion docs/Canvas/d02.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: 路径和子路径
sidebarDepth: 2
---

<Canvas-ch01-d02/>
<Canvas-d02/>

## 基本概念

Expand Down
119 changes: 117 additions & 2 deletions docs/SVG/s01-02.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,122 @@
---
title: SVG坐标系统transform
title: SVG之transform
sidebarDepth: 2
---

## 1. transform位移
## 1. transform

`SVG``transform`属性可实现元素位移(`translate`)、缩放(`scale`)、旋转(`rotate`)、斜切(`skew`),它与`CSS`中的`transform`概念上有很大的相似之处,但也有不同之处,如下:

::: warning
`svg`的元素应用`transform`属性,相当于复制了一份基于`viewbox`所创建的的坐标系统,后续所有的变形操作将在此 **坐标系统**上完成。如:位移(`translate`)是对坐标系统的位移,而不是对元素的位置;缩放(`scale`)是对坐标系统进行的缩放,而不是对元素的缩放……这便是`svg transform``css transform`的不同之处。
:::

## 2. 位移

语法 `translate(<tx> [<ty>])`
* tx: 水平方向位移
* ty: 垂直方向位移,缺省值为0

<SVG-s01-10/>

* 源码
```html
<!-- 位移前 -->
<circle cx="50" cy="50" r="30" stroke="red" stroke-dasharray="5 5" fill="none"></circle>
<!-- 位移后 -->
<circle cx="50" cy="50" r="30" fill="red" transform="translate(100,50)"></circle>
```

## 3. 缩放

语法 `scale(<sx> <sy>)`

* sx: 水平方向缩放
* sy: 垂直方向缩放,缺省值=sx

<SVG-s01-11/>

* 源码
```html
<!-- 缩放前 -->
<circle cx="50" cy="100" r="30" stroke="red" stroke-dasharray="5 5" fill="none"></circle>
<!-- 缩放后 -->
<circle cx="50" cy="100" r="30" fill="red" transform="scale(2)" fill-opacity="0.3"></circle>
```

::: warning
因为缩放是针对整个坐标系统,所以缩放后,圆心坐标位置发生了改变。大部分情况下,我们希望缩放能围绕圆形进行缩放(类似`CSS`中的`transform-origin`),可通过下面这种方式
`translate(cx, cy) scale(1.5) translate(-cx, -cy)`来实现
:::

<SVG-s01-12/>

* 源码

```html
<circle cx="50" cy="100" r="30" stroke="red" stroke-dasharray="5 5" fill="none"></circle>
<circle cx="50" cy="100" r="30" fill="red" transform="translate(50, 100) scale(1.5) translate(-50, -100)" fill-opacity="0.3"></circle>
```

## 4. 旋转

语法: `rotate(<rotate-angle> [<cx> <cy>])`
* rotate-angle: 旋转角度
* cx,cy: 旋转中心

<SVG-s01-13/>

* 源码
```html
<!-- 围绕坐标原点旋转 -->
<rect x="30" y="50" width="100" height="50" stroke="red" stroke-dasharray="5 5" fill="none"></rect>
<rect x="30" y="50" width="100" height="50" transform="rotate(15)" fill="red" fill-opacity="0.3"></rect>

<!-- 围绕矩形左上角旋转 -->
<rect x="180" y="50" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="180" y="50" width="100" height="50" transform="rotate(15, 180, 50)" fill="red" fill-opacity="0.3"></rect>

<!-- 围绕矩形中心旋转 -->
<!-- 方法一 -->
<rect x="350" y="50" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="350" y="50" width="100" height="50" transform="rotate(15, 400, 75)" fill="red" fill-opacity="0.3"></rect>
<!-- 方法二 -->
<!-- <rect x="350" y="50" width="100" height="50" transform="translate(400, 75) rotate(15) translate(-400, -75)" fill="red" fill-opacity="0.3"></rect> -->
```

## 5. 斜切

语法: `skewX(<skew-angle>) skewY(<skew-angle>)`
* skewX(&lt;skew-angle&gt;): 水平方向斜切角度
* skewY(&lt;skew-angle&gt;): 垂直方向斜切角度

<SVG-s01-14/>
* 源码
```html
<!-- 围绕坐标原点斜切效果 -->
<rect x="30" y="75" width="100" height="50" stroke="red" stroke-dasharray="5 5" fill="none"></rect>
<rect x="30" y="75" width="100" height="50" transform="skewX(15) skewY(15)" fill="red" fill-opacity="0.3"></rect>

<!-- 围绕矩形左上角斜切效果 -->
<rect x="180" y="75" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="180" y="75" width="100" height="50" transform="translate(180, 50) skewX(15) skewY(15) translate(-180, -50)" fill="red" fill-opacity="0.3"></rect>

<!-- 围绕矩形中心斜切效果 -->
<rect x="350" y="75" width="100" height="50" stroke="red" stroke-dasharrya="5 5" fill="none"></rect>
<rect x="350" y="75" width="100" height="50" transform="translate(400, 75) skewX(15) skewY(15) translate(-400, -75)" fill="red" fill-opacity="0.3"></rect>
```

## 6. transform叠加

`tranform`可叠加使用,比如:先(对坐标系)进行位移再进行旋转。需要强调的是后面(对坐标系)的旋转操作是在(对坐标系)位移后的基础上进行的。

<SVG-s01-15/>

::: warning
`transform`叠加并不满足交换律,示例中先位移再旋转的效果并不等于先旋转再位移的效果。这个特性跟`CSS`中的`transform`是一致的。这种特性如果有线性代数的背景知识很好理解:物体在空间内发生运动,可以通过变换矩阵**相乘**来实现,而**矩阵相乘不满足交换律**
:::

## 参考

* [SVG Essentials](http://www.softouch.on.ca/kb/data/SVG%20Essentials.%202E.pdf)
* [Understanding SVG Coordinate Systems and Transformations (Part 2) — The transform Attribute](https://www.sarasoueidan.com/blog/svg-transformations/)

0 comments on commit 59b779c

Please sign in to comment.