├── image.png ├── babel.config.js ├── public ├── favicon.ico └── index.html ├── src ├── assets │ └── logo.png ├── main.js ├── App.vue └── components │ └── FreeTransform.vue ├── .npmignore ├── .travis.yml ├── .gitignore ├── .github └── FUNDING.yml ├── LICENSE.md ├── package.json └── README.md /image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skmail/vue-free-transform/HEAD/image.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skmail/vue-free-transform/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skmail/vue-free-transform/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | __tests__ 3 | node_modules 4 | .babelrc 5 | .eslintrc 6 | .gitignore 7 | .npmignore 8 | .travis.yml 9 | package.json 10 | package-lock.json 11 | yarn-error.log 12 | .idea -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "8" 5 | 6 | before_install: 7 | - 'nvm install-latest-npm' 8 | 9 | env: 10 | matrix: 11 | 12 | sudo: false 13 | 14 | script: 15 | - npm run lint 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vue-free-transform 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: skmail 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Solaiman Kmail (skmail) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-free-transform", 3 | "description": "A free transform tool", 4 | "author": "Solaiman Kmail (https://github.com/skmail)", 5 | "version": "1.0.11", 6 | "main": "./dist/FreeTransform.common.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/skmail/vue-free-transform" 10 | }, 11 | "scripts": { 12 | "serve": "vue-cli-service serve", 13 | "test": "vue-cli-service test", 14 | "build": "vue-cli-service build", 15 | "build:lib": "vue-cli-service build --target lib --name FreeTransform ./src/components/FreeTransform.vue", 16 | "lint": "vue-cli-service lint" 17 | }, 18 | "dependencies": { 19 | "free-transform": "^0.1.3", 20 | "vue": "^2.5.17" 21 | }, 22 | "devDependencies": { 23 | "@vue/cli-plugin-babel": "^3.0.1", 24 | "@vue/cli-plugin-eslint": "^3.0.1", 25 | "@vue/cli-service": "^3.0.1", 26 | "vue-template-compiler": "^2.5.17" 27 | }, 28 | "eslintConfig": { 29 | "root": true, 30 | "env": { 31 | "node": true 32 | }, 33 | "extends": [ 34 | "plugin:vue/essential", 35 | "eslint:recommended" 36 | ], 37 | "rules": {}, 38 | "parserOptions": { 39 | "parser": "babel-eslint" 40 | } 41 | }, 42 | "postcss": { 43 | "plugins": { 44 | "autoprefixer": {} 45 | } 46 | }, 47 | "browserslist": [ 48 | "> 1%", 49 | "last 2 versions", 50 | "not ie <= 8" 51 | ], 52 | "files": [ 53 | "dist/*", 54 | "src/*", 55 | "public/*", 56 | "*.json", 57 | "*.js" 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VueJS Free Transform Tool 2 | 3 | 4 | [![NPM Version](https://img.shields.io/npm/v/vue-free-transform.svg?style=flat)](https://www.npmjs.com/package/vue-free-transform) [![NPM Downloads](https://img.shields.io/npm/dm/vue-free-transform.svg?style=flat)](https://www.npmjs.com/package/vue-free-transform) [![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT) [![Build Status](https://img.shields.io/travis/skmail/vue-free-transform/master.svg?style=flat)](https://travis-ci.org/skmail/vue-free-transform) 5 | 6 | 7 | VueJS component for resizing, dragging and rotating html elements using css transform matrix 8 | 9 | ![VueJS free transform tool](https://raw.githubusercontent.com/skmail/vue-free-transform/master/image.png) 10 | 11 | 12 | ## Installation 13 | `yarn install vue-free-transform` or `npm install vue-free-transform --save` 14 | 15 | ## Demo 16 | https://codesandbox.io/s/1jl7z9p3q 17 | 18 | 19 | ## Usage 20 | 21 | ```js 22 | import FreeTransform from 'vue-free-transform' 23 | ``` 24 | 25 | ```vue 26 | 27 | 39 |
40 | 41 |
42 | 43 |
44 | ``` 45 | ## Optional Attributes 46 | 47 | `selected` 48 | `selectOn` 49 | `styles` 50 | 51 | | Attribute | Description | 52 | | ------------- |:-------------:| 53 | | styles | additional styles for parent wrapper usefull for z-index| 54 | | selected | hide the controls when values is false | 55 | | selectOn | trigger selection on `mousedown`, `click` or `dblclick` | 56 | | aspect-ratio | enable aspect ratio resizing default (true)| 57 | | scale-from-center | enable scale from center resizing default (true)| 58 | 59 | 60 | 61 | ## Events 62 | `onSelect` 63 | `dblclick` 64 | `click` 65 | `mousedown` 66 | 67 | ## css 68 | 69 | ```css 70 | 71 | .tr-transform--active{ 72 | position: absolute; 73 | z-index: 5; 74 | } 75 | 76 | .tr-transform__content{ 77 | user-select: none; 78 | } 79 | .tr-transform__rotator { 80 | top: -45px; 81 | left: calc(50% - 7px); 82 | } 83 | 84 | .tr-transform__rotator, 85 | .tr-transform__scale-point { 86 | background: #fff; 87 | width: 15px; 88 | height: 15px; 89 | border-radius: 50%; 90 | position: absolute; 91 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1); 92 | border: 1px solid rgba(0, 0, 0, 0.1); 93 | cursor: pointer; 94 | } 95 | 96 | .tr-transform__rotator:hover, 97 | .tr-transform__scale-point:hover { 98 | background: #F1F5F8; 99 | } 100 | 101 | .tr-transform__rotator:active, 102 | .tr-transform__scale-point:active { 103 | background: #DAE1E7; 104 | } 105 | 106 | .tr-transform__scale-point { 107 | 108 | } 109 | 110 | .tr-transform__scale-point--tl { 111 | top: -7px; 112 | left: -7px; 113 | } 114 | 115 | .tr-transform__scale-point--ml { 116 | top: calc(50% - 7px); 117 | left: -7px; 118 | } 119 | 120 | .tr-transform__scale-point--tr { 121 | left: calc(100% - 7px); 122 | top: -7px; 123 | } 124 | 125 | .tr-transform__scale-point--tm { 126 | left: calc(50% - 7px); 127 | top: -7px; 128 | } 129 | 130 | .tr-transform__scale-point--mr { 131 | left: calc(100% - 7px); 132 | top: calc(50% - 7px); 133 | } 134 | 135 | .tr-transform__scale-point--bl { 136 | left: -7px; 137 | top: calc(100% - 7px); 138 | } 139 | 140 | .tr-transform__scale-point--bm { 141 | left: calc(50% - 7px); 142 | top: calc(100% - 7px); 143 | } 144 | 145 | .tr-transform__scale-point--br { 146 | left: calc(100% - 7px); 147 | top: calc(100% - 7px); 148 | } 149 | ``` 150 | 151 | 152 | ## Keyboard shortcuts 153 | `shift` for aspect ratio resizing 154 | 155 | `alt` for scaling from center 156 | 157 | `shift` + `alt` scaling from center based on aspect ratio 158 | 159 | `shift` while rotation will snap rotation using 15 degrees -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 153 | 154 | 261 | -------------------------------------------------------------------------------- /src/components/FreeTransform.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 237 | --------------------------------------------------------------------------------