Despite Metamask seems to complicate the process to you, if you give it a try you'll find that in reality it simplifies it for both users ( until some point ) and developpers.
To introduce a bit the topic just know that i've been on the same way as you and am developping a prototype of dApp through Angular 5, Web3js and truffle. The main idea was to have a full decentralized back-end for my prototype, which means that aside of distributing the front-end, http server wouldn't do anything else, all the back-end logic going to the ethereum network.
As i digged into Solidity i discoverd how little i knew despite reading hundreds of topics about dApp development.
I began using the Web3 object provided by Metamask in order to be able to implement my first features faster.
I had prepared a section of my Application in order to handle v3 Keystores like the one generated actually by MyEtherWallet in order to get indepedence of Metamask if user wanted to.
Whilst i achieved thanks to v1.0.0 of Web3 to decrypt the keystore file with the password i got stuck when it had to come to send signed transactions without metamask.
Below a few points about what are the complications about getting rid of Metamask :
You'll have to generate signature for every transaction your user will want.
In order to give user some control over its transaction you'll have to implement a modal or a panel that will ask user to confirm every transaction that requires gas, otherwise it will mean that your can spend user's funds as you want, imagining you store the decrypted wallet.
- You won't be able to use Web3 for signing your transactions and will have to rely on others libraries such as ethereumjs-tx.
- You will have to create your own accounts manager to be able to switch easily from an account to another
About last points note that using metamask in coordination with web3 you wont have to care much about those things as you'll just have to load the ABIs of your contracts and call the methods or events you want. When needing to spend gas Metamask will automatically catch the transaction request and ask confirmation. Switching accounts will take only a few seconds.
I know that this whole text doesn't provide the solution you would like but as you seem to be new, in order to be able to dig a bit without getting stuck and frustrated in complex processes and in order to dig progressively in this complexity i thought it would be a good thing to relate you how i went there and why Metamask is an affordable solution for developping first tests and prototypes.
EDIT (on demand for code) :
You can find a starter-pack of a small dApp here
The dApp shows how to detect Metamask ( which injects a Web3 Object in the window DOM Object ) and how to make small transaction.
I made a few months ago a small commented snippet on how to call method of a Contract for which we know the ABI. You'll find it here
Hope it helps !